FIX Retain custom sort on custom lists in GridFieldAddExistingAutoCompleter

Forcing sort by the first search field isn't always appropriate.
When a custom search list is used, we can set the expectation that custom sorting is intended as well.
As an example, this can be used to autocomplete based on FULLTEXT indexes,
and sort based on relevancy.
This commit is contained in:
Ingo Schommer 2020-08-04 22:02:20 +12:00
parent 821ef9559a
commit 9d03a6856c
2 changed files with 58 additions and 4 deletions

View File

@ -223,8 +223,8 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF
*/
public function doSearch($gridField, $request)
{
$searchStr = $request->getVar('gridfield_relationsearch');
$dataClass = $gridField->getModelClass();
$allList = $this->searchList ? $this->searchList : DataList::create($dataClass);
$searchFields = ($this->getSearchFields())
? $this->getSearchFields()
@ -241,12 +241,22 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF
$params = [];
foreach ($searchFields as $searchField) {
$name = (strpos($searchField, ':') !== false) ? $searchField : "$searchField:StartsWith";
$params[$name] = $request->getVar('gridfield_relationsearch');
$params[$name] = $searchStr;
}
$results = $allList
$results = null;
if ($this->searchList) {
// Assume custom sorting, don't apply default sorting
$results = $this->searchList;
} else {
$results = DataList::create($dataClass)
->sort(strtok($searchFields[0], ':'), 'ASC');
}
// Apply baseline filtering and limits which should hold regardless of any customisations
$results = $results
->subtract($gridField->getList())
->filterAny($params)
->sort(strtok($searchFields[0], ':'), 'ASC')
->limit($this->getResultsLimit());
$json = [];

View File

@ -2,10 +2,14 @@
namespace SilverStripe\Forms\Tests\GridField;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Convert;
use SilverStripe\Dev\CSSContentParser;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\Tests\GridField\GridFieldAddExistingAutocompleterTest\TestController;
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Permissions;
@ -127,4 +131,44 @@ class GridFieldAddExistingAutocompleterTest extends FunctionalTest
new ArrayList([$team1, $team2])
);
}
public function testRetainsCustomSort()
{
$component = new GridFieldAddExistingAutocompleter($targetFragment = 'before', ['Test']);
$component->setSearchFields(['Name']);
$grid = $this->getGridFieldForComponent($component);
$grid->setList(Team::get()->filter('Name', 'force-empty-list'));
$component->setSearchList(Team::get());
$request = new HTTPRequest('GET', '', ['gridfield_relationsearch' => 'Team']);
$response = $component->doSearch($grid, $request);
$this->assertFalse($response->isError());
$result = json_decode($response->getBody(), true);
$this->assertEquals(
['Team 1', 'Team 2', 'Team 3', 'Team 4'],
array_map(function ($item) { return $item['label']; }, $result)
);
$component->setSearchList(Team::get()->sort('Name', 'DESC'));
$request = new HTTPRequest('GET', '', ['gridfield_relationsearch' => 'Team']);
$response = $component->doSearch($grid, $request);
$this->assertFalse($response->isError());
$result = json_decode($response->getBody(), true);
$this->assertEquals(
['Team 4', 'Team 3', 'Team 2', 'Team 1'],
array_map(function ($item) { return $item['label']; }, $result)
);
}
protected function getGridFieldForComponent($component)
{
$config = GridFieldConfig::create()->addComponents(
$component,
new GridFieldDataColumns()
);
return (new GridField('testfield', 'testfield'))
->setConfig($config);
}
}