Form Input - Select Search
AJAX-powered searchable select input using Select2. For use inside Repeater or dynamic containers, use SelectTwo instead.
Basic Usage
$form->addField()->setLabel('User')->addSelectSearchControl('userId')
->setDataFromModel(UserModel::class)
->setKeyField('user_id')
->setSearchField('username')
->setValue($userId);
Data Sources
From Model
$form->addField()->setLabel('Country')->addSelectSearchControl('country')
->setDataFromModel(CountryModel::class, function ($q) {
$q->where('active', true);
$q->orderBy('name');
})
->setKeyField('country_id')
->setSearchField('name');
From SQL Query
$form->addField()->setLabel('Product')->addSelectSearchControl('product')
->setQuery('SELECT * FROM products WHERE status > 0')
->setKeyField('product_id')
->setSearchField('name');
From Collection
$collection = ProductModel::where('active', true)->get();
$form->addField()->setLabel('Product')->addSelectSearchControl('product')
->setDataFromCollection($collection)
->setKeyField('id')
->setSearchField('name');
Format
String Template
Use {field} placeholders to build the display template:
$select->setFormat('<div>{name} <span class="badge badge-success">{code}</span></div>');
Set different templates for dropdown and selected display:
$select->setFormatResult('<div>{name}<br/><small>{email}</small></div>');
$select->setFormatSelection('{name}');
Closure Format
Use a closure for complex formatting with access to the model:
$select->setFormat(function ($model) {
$div = c::div();
$div->addDiv()->add($model->name);
$div->addSpan()->addClass('badge badge-info')->add($model->code);
return $div;
});
Multiple Selection
$select->setMultiple(true);
$select->setName('countries[]');
$select->setValue(['ID', 'US', 'JP']);
Prepend Data
Add static options at the top of the results (shown on page 1):
$select->prependRow(['id' => 'ALL', 'name' => '-- All --']);
Or set all prepend data at once:
$select->setPrependData([
['id' => 'ALL', 'name' => '-- All --'],
['id' => 'NONE', 'name' => '-- None --'],
]);
Options
| Method | Description |
|---|---|
setKeyField($field) |
Primary key field name |
setSearchField($field) |
Field(s) to search on |
setSearchFullTextField($field) |
Full-text search field(s) |
setMinInputLength($n) |
Minimum characters before search triggers |
setDelay($ms) |
Debounce delay in milliseconds (default: 100) |
setPerPage($n) |
Results per AJAX page (default: 10) |
setAllowClear($bool) |
Show clear button |
setAutoSelect($bool) |
Auto-select first result |
setPlaceholder($text) |
Placeholder text |
setOnModal($bool) |
Fix z-index for use inside Bootstrap modals |
addDropdownClass($class) |
Add CSS class to dropdown |
Depends On
Filter options based on another field's value:
$continentSelect = $form->addField()->setLabel('Continent')->addSelectControl('continent')
->setList($continentList);
$countrySelect = $form->addField()->setLabel('Country')->addSelectSearchControl('country')
->setDataFromModel(CountryModel::class)
->setKeyField('code')
->setSearchField('name');
$countrySelect->setDependsOn($continentSelect, function ($q, $value) {
if (strlen($value) > 0) {
$q->where('continent', '=', $value);
}
});
Extending SelectSearch
Create a reusable custom select by extending the class:
class MyApp_FormInput_UserSelect extends CElement_FormInput_SelectSearch {
protected function build() {
parent::build();
$this->setPlaceholder('Search user...');
$this->setDataFromModel(UserModel::class);
$this->setKeyField('user_id');
$this->setSearchField(['username', 'email']);
$this->setFormat('<div>{username} <small class="text-muted">{email}</small></div>');
}
}
Value Callback
Transform field values in the response:
$select->setValueCallback(function ($row, $key, $value) {
if ($key === 'name') {
return strtoupper($value);
}
return $value;
});