Skip to content

Commit

Permalink
FIX Clear filter from url state
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Sep 14, 2023
1 parent c9913dc commit 6fe1f6f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 25 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

68 changes: 47 additions & 21 deletions client/src/legacy/GridField.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,42 +200,68 @@ $.entwine('ss', function($) {
}
},

/**
* This will first retrieve state of the gridfield which is generated by PHP and sent to the
* browser as HTML via PJAX and stored in the data-schema attribute on all of the '3 dots'
* elements on each gridfield row
*
* It will then update the browser location with the new state of the gridfield using
* window.ss.router
*
* This allows users to bookmark different views in the CMS
*/
keepStateInHistory: function() {
const newSchema = $(this).find('.gridfield-actionmenu__container').data('schema');
const gridFieldName = $(this).data('name');
if (newSchema && newSchema.length > 0) {
newSchema.filter( e => {
if (e.type === 'link') {
const reqString = this.buildURLString(e.url)
const searchParam = reqString ? '?' + reqString.join('&') : '';
window.ss.router.replace(window.location.pathname + searchParam, undefined, undefined, false);
const urlQueryString = this.buildUrlQueryString(e.url, gridFieldName);
window.ss.router.replace(window.location.pathname + urlQueryString, undefined, undefined, false);
}
})
}
},

/**
* A params string can have duplicate keys.
* Function buildURLString splits string to "key => value" array
* and replaces values for existing keys with the new value
* and returns string with unique keys only
* Builds a url query string from the existing query string in window.location
* and overrides it with the params from the query string in the pjaxUrl param
*
* For any query string params that relate to the gridState of the gridFieldName, only
* take these from the pjaxUrl param
*
* @param {string} url
* @returns string
*/
buildURLString: function(url) {
const link = [window.location.origin, url].join('/');
const params = [window.location.search, (new URL(link)).searchParams.toString()].join('&').substring(1);
const newrequest = [];
const reqString = [];
params.split('&').forEach(param => {
const newVal = param.split('=');
newrequest[newVal[0]] = newVal[1] ? newVal[1] : '';
});
Object.keys(newrequest).forEach(param => {
reqString.push([param, newrequest[param]].join('='));
});

return reqString;
buildUrlQueryString: function(pjaxUrl, gridFieldName) {
const locationObj = {};
for (const param of window.location.search.replace(/^\?/, '').split('&')) {
const [key, val] = param.split('=');
// This regex will naively match the gridfield number \-[0-9]$, so if there are multiple
// gridfields with the same name (i.e. class) on the screen, it will be overly
// aggressive in removing their state. This limitation is because I couldn't find an
// easy way to extract the gridfield number from the gridfield
if (key.match(new RegExp(`^gridState\\-${gridFieldName}\\-[0-9]$`))) {
continue;
}
locationObj[key] = val;
}
const pjaxUrlObj = {};
const link = [window.location.origin, pjaxUrl].join('/');
const searchParams = (new URL(link)).searchParams;
for (const [key, val] of searchParams.entries()) {
pjaxUrlObj[key] = val;
}
const retObj = Object.assign(locationObj, pjaxUrlObj);
const retArr = [];
for (const key in retObj) {
if (key === '') {
continue;
}
const val = retObj[key];
retArr.push([key, val].join('='));
}
return retArr.length === 0 ? '' : '?' + retArr.join('&');
}
});

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"silverstripe/frameworktest": "^0.4.3",
"silverstripe/frameworktest": "^0.4.14",
"squizlabs/php_codesniffer": "^3",
"nikic/php-parser": "^3 || ^4",
"monolog/monolog": "~1.16"
Expand Down
29 changes: 27 additions & 2 deletions tests/behat/features/gridfield-search.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ Feature: Search in GridField
So that I see proper result and don't see warning

Background:
Given the "Company" "Walmart" with "Category"="Retail"
And the "Company" "ExxonMobil" with "Category"="Oil"
Given the "Company" "ExxonMobil" with "Category"="Oil"
And the "Company" "Vitol" with "Category"="Other"
And the "Company" "Walmart" with "Category"="Retail"
And the "Company" "Walmart B" with "Category"="Retail"
And the "Company" "Walmart C" with "Category"="Retail"
And the "Company" "Walmart D" with "Category"="Retail"
And the "group" "EDITOR" has permissions "Access to 'Pages' section" and "Access to 'Test ModelAdmin' section" and "TEST_DATAOBJECT_EDIT"
# This extension will limit to only showing 3 records per page so that pagination shows
And I add an extension "FrameworkTestModelAdminExtension" to the "TestModelAdmin" class
And I am logged in as a member of "EDITOR" group
And I go to "/admin/test"

Expand All @@ -23,3 +28,23 @@ Feature: Search in GridField
And I click "Walmart" in the "#Form_EditForm" element
Then I should see "Walmart"
And I should see "Walmart" in the ".breadcrumbs-wrapper" element

@sboyd
Scenario: I can clear search and paginate
When I press the "Open search and filter" button
# This will match on all of the "Walmart" records
And I fill in "SearchBox__q" with "a a"
And I press the "Enter" key in the "SearchBox__q" field
Then the "[name=SearchBox__q]" element "value" attribute should be "a a"
And I should see "Walmart" in the ".ss-gridfield-item:nth-of-type(1) .col-Name" element
And I should see "Walmart B" in the ".ss-gridfield-item:nth-of-type(2) .col-Name" element
And I should see "Walmart C" in the ".ss-gridfield-item:nth-of-type(3) .col-Name" element
And I should not see "ExxonMobil" in the ".col-Name" element
And I should not see "Vitol" in the ".col-Name" element
And I click on the ".search-box__cancel" element
When I click on the "#action_pagination_next" element
And I press the "Open search and filter" button
Then the "[name=SearchBox__q]" element "value" attribute should be ""
And I should see "Walmart B" in the ".ss-gridfield-item:nth-of-type(1) .col-Name" element
And I should see "Walmart C" in the ".ss-gridfield-item:nth-of-type(2) .col-Name" element
And I should see "Walmart D" in the ".ss-gridfield-item:nth-of-type(3) .col-Name" element

0 comments on commit 6fe1f6f

Please sign in to comment.