Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii2 DropDownList Onchange change Autocomplete Widget "source" attribute?

I have already tried this : yii2 dependent autocomplete widget

but i don't know why it's not working. here my html with 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.');}

                    '])?>

Autocomplete:

<?= $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);
                    }")
                ],
            ])?>

i want to change autocomplete source according to dropdownlist value, if S then load $s_data else load $e_data. Any help with this. Thanks.

Here's my 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();

and,

$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();
like image 820
Insane Skull Avatar asked Jul 15 '15 09:07

Insane Skull


1 Answers

Well, I've added your code snippets to my test yii2 environment to test what's wrong. So there are some problems with your code:

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

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

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

']

First of all I noticed what yii apply some escaping for quotation mark symbols for your "S" and "E", and your code in browser looks like &quot;S&quot;.

Next, jui autocomplete plugin adds a property to jquery prototype with name "autocomplete" but not "autoComplete". As for as js is case sensitive, this two names looks different for it.

So my solution was to move all js from onchange property to separate js script, as it shown below (for testing purposes you can add it right in your yii view file where you use code provided in your question)

<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>

And paste name of this new event handler to your dropdownList's onchange property like this:

['onChange' => 'holderTypeChangeHandler']

UPDATE: ---------------------

Since Yii2 Autocomplete based on JQuery UI autocomplete widget and Yii2 Autocomplete clientOptions contains settings for JUI autocomplete widget, then we can refer to JUI API docs for explanation of the source option. As you can see, this option can be a string (in this case it used as URI to JSON data), a function or an js array of data or js array of objects.

In your question you are using \yii\db\Query to fetch some data from db with help of method all(), which returns an array of data. So finally you need to convert the array of data which you get with \yii\db\Query->all to js array of objects. To do it, use php json functions, particulary for your case you need to use json_encode() function:

// Let's 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 ?> });

The same if for your $e_data. Just pay attention, your get your data from db with PHP, but use it with JS, so php array needs to be converted to a string presentation js array of objects, and this conversion you can do with json_encode.

like image 80
dajnz Avatar answered Oct 11 '22 21:10

dajnz