Yii2 DropDownList Onchange изменить атрибут Autocomplete Widget "source"?

Я уже пробовал это: yii2 зависимый виджет автозаполнения

но я не знаю, почему он не работает. здесь мой html с script:

<?= $form->field($model, 'lbt_holder_type')->dropDownList(['prompt' => '--- Select Holder Type ---', 'S' => 'Student', 'E' => 'Employee'], 
                    ['onChange' => 'JS: var value = (this.value); 
                                if(value == "S"){$(#libraryborrowtransaction-name).autoComplete({source: '. $s_data.');}
                                if(value == "E"){$(#libraryborrowtransaction-name).autoComplete({source: '. $e_data.');}

                    '])?>

Автозаполнение:

<?= $form->field($model, 'name')->widget(\yii\jui\AutoComplete::classname(), [
                'options' => ['class' => 'form-control', 'placeholder' => 'Enter Name/ID'],
                'clientOptions' => [
                    'source' => $s_data,
                    'autoFill' => true,
                    'minLength' => '1',
                    'select' => new yii\web\JsExpression("function( event, ui ) {
                        $('#libraryborrowtransaction-lbt_holder_id').val(ui.item.id);
                    }")
                ],
            ])?>

Я хочу изменить источник автозаполнения в соответствии со значением dropdownlist, если S затем загрузить $s_data else загрузить $e_data. Любая помощь в этом. Спасибо.

Здесь мои данные,

$s_data = (new \yii\db\Query())
->select(["CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as value","CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as label","s_info.stu_info_stu_master_id as id"])
->from('stu_master stu')
->join('join','stu_info s_info','s_info.stu_info_id = stu_master_stu_info_id')
->where('is_status = 0')
->all();

и

$e_data = (new \yii\db\Query())
    ->select(["CONCAT(emp_unique_id, ' - ',emp_first_name,' ',emp_last_name) as value","info.emp_info_emp_master_id as id"])
    ->from('emp_master emp')
    ->join('join', 'emp_info info', 'info.emp_info_id = emp_info_emp_master_id')
    ->where('is_status = 0')        
    ->all();

Ответ 1

Ну, я добавил фрагменты кода в свою тестовую среду yii2, чтобы проверить, что не так. Таким образом, есть некоторые проблемы с вашим кодом:

[
   'onChange' => 
       'JS: var value = (this.value); 

       if(value == "S"){$(#libraryborrowtransaction-name).
           autoComplete({source: '. $s_data.');}

       if(value == "E"){$(#libraryborrowtransaction-name).
           autoComplete({source: '. $e_data.');}

']

Прежде всего, я заметил, что yii применяют некоторые escape-символы для символов кавычек для ваших "S" и "E", а ваш код в браузере выглядит как &quot;S&quot;.

Далее, плагин jui autocomplete добавляет свойство прототипу jquery с именем "autocomplete", но не "autocomplete". А поскольку js чувствителен к регистру, эти два имени выглядят по-разному.

Итак, мое решение состояло в том, чтобы переместить все js из свойства onchange для разделения js script, как показано ниже (для целей тестирования вы можете добавить его прямо в свой файл просмотра yii, где вы используете код, указанный в вашем вопросе)

<script>
    function holderTypeChangeHandler(ev) {
        var value = (this.value); 
        if(value == 'S'){
            $('#libraryborrowtransaction-name').autocomplete({source: ' . $s_data . '});
        }
        if(value == 'E'){
            $('#libraryborrowtransaction-name').autocomplete({source: ' . $e_data . '});
        } 
    }
    window.onload = function(){
        $('#libraryborrowtransaction-lbt_holder_type').on('change', holderTypeChangeHandler);

    };
</script>

И вставьте имя этого нового обработчика событий в свойство dropdownList onchange следующим образом:

['onChange' => 'holderTypeChangeHandler']

ОБНОВЛЕНИЕ: ---------------------

Так как автозаполнение Yii2 на основе виджета автозаполнения JQuery UI и автозаполнения Yii2 clientOptions содержит параметры для виджета автозаполнения JUI, тогда мы можем обратиться к JUI API для объяснения опции source. Как вы можете видеть, эта опция может быть строкой (в этом случае она используется как URI для данных JSON), функцией или массивом js данных или массивом объектов js.

В вашем вопросе вы используете \yii\db\Query для получения некоторых данных из db с помощью method all(), который возвращает массив данные. Итак, вам нужно преобразовать массив данных, который вы получаете с помощью \yii\db\Query->all в массив объектов js. Чтобы сделать это, используйте php json functions, особенно для вашего случая вам нужно использовать функцию json_encode():

// Let say this is a result of your query to db with use of `\yii\db\Query->...->all();`
$some_array = [                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    [                                                                                                                                                    
        "value" => "Val 1",                                                                                                                                
        "label" => "Label 1",
        "id" => 1
    ],
    [
        "value" => "Val 2",
        "label" => "Label 2",
        "id" => 2
    ]
]

// Just convert it to json string
$s_data = json_encode($some_array);
...
// When concat this json string as a value of source attribute for Yii Autocomplete
$('#libraryborrowtransaction-name').autocomplete({source: <?= $s_data ?> });

То же самое, если для вашего $e_data. Просто обратите внимание, вы получаете свои данные из db с помощью PHP, но используете его с JS, поэтому php-массив необходимо преобразовать в массив строк js-представления объектов, и это преобразование можно сделать с помощью json_encode.