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...
],
],
];
}
}