# Select2

# Базовое использование

<xf:macro name="tc_clib_select2_macros::select2_includes" />

<div class="block">
    <div class="block-container">
        <div class="block-body">
            <xf:selectrow data-xf-init="tc-s2-select" label="OS" placeholder="Choose…">
                <xf:option></xf:option>
                <xf:optgroup label="Desktop">
                    <xf:option value="linux">Linux</xf:option>
                    <xf:option value="windows">Windows</xf:option>
                    <xf:option value="osx">OS X</xf:option>
                </xf:optgroup>
                <xf:optgroup label="Mobile">
                    <xf:option value="android">Android</xf:option>
                    <xf:option value="ios">IOS</xf:option>
                    <xf:option value="blackberry">BlackBerry</xf:option>
                </xf:optgroup>
                <xf:option value="other">Other</xf:option>
            </xf:selectrow>
        </div>
    </div>
</div>

Базовое использование
Базовое использование

# TeslaCloud.S2Select (tc-s2-select)

# Параметры

Параметр Значение по умолчанию Описание Настройка Select2
allowClear* false Если true, к полю выбора будет добавлена кнопка очистки. allowClear
closeOnSelect* true Если true, выпадающий список будет закрыт после выбора. closeOnSelect
dropdownAutoWidth false dropdownAutoWidth
dropdownCssClass Дополнительные классы CSS для выпадающего списка.
:all: добавит все классы, присутствующие в исходном элементе <select>.
dropdownCssClass
dropdownParent* $(document.body) Селектор для настройки положения выпадающего меню. dropdownParent
maxLength* 0 Максимальное количество символов для поискового запроса.
maxLength < 1 — без ограничений.
maximumInputLength
maxSelection 0 Максимальное количество опций, которые могут быть выбраны.
maxSelection < 1 — без ограничений.
maximumSelectionLength
minLength* 0 Минимальное количество символов, необходимое для начала поиска. minimumInputLength
minimumResultsForSearch* 0 Минимальное количество опций, необходимое для отображения окна поиска.
minimumResultsForSearch < 0 — отключить поиск.
minimumResultsForSearch
selectionCssClass Дополнительные классы CSS для контейнера выбора.
:all: добавит все классы, присутствующие в исходном элементе <select>.
selectionCssClass
selectOnClose* false Если true, после закрытия выпадающего списка будет выбрана опция, выделенная перед закрытием. selectOnClose
tags* false Если true, будет разрешено указание пользовательских значений. tags
theme* tc-clib_s2select theme
tokens [','] Список символов, которые следует использовать в качестве разделителей токенов. tokenSeparators
width* 100% Настройка ширины контейнера. width
scrollAfterSelect* false scrollAfterSelect
searchUrl URL для поисковых запросов.
data* null Массив объектов опций. data
resultTemplate** {{{styledText}}} Шаблон для отображения опции в выпадающем меню.
resultTemplateIconic** {{{iconHtml}}}&nbsp;{{{styledText}}} Шаблон для отображения варианта выбора с иконкой в выпадающем меню.
selectionTemplate*** {{{text}}} Шаблон для отображения выбранной опции.
selectionTemplateIconic*** {{{iconHtml}}}&nbsp;{{{text}}} Шаблон для отображения выбранной опции с иконкой.

* Подробности в документации Select2.
** См. Dropdown — Templating и Шаблонизация.
*** См. Selections — Templating и Шаблонизация.

# Получение данных через AJAX

Кроме генерации списка опций из HTML, существует возможность загрузки данных через AJAX.
Для включения загрузки через AJAX необходимо задать URL для поисковых запросов в параметре searchUrl.

При изменении значения в поле поиска на указанный URL выполнится GET запрос со следующими параметрами:

Параметр Описание
term Текущий поисковый запрос в поле поиска.
q Содержит то же, что и term.
_type Тип запроса. Если выполняется запрос к первой странице — query, в противном случае — query_append.
page Номер запрашиваемой страницы. Параметр присутствует только в запросах с пагинацией.

В ответ сервер должен вернуть ответ со следующим содержимым:

Ключ Описание
results* Массив с результатами поиска. См. ниже.
pagination Пагинация.
Единственный параметр — more, если true, при прокрутке до конца списка будет выполнен запрос к следующей странице.

Результаты поиска без группировки:

Ключ Описание
id* ID результата, который будет использоваться в качестве значения value опции. Любое значение, отличное от нуля.
text* Текст опции.
selected Если true, опция будет выбрана по умолчанию.
disabled Если true, опция будет недоступна для выбора.
iconHtml HTML-код для отображаемой иконки.
q Текущий поисковый запрос. Используется для выделения совпадения.

Результаты поиска с группировкой:

Ключ Описание
text* Название группы.
children* Массив с результатами поиска. То же, что и без группировки.

* Обязательно

# Пример поиска пользователей

<xf:macro name="tc_clib_select2_macros::select2_includes" />

