It's out the box - and betterer
https://docs.silverstripe.org/en/5/changelogs/5.2.0/#searchable-dropdown-field
https://api.silverstripe.org/5/SilverStripe/Forms/SearchableDropdownField.html
Use the 3.0 version for SilverStripe 3.*, and the 4.0 version for SilverStripe 4.*
Allows the user to select from a list of options while typing. It saves an ID against a field; be in Int, Text etc. Some handy use cases would be; selecting a CSS class from a large list, selecting a user from a remote API, or selecting a SilverStripe member when you have thousands of members.
composer require otago/autocomplete-suggest-field
- Flexible autocomplete This fields lets a developer customize what goes into the autocomplete list. It populates an HTML5 element that lets the user select an option via AJAX. To build an ajax list, create an action against the provided controller with the name autocomplete. It takes a GET parameter , and outputs a json array with the format id:etc, name:etc.
- Friendly display names You can have a $has_one or $db living on a DataObject or Page, and display a friendly name instead of an ugly ID. This makes your code base tidier, lets you forget about having to force a many_many when you don't really need it, and allows your cms admins to not hate your face.
- Frontend and backend compatible the only requirement is jQuery. No entwine needed.
composer vendor-expose
vendor/silverstripe/framework/sake dev/tests/AutocompleteSuggestTest
All modern browsers support this feature. older MSIE versions do not work
The following will create a search field in the CMS. Note the logged in user has to have access to the Member object. Searching logic is handled by a controller which comes out the box with autocomplete-suggest-field.
<?php
use OP\AutocompleteSuggestField;
use SilverStripe\Security\Member;
class MyFavouriteUserPage extends Page {
private static $has_one = array(
'FavouriteUser' => Member::class
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$suggesteduser = AutocompleteSuggestField::create('FavouriteUserID', Member::create());
$suggesteduser->setDescription('Enter text to search for your favourite user');
$fields->addFieldToTab('Root.Main', $suggesteduser);
return $fields;
}
}
Below shows how a developer can create custom search queries on the same file to return results
<?php
use OP\AutocompleteSuggestField;
use SilverStripe\CMS\Controllers\ModelAsController;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\View\Requirements;
use SilverStripe\Security\Member;
class MyFavouriteUserPage extends Page {
private static $has_one = array(
'FavouriteUser' => Member::class
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$suggesteduser = AutocompleteSuggestField::create('FavouriteUserID', Member::create(), 'Favourite user', ModelAsController::controller_for($this), null);
$suggesteduser->setDescription('Enter text to search for your favourite user');
$fields->addFieldToTab('Root.Main', $suggesteduser);
return $fields;
}
}
class MyFavouriteUserPageController extends PageController {
private static $allowed_actions = array(
'autocompleteFavouriteUserID',
);
/**
* searches users in the local db
* @param SS_HTTPRequest $httprequest
*/
public function autocompleteFavouriteUserID(HTTPRequest $httprequest) {
Requirements::clear();
$query = $httprequest->getVar('query');
$returnarray = array();
if ($query && strlen($query) > 1) {
$name = explode(' ', $query);
$members = array();
if (count($name) === 1) {
$members = Member::get()->filter(array('FirstName:StartsWith:nocase' => $name[0]))->limit(10);
}
if (count($name) > 1) {
$members = Member::get()->filter(array('FirstName:StartsWith:nocase' => $name[0], 'Surname:StartsWith:nocase' => $name[1]))->limit(10);
}
foreach ($members as $member) {
$returnarray[] = array('id' => $member->ID, 'name' => $member->getName());
}
}
print_r(json_encode($returnarray));
}
}
Note the [id=>'', name=>''] JSON format
class TeamPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'autocompleteTeam'
);
/**
* used to autocomplete the teams on office 365
* @param SS_HTTPRequest $httprequest
*/
public function autocompleteTeam(SS_HTTPRequest $httprequest) {
Requirements::clear();
$query = $httprequest->getVar('query');
$returnarray = array();
if ($query && strlen($query) > 1) {
$searchresult = office365::searchForTeam(urlencode($query));
foreach ($searchresult->value as $team) {
$returnarray[] = array('id' => $team->id, 'name' => $team->displayName . ' (' . $team->description . ')');
}
}
print_r(json_encode($returnarray));
}
}