[英]Display multiple fields in ExtJs 3.3 Combo box
我已經打開了一個 ExtJs 項目,我已經有一段時間沒有開始思考了,這讓我感到困惑。
我有一個 Ext.form.ComboBox 使用遠程 JSON 商店列出用戶。 我使用 XTemplate 來格式化下拉列表中列出的用戶:
'<tpl for="."><div class="x-combo-list-item">',
'{firstname} {lastname} ({email})',
'</div></tpl>'
當我展開下拉列表時,我看到我的用戶正確列出:
約翰·史密斯 (jsmith@company.com)
約翰福特 (jford@company.com)
但是,當我單擊用戶時,組合框內容會更改為您所期望的 valueField 屬性(“名字”)。
問題:
我不想顯示 John,而是希望顯示組合框:John Smith (jsmith@company.com)。
當我有兩個 John(John Smith 和 John Ford)並加載表單時,ExtJs 邏輯與它在列表中找到的第一個 John 匹配,並將字段的值更改為它匹配的第一個 John。
例如:約翰·史密斯 (ID = 1) 約翰·福特 (ID = 2)
用戶選擇John Ford,點擊組合菜單項后組合框中出現“John”,並將user_id = 2寫入數據庫。
然而,當我重新加載頁面時,名稱“John”匹配(從數據庫加載)到第一個列表條目,如果操作員沒有手動更改下拉對話框中的選擇,則選擇 John Smith 並且 user_id = 1 現在寫入數據庫(當用戶保存表單時)。
任何輸入將不勝感激。 我的直覺告訴我在加載和發布列表單擊期間應該有幾個鈎子,這將允許我操縱寫入元素的 innerHTML 元素的內容。
~~~~~~~~~~~~~
注意:我從自定義 class 繼承,它允許我提前輸入查詢,名字,姓氏和 email 地址(因為我們可能有數百個用戶要搜索)。
我繼承自的 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);
關於問題 #1,我發現獲得良好自定義顯示字段的最佳方法是在商店使用的 Ext.data.Record 定義中使用生成的字段。 這樣,您就可以訪問完整的記錄來創建您的顯示字段,而不僅限於一個字段。 由於 Sencha 正在轉向 Ext4,我無法在線找到 3.x 示例,但您可以在 ExtJS 下載的examples/form
目錄中找到此示例。 在這里,我修改了 ExtJS 組合示例之一( examples/form/combo.js
):
var store = new Ext.data.ArrayStore({
fields: ['abbr', 'state', 'nick', {
name: 'display',
convert: function(v, rec) { return rec[1] +' - '+ rec[0] }
// display looks like 'Texas - TX'
}],
data : Ext.exampledata.states // from states.js
});
var combo = new Ext.form.ComboBox({
store: store,
displayField:'display',
typeAhead: true,
mode: 'local',
forceSelection: true,
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true,
applyTo: 'local-states'
});
現在組合顯示諸如Texas - TX
之類的值,或者您convert
output 的任何值。 您可以在Ext.data.Field 文檔中找到用於convert
的文檔。
至於問題 #2,如果您使用便利商店 + 閱讀器組合(如 JsonStore 或 ArrayStore)之一,您可能需要為您的 Ext.data.Reader 或商店設置idProperty
。 idProperty
告訴 Ext 在哪個字段中尋找唯一標識符。 如果您沒有idProperty
或者您選擇的不是唯一的,您可能會遇到各種奇怪的行為。 文檔在這里。
你只需要用下面的代碼替換你的 displayField
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item">{firstName} {lastName} {email}</div>',
'</tpl>'
),
// template for the content inside text field
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'firstName} {lastName} {email}',
'</tpl>'
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.