在 ExtJs 3.3 组合框中显示多个字段
我已经打开了一个 ExtJs 项目,我已经有一段时间没有考虑过这个项目了,这让我感到困惑。
我有一个 Ext.form.ComboBox,它使用远程 JSON 存储来列出用户。我使用 XTemplate 来格式化下拉列表中列出的用户:
'<tpl for="."><div class="x-combo-list-item">',
'{firstname} {lastname} ({email})',
'</div></tpl>'
当我展开下拉列表时,我看到我的用户正确列出:
John Smith ([电子邮件受保护])
John Ford ([电子邮件受保护])
但是,当我单击用户时,组合框内容会更改为您所期望的 valueField 属性(“名字”)。
问题:
-
我希望组合框显示:John Smith ([电子邮件受保护])。
-
当我有两个约翰(约翰·史密斯和约翰·福特)并且加载表单时,ExtJs 逻辑会与它在列表中找到的第一个约翰进行匹配,并将字段的值更改为它匹配的第一个约翰。
例如: 约翰·史密斯 (ID = 1) John Ford (ID = 2)
用户选择 John Ford,单击组合菜单项后组合框中会出现“John”,并且 user_id = 2 会写入数据库。
但是,当我重新加载页面时,名称“John”将与第一个列表条目匹配(从数据库加载),并且如果操作员没有手动更改下拉对话框中的选择,则选择 John Smith 并且 user_id = 1 现在已写入数据库(当用户保存表单时)。
任何意见将不胜感激。我的直觉告诉我,在加载和发布列表单击期间应该有几个钩子,这将允许我操纵写入元素的 innerHTML 元素的内容。
~~~~~~~~~~~~~
注意:我继承了一个自定义类,该类允许我提前输入名字、姓氏和电子邮件地址的查询(因为我们可能有数百个用户需要搜索) )。
我继承的 ComboBox 元素:
CW.form.CustomComboBox = Ext.extend( Ext.form.ComboBox, {
filterKeys:[],
// Note: This overrides the standard doQuery function in Ext 3.3
doQuery: function(q, forceAll){
q = Ext.isEmpty(q) ? '' : q;
var qe = {
query: q,
forceAll: forceAll,
combo: this,
cancel:false
};
if(this.fireEvent('beforequery', qe)===false || qe.cancel){
return false;
}
q = qe.query;
forceAll = qe.forceAll;
if(forceAll === true || (q.length >= this.minChars)){
if(this.lastQuery !== q){
this.lastQuery = q;
if(this.mode == 'local'){
this.selectedIndex = -1;
if(forceAll){
this.store.clearFilter();
}else{
// this.store.filter(this.displayField, q);
this.store.filterBy( function(rec,id){
return this.filterFn(rec,id,q);
}, this );
}
this.onLoad();
}else{
this.store.baseParams[this.queryParam] = q;
this.store.load({
params: this.getParams(q)
});
this.expand();
}
}else{
this.selectedIndex = -1;
this.onLoad();
}
}
},
/**
* Custom function for filtering the store
*/
filterFn: function(rec, id, q ){
// var filterKeys = ['id', 'firstname', 'lastname', 'email'];
var parts = q.split(' ');
// If no filter applied then show no results
if(parts.length == 0){
return false;
}
// Iterate through each of the parts of the user string
// They must all match, at least in part, one of the filterKeys
// (i.e. id, email, firstname, etc.)
for(i=0; i<parts.length;i++){
var foundPart = false;
// Create a RegExp object for this search snippet (i.e. '@gmai')
var matcher = this.store.data.createValueMatcher(parts[i] , true);
// Search until this matches one of the keys for this record
for(j=0;j<this.filterKeys.length; j++){
if(matcher.test(rec.get(this.filterKeys[j]))){
foundPart = true;
break;
}
}
// If there are no fields of the record matching this part,
// the record does not match (return false)
if( foundPart == false ){
return false;
}
}
return true;
},
initComponent: function(){
Ext.applyIf(this,{
listeners:{
beforequery: function(qe){
delete qe.combo.lastQuery;
return true;
}
}
});
if(this.filterKeys.length == 0){
this.filterKeys = [this.displayField];
}
CW.form.CustomComboBox.superclass.initComponent.call(this);
}
});
Ext.reg('custom-combo', CW.form.CustomComboBox);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于问题#1,我发现获得良好的自定义显示字段的最佳方法是使用商店使用的 Ext.data.Record 定义中的生成字段。这样您就可以获得完整的记录来创建您的显示字段,而不仅限于一个字段。由于 Sencha 正在转向 Ext4,我无法在网上找到 3.x 示例,但您可以在 ExtJS 下载的
examples/form
目录中找到此示例。在这里,我修改了 ExtJS 组合示例之一 (examples/form/combo.js
):现在组合显示诸如
Texas - TX
之类的值,或者您拥有的任何值转换
输出。您可以在 convert 的文档="noreferrer">Ext.data.Field 文档。对于问题 #2,如果您使用 JsonStore 或 ArrayStore 等便利店 + 阅读器组合之一,则可能需要为 Ext.data.Reader 或您的商店设置
idProperty
。idProperty
告诉 Ext 在哪个字段中查找唯一标识符。如果您没有 idProperty 或者您选择的不是唯一的,您可能会遇到各种奇怪的行为。相关文档位于此处。Regarding issue #1, the best way I have found to get good custom display fields is to use generated fields in the Ext.data.Record definition that the Store uses. That way you get the full record to access to create your display field and aren't limited to just one field. I can't find the 3.x examples online now that Sencha is moving on to Ext4, but you can find this example in the
examples/form
directory of your ExtJS download. Here I've modified one of the ExtJS combo examples (examples/form/combo.js
):And now the combo displays values like
Texas - TX
, or whatever you haveconvert
output. You can find documentation forconvert
in the Ext.data.Field docs.As for issue #2, you may need to set the
idProperty
for your Ext.data.Reader or your store if you're using one of the convenient store + reader combos like JsonStore or ArrayStore.idProperty
tells Ext which field to look for for a unique identifier. You can get all kinds of weird behavior if you don't have anidProperty
or you choose one that isn't unique. Docs for that are here.您只需要将您的 displayField 替换为以下代码
You just need to replace your displayField with the below code