<div class="block">
    <div class="block-container">
        <div class="block-body">
            <xf:selectrow data-xf-init="tc-s2-select"
                          label="Username" placeholder="Enter username…"
                          data-min-length="2" data-search-url="{{ link('members/find') }}" />
        </div>
    </div>
</div>

Поиск пользователей
Поиск пользователей

# Пример поиска иконок Font Awesome

<xf:macro name="tc_clib_select2_macros::select2_includes" />

<div class="block">
    <div class="block-container">
        <div class="block-body">
            <xf:selectrow data-xf-init="tc-s2-select" multiple="true"
                          label="Icon" placeholder="Find icon…"
                          data-min-length="2" data-search-url="{{ link('demo/find-fa-icon') }}" />
        </div>
    </div>
</div>

Код контроллера:

<?php

namespace Demo\Pub\Controller;

use XF;
use XF\Mvc\Reply\View;
use XF\Pub\Controller\AbstractController;

class Demo extends AbstractController
{
    /**
     * @return View
     */
    public function actionFindFaIcon()
    {
        $results = [];

        $query = $this->filter('q', 'str');
        if ($query)
        {
           foreach (XF::app()->data('XF:FontAwesome')->getIconMetadata() as $icon => $data)
           {
              if (
                 stripos($icon, $query) === 0
                 || stripos($data['label'], $query) === 0
              )
              {
                 $results[] = [
                    'id'   => $icon,
                    'text' => $data['label'],
                    'q'    => $query
                 ];
              }
           }
        }

        $reply = $this->view();
        $reply->setJsonParams([
           'results' => $results
        ]);

        return $reply;
    }
}

Поиск иконок FontAwesome
Поиск иконок FontAwesome

# Шаблонизация

Select2 позволяет изменить внешний вид выбранных опций и их списка в выпадающем меню. Для этого в TeslaCloud.S2Select возможно задать шаблоны, компилируемые библиотекой mustache.js.
Шаблоны задаются параметрами selectionTemplate и resultTemplate для выбранных опций и их списка в выпадающем меню соответственно. Шаблоны опций с иконками передаются параметрами с постфиксом Iconic (resultTemplateIconic и selectionTemplateIconic).

В шаблонах доступны следующие переменные:

Переменная Описание
id ID результата, который будет использоваться в качестве значения опции. Любое значение, отличное от нуля.
text Текст опции без форматирования (в том виде, в каком он был в теле опции или при поиске через AJAX).
styledText Отформатированный текст опции. При поиске через AJAX, совпадение с поисковым запросом будет выделено через <strong>.
selected Если true, опция будет выбрана по умолчанию.
disabled Если true, опция будет недоступна для выбора.
iconHtml HTML-код для отображаемой иконки. Код иконки может быть задан из HTML с помощью атрибута data-icon-html в <option>.
q Текущий поисковый запрос. Используется для выделения совпадения.

При поиске через AJAX могут присутствовать и другие переменные, переданные в ответе сервера.

# Пример отображения иконок в списке, сгенерированном из HTML

<xf:macro name="tc_clib_select2_macros::select2_includes" />

<div class="block">
    <div class="block-container">
        <div class="block-body">
            <xf:selectrow data-xf-init="tc-s2-select" label="OS" placeholder="Choose…">
                <xf:option></xf:option>
                <xf:optgroup label="Desktop">
                    <xf:option value="linux" data-icon-html="<i class='fab fa-linux fa-fw'></i>">Linux</xf:option>
                    <xf:option value="windows" data-icon-html="<i class='fab fa-windows fa-fw'></i>">Windows</xf:option>
                    <xf:option value="osx" data-icon-html="<i class='fab fa-apple fa-fw'></i>">OS X</xf:option>
                </xf:optgroup>
                <xf:optgroup label="Mobile">
                    <xf:option value="android" data-icon-html="<i class='fab fa-android fa-fw'></i>">Android</xf:option>
                    <xf:option value="ios" data-icon-html="<i class='fab fa-apple fa-fw'></i>">IOS</xf:option>
                    <xf:option value="blackberry" data-icon-html="<i class='fab fa-blackberry fa-fw'></i>">BlackBerry</xf:option>
                </xf:optgroup>
                <xf:option value="other">Other</xf:option>
            </xf:selectrow>
        </div>
    </div>
</div>

Иконки из HTML
Иконки из HTML

# Пример отображения иконок в списке при поиске через AJAX

Шаблон идентичен шаблону из данного примера. В коде контроллера к результатам поиска добавляется иконка:

                 $results[] = [
                    'id'   => $icon,
                    'text' => $data['label'],
+                   'iconHtml' => XF::app()->templater()->fontAwesome(
+                       ($data['is_brand'] ? 'fab ' : '') . 'fa-' . $icon
+                   ),
                    'q'    => $query
                 ];

Иконки из AJAX
Иконки из AJAX