【问题标题】:How to load model data to Select2 dropdown which uses Ajax filtering in Yii如何将模型数据加载到在 Yii 中使用 Ajax 过滤的 Select2 下拉列表
【发布时间】:2014-05-23 06:30:31
【问题描述】:

我在视图中使用以下 select2 Yii 小部件来填充下拉列表。由于准备选择列表所需的数据包含超过 2K 条记录,我使用 select2 和 minimumInputLength 参数和一个 ajax 查询来根据用户输入生成列表的部分结果。如果我创建一个新记录,我完全没有问题。它可以很好地填充所有内容,我可以将数据保存到我的数据库中。但是,我不知道如何在更新操作期间将保存的数据加载回此下拉列表。我在某处读到了 initselection 用于此目的,但我不知道如何使用它。

有人可以帮我解决这个问题吗?

我的看法:

$this->widget('ext.select2.ESelect2', array(
            'selector' => '#EtelOsszerendeles_osszetevo_id',
            'options'  => array(
                    'allowClear'=>true,
                    'placeholder'=>'Kérem válasszon összetevőt!',
                    'minimumInputLength' => 3,
                    'ajax' => array(
                            'url' => Yii::app()->createUrl('etelOsszerendeles/filterOsszetevo'),
                            'dataType' => 'json',
                            'quietMillis'=> 100,
                            'data' => 'js: function(text,page) {
                                            return {
                                                q: text,
                                                page_limit: 10,
                                                page: page,
                                            };
                                        }',
                            'results'=>'js:function(data,page) { var more = (page * 10) < data.total; return {results: data, more:more }; }',
                    ),
            ),
          ));?>

我的控制器的动作过滤器:

public function actionFilterOsszetevo()
{
    $list = EtelOsszetevo::model()->findAll('nev like :osszetevo_neve',array(':osszetevo_neve'=>"%".$_GET['q']."%"));
    $result = array();
    foreach ($list as $item){
        $result[] = array(
                'id'=>$item->id,
                'text'=>$item->nev,
        );
    }
    echo CJSON::encode($result);
}

【问题讨论】:

    标签: php jquery ajax yii jquery-select2


    【解决方案1】:

    我使用 initSelection 以这种方式加载现有记录以进行更新(我将您的一些视图代码替换为 ... 以专注于主要更改)。用 Yii 1.1.14 测试。本质上,我使用了两种不同的 ajax 调用:

    查看:

    <?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]); });
                       }
                    }',
            ),
          ));
    ?>
    

    现在在您的控制器中,您应该收到用于 ajax 处理的参数:查询 (q),作为字符串,插入时; id (id) 更新时为 int。在 $_GET 中读取时,参数名称必须与 ajax data 参数相同(在此示例中插入 q;在更新中 id)。代码未重构/优化:

    控制器:

     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(); 
     }
    

    模型 - 自定义查询和一点秩序/安全/干净:)

     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 );
     }
    

    编辑:

    当使用传统的 HTTP Post(同步,例如 Yii 生成的表单)预加载更新时,它可以开箱即用。对于异步/Ajax 更新,例如使用 JQuery:

    事件/触发器:

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

    这样,initSelection 将再次以异步方式运行,并使用新的 id_to_load 值,按 id 重新加载记录。

    根据您的情况和您的需要,initSelection 可能完全不同,以避免来自 db 或 you can use formatResult and formatSelection custom functions (are described in Load Remote Data sample source code) 的加载记录。阅读文档,我知道 initSelection 的回调需要带有 id 和文本元素的 JSON 数据才能正确加载,或者您可以尝试将这两个概念结合起来(此 initSelection 与您的自定义 JS 事件/触发器调用)(未测试):

           '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);                       
            }',
    

    或者直接在触发调用上:

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

    希望对您有所帮助。

    【讨论】:

    • 谢谢亚历杭德罗!我会试一试,很快就会回复你。
    • 我正在玩这个,但我需要对 initSelection 部分进行一些解释。实际上,我的 initSelection 过滤器操作从 url 中获取所有必需的信息,因此我不必向它传递任何数据。我认为这是您代码的第一部分在 initSelection 中所做的。因此,一旦我按下更新按钮并开始更新操作,过滤器控制器就可以返回选定的 id 和值。那么,如何将它传递给我的 select2 小部件以用作初始值?
    • @g0m3z 您好,请查看编辑部分,希望对您有所帮助
    • 感谢您抽出宝贵时间帮助我!我根据您的宝贵意见解决了这个问题,这有助于我了解 initSelection 的工作原理。我在第一次尝试时做错的是我在 ajax 定义中包含了initSelection。在我将它移到适当的位置后,它工作正常。一旦调用更新操作,我使用以下代码加载值:initSelection'=&gt;'js:function(element,callback){var data={id:'.$model-&gt;osszetevo-&gt;id.',text:"'.$model-&gt;osszetevo-&gt;nev.'"}; callback(data);}',
    【解决方案2】:

    我试过这样做,但做不到

    我想出的填写和选择记录的解决方案是:

    如果属性有一些数据(在更新模式或默认值),我写了一些 javascript 在文档就绪事件之后,将用我的数据填充选择(只需选择它并在其中推送 html),并制作它选择了,然后我休息(或更新)选择以显示我的工作。

    【讨论】:

      猜你喜欢
      • 2012-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多