Control: Select2 - 10quality/wpmvc-addon-administrator GitHub Wiki
Control used as a field type to display a Select2 control (<select>).
| Control | Data type | Description |
|---|---|---|
wide |
bool |
Flag that indicates if the input should display wider or small. Default: false
|
add_empty |
bool |
Flag that indicates if an empty option should be added. Default: false
|
empty_label |
string |
Empty option label. Default: `` |
attributes |
array |
HTML attributes listed as an array. Select2 JS options can be set as a data attribute. |
| Attribute | Data type | Description |
|---|---|---|
placeholder |
string |
String to display as input placeholder. Default: `` |
multiple |
bool |
Flag that indicates if supports multiple selection. Default: false
|
data-allow-clear |
int |
See select2 configuration options. Default: 0
|
data-tags |
int |
See select2 configuration options. Default: 0
|
data-select-on-close |
int |
See select2 configuration options. Default: 0
|
data-scroll-after-select |
int |
See select2 configuration options. Default: 0
|
data-min-input-length |
int |
See select2 configuration options. Default: 0
|
data-max-input-length |
int |
See select2 configuration options. Default: 0
|
data-max-selection-length |
int |
See select2 configuration options. Default: 0
|
data-min-results-search |
int |
See select2 configuration options. Default: 0
|
data-container-class |
int |
See select2 configuration options. Default: `` |
data-ajax |
string |
Remote data source URL. See select2 ajax options. Default: `` |
data-ajax-data-type |
string |
See select2 ajax options. Default: json
|
data-ajax-delay |
int |
See select2 ajax options. Default: `` |
data-ajax-cache |
int |
See select2 ajax options. Default: `` |
data-ajax-request |
string |
Name of a window JS function that will process the request sent to the server. See select2 ajax options ajax.data. Default: Custom addon function
|
data-ajax-results |
string |
Name of a window JS function that will process the results received from the server. See select2 ajax options ajax.processResults. Default: Custom addon function
|
data-template-results |
string |
Name of a window JS function that will format the results. See select2 configuration options templateResult. Default: `` |
data-template-selection |
string |
Name of a window JS function that will format the selection. See select2 configuration options templateSelection. Default: `` |
data-sorter |
string |
Name of a window JS function that will sort results. See select2 configuration options sorter. Default: `` |
data-tokenizer |
string |
Name of a window JS function that will tokenize. See select2 configuration options tokenizer. Default: `` |
data-init-selection |
string |
Name of a window JS function that will process the initial selection. See select2 configuration options initSelection. Default: `` |
data-matcher |
string |
Name of a window JS function that will match results. See select2 configuration options matcher. Default: `` |
// Namespace and use statement...
class Settings extends Model
{
// Class properties...
protected function init()
{
// Other properties...
$this->tabs = [
'tab_id' => [
'fields' => [
'field_id' => [
'type' => 'select2',
'title' => __( 'Select 2', 'my-domain' ),
'description' => __( 'Replacement for regular select.' ),
'options' => [
'a' => __( 'Option A', 'my-domain' ),
'b' => __( 'Option B', 'my-domain' ),
'c' => __( 'Option C', 'my-domain' ),
],
'control' => [
'wide' => true,
],
],
// Other fields...
],
],
];
}
}// Namespace and use statement...
class Settings extends Model
{
// Class properties...
protected function init()
{
// Other properties...
$this->tabs = [
'tab_id' => [
'fields' => [
'field_id' => [
'type' => 'select2',
'title' => __( 'Select 2 multiple', 'my-domain' ),
'description' => __( 'Multiple selection.' ),
'options' => [
'a' => __( 'Option A', 'my-domain' ),
'b' => __( 'Option B', 'my-domain' ),
'c' => __( 'Option C', 'my-domain' ),
'd' => __( 'Option D', 'my-domain' ),
'e' => __( 'Option E', 'my-domain' ),
],
'control' => [
'wide' => true,
'attributes' => [
'placeholder' => __( 'Select an option...', 'my-domain' ),
'multiple' => true,
'data-allow-clear' => 1,
]
],
],
// Other fields...
],
],
];
}
}// Namespace and use statement...
class Settings extends Model
{
// Class properties...
protected function init()
{
// Other properties...
$this->tabs = [
'tab_id' => [
'fields' => [
'field_id' => [
'type' => 'select2',
'title' => __( 'Select 2 remote', 'my-domain' ),
'description' => __( 'Use select 2 with a remote AJAX url. Example searches users.' ),
'control' => [
'wide' => true,
'attributes' => [
'data-ajax' => admin_url( '/admin-ajax.php?action=select2_users' ),
]
],
],
// Other fields...
],
],
];
}
}You will need to create an ajax endpoint handler in order to provide data to the select2.
Add a similar hook at your Main.php file:
$this->add_action( 'wp_ajax_select2_users', 'AjaxController@ajax_users' );And inside your AjaxController place a similar code to:
/**
* @hook wp_ajax_select2_users
*/
public function ajax_users()
{
$response = new Response;
$response->data = [];
try {
// Request
$request = [
'term' => Request::input( 'term' ),
];
if ( empty( $request['term'] ) ) {
$response->error( 'term', 'Empty search term.' );
}
if ( $response->passes ) {
$response->data = QueryBuilder::create()
->select( 'users.ID as `id`' )
->select( 'users.user_email as `text`' )
->select( 'users.user_login as `username`' )
->from( 'users as users' )
->join( 'usermeta as name', [
[
'key_a' => 'name.user_id',
'key_b' => 'users.ID',
],
[
'key' => 'name.meta_key',
'operator' => 'IN',
'value' => ['first_name', 'last_name'],
],
] )
->keywords( $request['term'], ['users.user_login', 'name.meta_value'] )
->group_by( 'users.ID' )
->get( ARRAY_A );
$response->success = true;
}
} catch ( Exception $e ) {
Log::error( $e );
}
$response->json();
}NOTE: The example above uses the QueryBuilder module class to query the database with the provided search term. Select2 needs to recieve at least an id and a text field on every results row.
Change the response data structure to like this:
/**
* @hook wp_ajax_select2_users
*/
public function ajax_users()
{
$response = new Response;
$response->data = [];
try {
// Request
$request = [
'term' => Request::input( 'term' ),
'page' => Request::input( 'page', 1 ),
'limit' => 10,
];
// Some validations...
if ( $response->passes ) {
$response->data['results'] = QueryBuilder::create()
//
->limit( $request['limit'] )
->offset( $request['limit'] * ( $request['page'] - 1 ) )
->get( ARRAY_A );
$response->data['pagination'] = count( $response->data['results'] ) === $request['limit'];
$response->success = true;
}
} catch ( Exception $e ) {
Log::error( $e );
}
$response->json();
}Once saved, the data stored by the results' row property id. If no filter is added, the id value will be displayed when the settings page is rendered.
To fix this, use filter administrator_value_{field_id} to change what should be displayed instead, for example:
/**
* @hook administrator_value_{field_id}
*/
public function field_id_value( $id )
{
$user = get_user_by( 'id', $id );
return $user->user_email;
}The addon comes with the global JS function select2_format_html that will convert the property text of every result's row into HTML. Usage example:
// Namespace and use statement...
class Settings extends Model
{
// Class properties...
protected function init()
{
// Other properties...
$this->tabs = [
'tab_id' => [
'fields' => [
'field_id' => [
'type' => 'select2',
'title' => __( 'Select 2 remote', 'my-domain' ),
'control' => [
'wide' => true,
'attributes' => [
'data-ajax' => admin_url( '/admin-ajax.php?action=select2_users' ),
'data-template-results' => 'select2_format_html',
]
],
],
// Other fields...
],
],
];
}
}An example on how to change the text returned by the response into HTML`:
/**
* @hook wp_ajax_select2_users
*/
public function ajax_users()
{
$response = new Response;
$response->data = [];
try {
// ...
if ( $response->passes ) {
$view_engine = $this->view;
$response->data = QueryBuilder::create()
// ...
->get( ARRAY_A, function( $row ) use( &$view_engine ) {
$row['text'] = $view_engine->get( 'view.key', $row );
return $row;
} );
$response->success = true;
}
} catch ( Exception $e ) {
Log::error( $e );
}
$response->json();
}IMPORTANT: Take into consideration, sending HTML from the server is slower than doing it via Javascript.
You can format and change the way results are presented by adding a custom window (global) JS function and a custom HTML template.
Create a JS script in your assets, something like this:
function format_user_results( row ) {
if ( row.loading ) {
return row.text;
}
var $template = jQuery( jQuery( '#select2-user' ).html() );
for ( var prop in row ) {
$template.find( '*[role="' + prop + '"]' ).html( row[prop] );
}
return $template;
}Add the compiled script to your auto-enqueue configuration, like this:
return [
// Other settings...
'autoenqueue' => [
'enabled' => true,
'assets' => [
[
'asset' => 'js/admin.js',
'id' => 'admin-settings',
'dep' => ['jquery'],
'footer' => true,
'is_admin' => true,
'enqueue' => false,
]
],
],
];Enqueue the file using method enqueue() inside your settings model:
public function enqueue()
{
wp_enqueue_script( 'admin-settings' );
}Add a template view at the footer of the settings page, like this at Main.php:
$this->add_action( 'administrator_footer_{model id}', '[email protected]' );And with a view that look like this:
<script id="select2-user" type="text/template">
<div class="select2-result-user clearfix">
<div class="user-email"><strong role="text"></strong></div>
<div class="user-details"><small role="username"></small></div>
</div>
</script>Finally, indicate the name of the global function at the control options of the field:
// Namespace and use statement...
class Settings extends Model
{
// Class properties...
protected function init()
{
// Other properties...
$this->tabs = [
'tab_id' => [
'fields' => [
'field_id' => [
'type' => 'select2',
'title' => __( 'Select 2 remote', 'my-domain' ),
'control' => [
'wide' => true,
'attributes' => [
'data-ajax' => admin_url( '/admin-ajax.php?action=select2_users' ),
'data-template-results' => 'format_user_results',
]
],
],
// Other fields...
],
],
];
}
}

