Skip to content

Commit

Permalink
API Combine GridField and CMSMain filter JS/CSS/templates
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Feb 25, 2025
1 parent fc62b3e commit 178b7d5
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 237 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/styles/bundle.css

Large diffs are not rendered by default.

21 changes: 0 additions & 21 deletions client/src/components/GridField/GridField.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,6 @@
}
}

.grid-field__filter-open {
.grid-field__table & {
vertical-align: bottom;
margin: 0;
float: right;
margin-top: -$input-btn-padding-y;
margin-bottom: -$input-btn-padding-y;
}
}

.grid-field__filter-submit,
.grid-field__filter-clear {
.grid-field & {
Expand Down Expand Up @@ -152,17 +142,6 @@ div.grid-field__sort-field + .form__fieldgroup-item {
position: absolute;
}

.grid-field__filter-header {
.fieldgroup:not(.grid-field__filter-buttons),
.fieldgroup:not(.grid-field__filter-buttons) .fieldgroup-field {
width: 100%;
}

.ss-gridfield-button-reset {
margin-right: 0;
}
}

.grid-field__filter-buttons {
right: -5px;
position: relative;
Expand Down
14 changes: 14 additions & 0 deletions client/src/components/Search/SearchForm.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@

@media(width >= 375px) {
flex-direction: row;

// Make sure fields using WithinRangeFilter display the same in gridfield search
// as they do in CMSMain search
// This is necessary to override .cms-edit-form styling which doesn't apply in CMSMain
.form-group {
margin-right: map_get($spacers, 2);
display: inline-block;

.form__field-holder,
.form__field-label {
padding-left: 0;
padding-right: 0;
}
}
}
}

Expand Down
197 changes: 37 additions & 160 deletions client/src/legacy/GridField.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import $ from 'jquery';
import i18n from 'i18n';
import React from 'react';
import { createRoot } from 'react-dom/client';
import Search from 'components/Search/Search.js';
import { schemaMerge } from 'lib/schemaFieldValues';
import { loadComponent } from 'lib/Injector';

import '../../../thirdparty/jquery-ui/jquery-ui.js';
Expand All @@ -14,12 +12,9 @@ $.entwine('ss', function($) {
onmatch: function () {
if (this.needsColumnFix()) {
this.fixColumns();
this.injectSearchButton(false);
}

if (this.hasFilters()) {
this.injectSearchButton(true);
};
this.fixShowFilters();

if (this.is('.grid-field--lazy-loadable') && (
(this.closest('.ss-tabset, .cms-tabset').length === 0) || (this.data('gridfield-lazy-load-state') === 'force') )
Expand All @@ -32,6 +27,14 @@ $.entwine('ss', function($) {
this.data('gridfield-lazy-load-state', 'ready');
},

fixShowFilters: function() {
if (this.hasFilters()) {
this.addClass('show-filter');
} else {
this.removeClass('show-filter');
}
},

/**
* @func Trigger a lazy load on this gridfield
*/
Expand All @@ -52,7 +55,7 @@ $.entwine('ss', function($) {
reload: function(ajaxOpts, successCallback) {
var self = this, form = this.closest('form'),
focusedElName = this.find(':input:focus').attr('name'), // Save focused element for restoring after refresh
data = form.find(':input:not(.grid-field__search-holder :input, .relation-search)').serializeArray(),
data = form.find(':input:not(.cms-content-filters :input, .relation-search)').serializeArray(),
tbody = this.find('tbody'),
colspan = this.find('.grid-field__title-row th').attr('colspan');
;
Expand Down Expand Up @@ -95,15 +98,6 @@ $.entwine('ss', function($) {
// multiple relationships via keyboard.
if(focusedElName) self.find(':input[name="' + focusedElName + '"]').focus();

// Update filter
if (self.find('.grid-field__filter-header, .grid-field__search-holder').length) {
var visible = ajaxOpts.data[0].filter === "show";
if (self.needsColumnFix()) {
self.fixColumns();
}
self.injectSearchButton(visible);
}

if(successCallback) successCallback.apply(this, arguments);
self.trigger('reload', self);

Expand All @@ -117,6 +111,7 @@ $.entwine('ss', function($) {
},
complete: function(request, status) {
self.find('.loading').removeClass('loading');
self.fixShowFilters();
}
}, ajaxOpts));
},
Expand Down Expand Up @@ -166,7 +161,7 @@ $.entwine('ss', function($) {

needsColumnFix: function() {
return (
this.find('.grid-field__filter-header, .grid-field__search-holder').length &&
this.find('.cms-content-filters').length &&
!this.find('.grid-field__col-compact').length &&
!this.find('th.col-Actions').length
);
Expand All @@ -181,30 +176,6 @@ $.entwine('ss', function($) {
var colspan = cell.attr('colspan') ?? 1;
cell.attr('colspan', Number(colspan) + 1);
});
var $extraCell = $('<th class="extra" />');
$('.grid-field__filter-header th:last .action').each(function() {
$(this).detach();
$extraCell.append($(this));
});
$('.grid-field__filter-header').append($extraCell);
},

injectSearchButton: function(visible) {
const hasLegacyFilterHeader = this.find('.grid-field__filter-header').length > 0;
let content;
if (visible) {
content = '<span class="non-sortable"></span>';
this.addClass('show-filter').find('.grid-field__filter-header, .grid-field__search-holder').removeClass('grid-field__search-holder--hidden');
if (!hasLegacyFilterHeader) {
this.find(':button[name=showFilter]').hide();
}
} else {
content = '<button type="button" title="Open search and filter" name="showFilter" class="btn btn-secondary font-icon-search btn--no-text btn--icon-lg grid-field__filter-open"></button>';
this.removeClass('show-filter').find('.grid-field__filter-header, .grid-field__search-holder').addClass('grid-field__search-holder--hidden');
}
if (hasLegacyFilterHeader) {
this.find('.sortable-header th:last').html(content);
}
},

/**
Expand Down Expand Up @@ -342,19 +313,17 @@ $.entwine('ss', function($) {
})

$('.grid-field :button[name=showFilter]').entwine({
onclick: function(e) {
this.closest('.grid-field')
.find('.grid-field__filter-header, .grid-field__search-holder')
.removeClass('grid-field__search-holder--hidden')
.find(':input:first').focus(); // focus first search field

this.closest('.grid-field').addClass('show-filter');
this.parent().html('<span class="non-sortable"></span>');
e.preventDefault();
}
/**
* Overrides showHide function in LeftAndMain.js
*/
showHide() {
this.closest('.grid-field').toggleClass('show-filter');
this._super();
// jQuery has to be used with this explicit name here or it won't work for some reason
jQuery(this).toggle();
},
});


$('.grid-field .ss-gridfield-item').entwine({
onclick: function (event) {
if (event.target.classList.contains('action-menu__toggle')) {
Expand Down Expand Up @@ -674,36 +643,19 @@ $.entwine('ss', function($) {
}
});

$('.js-injector-boot .grid-field .grid-field__search-holder').entwine({
Component: null,
ReactRoot: null,

$('.js-injector-boot .grid-field .search-holder').entwine({
onmatch() {
this._super();

// Make sure this appears at the top of the gridfield
this.prependTo(this.parent());
const holder = this.closest('.cms-content-filters');
holder.prependTo(holder.parent());

const cmsContent = this.closest('.cms-content').attr('id');
const context = (cmsContent)
? { context: cmsContent }
: {};

const Search = loadComponent('Search', context);
this.setComponent(Search);

this.refresh();
},

onunmatch() {
// Allow LeftAndMain.js to set up the search holder
this._super();
const root = this.getReactRoot();
if (root) {
root.unmount();
this.setReactRoot(null);
}
},

/**
* Overrides close function in LeftAndMain.js
*/
close() {
const props = this.data('schema');

Expand All @@ -729,6 +681,9 @@ $.entwine('ss', function($) {
gridField.reload({ data: ajaxData }, successCallback);
},

/**
* Overrides search function in LeftAndMain.js
*/
search(data) {
const props = this.data('schema');

Expand Down Expand Up @@ -761,29 +716,12 @@ $.entwine('ss', function($) {
gridField.reload({ data: ajaxData }, successCallback);
},

refresh() {
const props = this.data('schema');
const Search = this.getComponent();
const handleHide = () => this.close();
const handleSearch = (data) => this.search(data);
const idName = String(props.gridfield).replace(/\-/g, '.');

let root = this.getReactRoot();
if (!root) {
root = createRoot(this[0]);
}
root.render(
<Search
id={`${props.gridfield}Search`}
display="VISIBLE"
displayBehavior="HIDEABLE"
filterPrefix="Search__"
onHide={handleHide}
onSearch={handleSearch}
{...props}
/>
);
this.setReactRoot(root);
/**
* Overrides getSearchID function in LeftAndMain.js
*/
getSearchID() {
const data = this.data('schema');
return `${data.gridfield}Search`;
},
});

Expand All @@ -797,67 +735,6 @@ $.entwine('ss', function($) {
e.preventDefault();
}
}
})

/**
* Catch submission event in filter input fields, and submit the correct button
* rather than the whole form.
*/
$('.grid-field .grid-field__filter-header :input').entwine({
onmatch: function() {
var filterbtn = this.closest('.extra').find('.ss-gridfield-button-filter'),
resetbtn = this.closest('.extra').find('.ss-gridfield-button-reset');

if(this.val()) {
filterbtn.addClass('filtered');
resetbtn.addClass('filtered');
}
this._super();
},
onunmatch: function() {
this._super();
},
onkeydown: function(e) {
// Skip reset button events, they should trigger default submission
if(this.closest('.ss-gridfield-button-reset').length) return;

var filterbtn = this.closest('.extra').find('.ss-gridfield-button-filter'),
resetbtn = this.closest('.extra').find('.ss-gridfield-button-reset');

if(e.keyCode == '13') {
var btns = this.closest('.grid-field__filter-header').find('.ss-gridfield-button-filter');
var filterState='show'; //filterstate should equal current state.
if(this.hasClass('ss-gridfield-button-close')||!(this.closest('.grid-field').hasClass('show-filter'))){
filterState='hidden';
}

var ajaxData = [{
name: btns.attr('name'),
value: btns.val(),
filter: filterState,
triggerChange: false
}];

if (btns.data('action-state')) {
ajaxData.push({
name: 'ActionState',
value: JSON.stringify(btns.data('action-state')),
});
}

const gridField = $(this).getGridField();
const successCallback = function() {
gridField.keepStateInHistory();
};

gridField.reload({ data: ajaxData }, successCallback);

return false;
}else{
filterbtn.addClass('hover-alike');
resetbtn.addClass('hover-alike');
}
}
});

$(".grid-field .relation-search").entwine({
Expand Down
6 changes: 3 additions & 3 deletions client/src/legacy/LeftAndMain.EditForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ $.entwine('ss', function($){
PlaceholderHtml: '',

/**
* Variable: ChangeTrackerOptions
* (Object)
* This can be customised to change settings for the change tracker.
* See jquery.changetracker.js
*/
ChangeTrackerOptions: {
ignoreFieldSelector: '.no-change-track, .ss-upload :input, .cms-navigator :input'
ignoreFieldSelector: '',
},

/**
Expand Down
Loading

0 comments on commit 178b7d5

Please sign in to comment.