如何将模型数据加载到在 Yii 中使用 Ajax 过滤的 Select2 下拉列表
Posted
技术标签:
【中文标题】如何将模型数据加载到在 Yii 中使用 Ajax 过滤的 Select2 下拉列表【英文标题】:How to load model data to Select2 dropdown which uses Ajax filtering in Yii 【发布时间】: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);
【问题讨论】:
【参考方案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'=>'js:function(element,callback)var data=id:'.$model->osszetevo->id.',text:"'.$model->osszetevo->nev.'"; callback(data);',
【参考方案2】:
我试过这样做,但做不到
我想出的填写和选择记录的解决方案是:
如果属性有一些数据(在更新模式或默认值),我写了一些 javascript 在文档就绪事件之后,将用我的数据填充选择(只需选择它并在其中推送 html),并制作它选择了,然后我休息(或更新)选择以显示我的工作。
【讨论】:
以上是关于如何将模型数据加载到在 Yii 中使用 Ajax 过滤的 Select2 下拉列表的主要内容,如果未能解决你的问题,请参考以下文章
Yii2 - 使用 Ajax 加载为 Select2 插件设置值