Select2. Добавить, если не найден.

Вопросы по вёрстке и JavaScript
Ответить
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Select2. Добавить, если не найден.

Сообщение Uterm »

Задача: реализовать подбор в инпут из справочника, при отсутствии нужного элемента в справочнике - сделать удобное его добавление.

Использую Select2 виджет от картика (kartik\select2\Select2). Если элемент в справочнике не найден, сделал вывод кнопки "Добавить в справочник".

Код: Выделить всё

                    <?= $form->field($item, "[{$i}]product_id")->widget(Select2::classname(), [
                        'data' => ArrayHelper::map(Product::find()->all(), 'id', 'title'),
                        'options' => ['placeholder' => $item->getAttributeLabel('product_id')],
                        'pluginOptions' => [
                            'language' => [
                                'noResults' => new JsExpression('function () { return "<button type=\"button\" class=\"btn btn-info btn-xs\">Добавить в справочник</button>"; }'),
                            ],
                            'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
                            'allowClear' => true,
                        ],
                    ])->label(false) ?>
Теперь мне надо как то реализовать добавление, или хотя бы вывод всплывающего окна для добавления элемента в справочник. Подскажите как такое можно сделать?
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Select2. Добавить, если не найден.

Сообщение Loveorigami »

Я делал немного по другому.
рядом ставил кнопку для bootstrap modal. Если не находил - нажимал ее. В модальное окно подгружал вид для создания записи.
После закрытия окна в select делал append последней записи.

Дела при помощи
https://github.com/karnbrockgmbh/yii2-modal-ajax/pulls

Правда, там нашел один баг
https://github.com/karnbrockgmbh/yii2-m ... x/issues/2

Сделал PR
но пока не приняли https://github.com/karnbrockgmbh/yii2-modal-ajax/pull/3

временно можете стянуть пакет у меня
https://github.com/loveorigami/yii2-modal-ajax
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Re: Select2. Добавить, если не найден.

Сообщение Uterm »

Спасибо за помощь, а можно посмотреть код касающийся вот этого:
Loveorigami писал(а):После закрытия окна в select делал append последней записи.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Select2. Добавить, если не найден.

Сообщение Loveorigami »

Примерно так (скопировал из проекта)
тут без appenda, т.к. данные получаю через ajax
Настройки select2 - все стандартно.

Код: Выделить всё

        $widgetOptions = ArrayHelper::merge([
            'initValueText' => $val, // set the initial display text
            'options' => [
                'prompt'=>'',
                'id' => $this->fieldId,
            ],
            'pluginOptions' => [
                'allowClear' => false,
                'minimumInputLength' => 2,
                'ajax' => [
                    'url' => $url,
                    'dataType' => 'json',
                    'data' => new JsExpression('function(params) { return {q:params.term}; }')
                ],
                'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
                'templateResult' => new JsExpression('function(data) { return data.text; }'),
                'templateSelection' => new JsExpression('function (data) { return data.text; }'),
            ],
        ], $this->widgetOptions, ["options" => $options]);

Функция на закрытие окна

Код: Выделить всё

        $theme = Select2::THEME_DEFAULT;
        $js = <<<JS

$('#add-$this->fieldId').on('kbModalSubmit', function(event, data, status, xhr) {
    console.log('kbModalSubmit' + status);
    if(status){
        $(this).modal('toggle');
        $('#$this->fieldId').html('').select2({
            theme: '$theme',
            data:
            [
               {id: data['id'], text: data['name']}
            ]
        });
    }
});

JS;

        $view=\Yii::$app->getView();
        $view->registerJs($js);
 
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Re: Select2. Добавить, если не найден.

Сообщение Uterm »

Спасибо за информацию, смысл я уловил, решил сделать примерно так же. Начал с простого переделывания select2 на ajax и застрял. Не подгружает список по аяксу, крутит загрузку и все. Попробовал сделать на чистом basic и приближенно к демке картика. Сделал две таблички: city (id, name, description) и order (id, city). Вот код:

Код: Выделить всё

// views\site\index.php

$cityDesc = empty($model->city) ? '' : City::findOne($model->city)->description;

echo $form->field($model, 'city')->widget(Select2::classname(), [
    'initValueText' => $cityDesc,
    'options' => ['placeholder' => 'Search for a city ...'],
    'pluginOptions' => [
        'allowClear' => true,
        'minimumInputLength' => 3,
        'ajax' => [
            'url' => Url::to(['list-items']),
            'dataType' => 'json',
            'data' => new JsExpression('function(params) { return {q:params.term}; }')
        ],
        'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
        'templateResult' => new JsExpression('function(city) { return city.text; }'),
        'templateSelection' => new JsExpression('function (city) { return city.text; }'),
    ],
]);
 

Код: Выделить всё

// controllers\SiteController.php

public function actionIndex()
{
    $model = new Order();
    return $this->render('index', [
        'model' => $model,
    ]);
}

public function actionListItems($q = null, $id = null) {
    Yii::$app->response->format = Response::FORMAT_JSON;
    $out = ['results' => ['id' => '', 'text' => '']];
    if (!is_null($q)) {
        $query = new Query;
        $query->select('id, name AS text')
            ->from('city')
            ->where(['like', 'name', $q])
            ->limit(20);
        $command = $query->createCommand();
        $data = $command->queryAll();
        $out['results'] = array_values($data);
    }
    elseif ($id > 0) {
        $out['results'] = ['id' => $id, 'text' => City::find($id)->name];
    }
    return $out;
}
 
Подскажите пожалуйста, где закралась ошибка?
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Re: Select2. Добавить, если не найден.

Сообщение Uterm »

Дайте пожалуйста рабочий код работы select2 через ajax, и структуру таблиц.
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Re: Select2. Добавить, если не найден.

Сообщение Uterm »

Нашел ошибку. Не указал namespace для Query в контроллере :)
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Select2. Добавить, если не найден.

Сообщение Loveorigami »

Только "дошел" до форума... )))

Рад, что разобрались сами
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Re: Select2. Добавить, если не найден.

Сообщение Uterm »

Как бы мне теперь скрестить виджет модального окна и мою кнопку "Добавить в справочник", которая появляется если noResults в select2...
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Select2. Добавить, если не найден.

Сообщение Loveorigami »

Эт я не знаю... У меня кнопка находится сразу на странице... Не нашел - нажал - добавил...

По ходу пока писал, такая идея - сделайте кнопку скрытой. Если нет результата - показывайте ее ).
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Select2. Добавить, если не найден.

Сообщение ElisDN »

Можно без кнопки прямо в списке свой вариант выводить:

Код: Выделить всё

if ($data) {
    $out['results'] = array_values($data);
} else {
    $out['results'] = ['id' => 0, 'text' => $q],
}
Uterm
Сообщения: 82
Зарегистрирован: 2013.11.18, 16:08

Re: Select2. Добавить, если не найден.

Сообщение Uterm »

Дмитрий,
у меня с вашим вариантом не работает. Больше не пишет "Совпадений не найдено", но и в инпут не вставляет, просто висит окно поиска и все.
Ответить