How to load model data to Select2 dropdown which uses Ajax filtering in Yii

浪子不回头ぞ 提交于 2019-12-06 01:29:34

I use initSelection to load existing record for update in this way (I replaced some of your view code with ... to focus in main changes). Tested with Yii 1.1.14. Essentially, I use two different ajax calls:

View:

<?php

$this->widget('ext.select2.ESelect2', array(
        'selector' => '#EtelOsszerendeles_osszetevo_id',
        'options'  => array(
                ...
                ...
                'ajax' => array(
                        'url' => Yii::app()->createUrl('client/searchByQuery'),
                        ...
                        ...
                        'data' => 'js: function(text,page) {
                                        return {
                                            q: text,
                                            ...
                                        };
                                    }',
                        ...
                ),
                'initSelection'=>'js:function(element,callback) {
                   var id=$(element).val(); // read #selector value
                   if ( id !== "" ) {
                     $.ajax("'.Yii::app()->createUrl('client/searchById').'", {
                       data: { id: id },
                       dataType: "json"
                     }).done(function(data,textStatus, jqXHR) { callback(data[0]); });
                   }
                }',
        ),
      ));
?>

Now in your controller you should receive parameters for ajax processing: query (q), as string, when inserting; id (id) as int when updating. Parameter names must be same as ajax data parameters (in this sample insert q; in update id) when read in $_GET. Code is not refactored/optimized:

Controller:

 public function actionSearchByQuery(){
        $data = Client::model()->searchByQuery( (string)$_GET['q'] );
        $result = array();
        foreach($data as $item):
           $result[] = array(
               'id'   => $item->id,
               'text' => $item->name,
           );
        endforeach;
        header('Content-type: application/json');
        echo CJSON::encode( $result );
        Yii::app()->end(); 
 }

 public function actionSearchById(){
        $data = Client::model()->findByPk( (int) $_GET['id'] );
        $result = array();
        foreach($data as $item):
           $result[] = array(
               'id'   => $item->id,
               'text' => $item->name,
           );
        endforeach;
        header('Content-type: application/json');
        echo CJSON::encode( $result );
        Yii::app()->end(); 
 }

Model - custom query and a little of order / security / clean :)

 public function searchByQuery( $query='' ) {
        $criteria = new CDbCriteria;
        $criteria->select    = 'id, ssn, full_name';
        $criteria->condition = "ssn LIKE :ssn OR full_name LIKE :full_name";
        $criteria->params = array (
            ':ssn' => '%'. $query .'%',
            ':full_name' => '%'. $query .'%',
        );
        $criteria->limit = 10;
        return $this->findAll( $criteria );
 }

EDIT:

It works out of box when update is preloaded with traditional HTTP Post (synchronous, for example with Yii generated forms). For async/Ajax updates, for example with JQuery:

Event / Trigger:

$('#button').on("click", function(e) {
        ...  
        ... your update logic, ajax request, read values, etc
        ...
        $('#select2_element').select2('val', id_to_load );
});

With this, initSelection will run again in async way with new id_to_load value, reloading record by id.

In your case and for your needs, initSelection could be complete different to avoid load record from db or you can use formatResult and formatSelection custom functions (are described in Load Remote Data sample source code). Reading documentation, I understand that initSelection's callback need JSON data with id and text elements to load properly or you could try to combine both concepts (this initSelection with your custom JS event/trigger call) (not tested):

       'initSelection'=>'js:function(element,callback) {
                   // here your code to load and build your values,
                   // this is very basic sample 
                   var id='myId'; 
                   var text='myValue'; 
                   data = {
                     "id": id,
                     "text": text
                   }
                   callback(data);                       
        }',

Or directly on Trigger call:

$('#button').on("click", function(e) {
        ...  
        ...             ...
        $("#select2_element").select2("data", {id: "myId", text: "MyVal"});
});

Hope that helps.

I tried doing that way, but couldn't do it

the solution I came up to get my record filled and selected was:

In case of the attribute having some data(in update mode or default value), I wrote some javascript that after document ready event, would fill the select with my data (just selected it ind pushed html in it), and made it selected, and then I rest( or update) the select to show my work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!