2011-05-02 82 views
6

我已經打開了一段ExtJs項目,但我一直沒有進入這個項目,這讓我感到莫名其妙。在ExtJs 3.3中顯示多個字段組合框

我有一個使用遠程JSON存儲來列出用戶的Ext.form.ComboBox。我使用XTemplate格式化用戶在下拉菜單中列出:

'<tpl for="."><div class="x-combo-list-item">', 
'{firstname} {lastname} ({email})', 
'</div></tpl>' 

當我展開下拉,我看到我的用戶正確列出:

約翰·史密斯([email protected]

約翰·福特([email protected]

然而,當我點擊一個用戶,組合框內容更改爲valueField財產(「姓」),你期望的那樣。

問題:

  1. 而不是顯示約翰的,我想在組合框中顯示:約翰·史密斯([email protected])。

  2. 當我有兩個John's(John Smith和John Ford)和表單加載時,ExtJs邏輯會匹配它在列表中找到的第一個John並將該字段的值更改爲匹配的第一個John。

例如: 約翰·史密斯(ID = 1) 約翰·福特(ID = 2)

用戶選擇約翰·福特,和 「John」 出現在組合框他們點擊過的後組合菜單項和user_id = 2被寫入數據庫。

但是,當我重新加載頁面時,名稱「John」與數據庫匹配(從數據庫加載)到第一個列表項,並且如果操作員沒有在下拉對話框中手動更改選擇,那麼John Smith是現在將選定的user_id = 1寫入數據庫(當用戶保存表單時)。

任何輸入將不勝感激。我的直覺告訴我,在加載和發佈列表單擊時應該有幾個鉤子,這將允許我操作寫入元素的innerHTML元素的內容。

~~~~~~~~~~~~~

注:我已經從一個自定義的類,它可以讓我提前鍵入反對,名字,姓氏和電子郵件地址查詢(繼承,因爲我們可能可能有數百個用戶進行搜索)。

我繼承的組合框元素:

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

回答

10

關於問題#1,最好的辦法,我發現獲得良好的自定義顯示的字段是在Ext.data.Record定義中使用生成的場該商店使用。通過這種方式,您可以獲得創建顯示字段的完整記錄,而不僅限於一個字段。我現在無法在網上找到3.x示例,Sencha正在轉向Ext4,但您可以在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輸出。您可以在Ext.data.Field docs中找到convert的文檔。

至於問題#2,如果您使用JsonStore或ArrayStore等方便的商店+閱讀器組合,則可能需要爲Ext.data.Reader或您的商店設置idPropertyidProperty告訴Ext尋找唯一標識符的字段。如果你沒有idProperty或者你選擇了一個不唯一的行爲,你可以得到各種奇怪的行爲。 Docs for here

+0

奇妙,以取代displayField,工作就像一個魅力。關於第二點 - 我確實設置了idProprety,但粗略的測試表明它已經作爲解決方案的結果被修復爲#1。乾杯! – Duncan 2011-05-03 11:11:32

+0

感謝這個解決方案,它對我的​​一個項目非常有用:) – 2011-05-30 15:42:01

2

你只需要使用下面的代碼

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>' 
) 
+0

對我來說這是partilly作品,當我點擊下拉列表時顯示在displayField值上的下拉值不是xtemplete值。 – 2015-03-30 13:09:07