Skip to content

Commit

Permalink
ENHANCEMENT Support multiple search fields in GridFieldRelationAdd, a…
Browse files Browse the repository at this point in the history
…nd allowing custom result formatting (SSF-53)
  • Loading branch information
chillu committed Mar 1, 2012
1 parent 9c95a9a commit a2afe4e
Showing 1 changed file with 52 additions and 11 deletions.
63 changes: 52 additions & 11 deletions forms/gridfield/GridFieldRelationAdd.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,24 @@ class GridFieldRelationAdd implements GridField_HTMLProvider, GridField_ActionPr
protected $itemClass = 'GridFieldRelationAdd';

/**
* Which column that should be used for doing a StartsWith search
* Which columns that should be used for doing a "StartsWith" search.
* If multiple fields are provided, the filtering is performed non-exclusive.
*
* @var string
* @var Array
*/
protected $fieldToSearch = '';

protected $searchFields = array();

/**
* @var string SSViewer template to render the results presentation
*/
protected $resultsFormat = '$Title';

/**
*
* @param string $fieldToSearch which field on the object in the list should be search
* @param array $searchFields Which fields on the object in the list should be searched
*/
public function __construct($fieldToSearch, $autoSuggestion=true) {
$this->fieldToSearch = $fieldToSearch;
public function __construct($searchFields) {
$this->searchFields = (array)$searchFields;
}

/**
Expand All @@ -48,7 +53,7 @@ public function getHTMLFragments($gridField) {
$forTemplate = new ArrayData(array());
$forTemplate->Fields = new ArrayList();

$value = $this->findSingleEntry($gridField, $this->fieldToSearch, $searchState, $gridField->getList()->dataClass);
$value = $this->findSingleEntry($gridField, $this->searchFields, $searchState, $gridField->getList()->dataClass);
$searchField = new TextField('gridfield_relationsearch', _t('GridField.RelationSearch', "Relation search"), $value);
// Apparently the data-* needs to be double qouted for the jQuery.meta data plugin
$searchField->setAttribute('data-search-url', '\''.Controller::join_links($gridField->Link('search').'\''));
Expand Down Expand Up @@ -141,15 +146,51 @@ public function getURLHandlers($gridField) {
*/
public function doSearch($gridField, $request) {
$allList = DataList::create($gridField->getList()->dataClass());
$results = $allList->subtract($gridField->getList())->filter($this->fieldToSearch.':StartsWith',$request->param('ID'));
$results->sort($this->fieldToSearch, 'ASC');
$filters = array();
$stmts = array();
// TODO Replace with DataList->filterAny() once it correctly supports OR connectives
foreach($this->searchFields as $searchField) {
$stmts[] .= sprintf('"%s" LIKE \'%s%%\'', $searchField, $request->param('ID'));
}
$results = $allList->where(implode(' OR ', $stmts))->subtract($gridField->getList());
$results->sort($this->searchFields[0], 'ASC');

$json = array();
foreach($results as $result) {
$json[$result->ID] = $result->{$this->fieldToSearch};
$json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result);
}
return Convert::array2json($json);
}

/**
* @param String
*/
public function setResultsFormat($format) {
$this->resultsFormat = $format;
return $this;
}

/**
* @return String
*/
public function getResultsFormat() {
return $this->resultsFormat;
}

/**
* @param Array
*/
public function setSearchFields($fields) {
$this->searchFields = $fields;
return $this;
}

/**
* @return Array
*/
public function getSearchFields() {
return $this->searchFields;
}

/**
* This will provide a StartsWith search that only returns a value if we are
Expand Down

2 comments on commit a2afe4e

@tractorcow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chillu Hey Ingo, I'm doing some research into the history of the GridState and have come across some issues with findSingleEntry not working (or ever being called). It looks as though this commit changed the API slightly.

If you look at

protected function findSingleEntry($gridField, $field, $searchTerm, $dataclass) {
it shows the function is expecting a single column for the second parameter, but in the above change you're passing in an array of search fields (
$value = $this->findSingleEntry($gridField, $this->searchFields, $searchState, $gridField->getList()->dataClass);
). The findSingleEntry is thus never able to produce a result from the given parameters. Fortunately, since GridFieldSearchRelation is always null, this returns nothing instead of crashing.

My question is, for 3.2, can we completely drop the following? they are (as far as I can tell) extraneous.

  • Drop findSingleEntry function
  • Remove GridFieldSearchRelation GridState key
  • Remove find function from getActions and handleAction (find operation is performed through doSearch)

I've done a quick test with the above stripped out and it seems to work fine. If you don't have any complaints, I'll include the above simplifications in a part of a larger PR with a few other GridField fixes.

@chillu
Copy link
Member Author

@chillu chillu commented on a2afe4e Oct 4, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Damian, the behaviour is frankly a bit confusing to me without trying it out in depth. findSingleEntry doesn't seem to have any effect other than setting the search field text, which seems unnecessary given we have $.autocomplete showing a list of results underneath the search field. I haven't looked into how the actual adding is handled via the JS, but as long as we can retain that base functionality I'm fine with removing the things you mentioned.

Please sign in to comment.