2012-09-04 129 views
7

我正在使用ExtJS 4並尋找一種方法,可以從組合的下拉列表中隱藏當前選定的值?Extjs組合框:從下拉列表中隱藏選定的值

所以不是這個( 「阿拉斯加」 目前在組合框中選擇)的:

default combobox behaviour

我希望值的列表如下所示:

enter image description here

在我的情況下,組合框是不可編輯(即你不能輸入一個任意值),我不認爲這顯示選定的值兩次是很有意義的:一旦在內把字段和一次在下拉列表中。我已經看到選擇了什麼,我想要下拉列表只顯示我其他選項我可以選擇。

到目前爲止,我沒有看到一個簡單的方法來做到這一點。可能最好的地方是過濾組合框存儲,但組合框使用自己的過濾器進行實時搜索功能。

有人認爲這個問題?我想做些奇怪的事情嗎? 我很驚訝,我一直沒有找到任何相關的主題。

+0

在Sencha的論壇上提出同樣的問題:http://www.sencha.com/forum/showthread.php?241063-Combobox-hide-selected-value-from-dropdown-list&p=882210 –

回答

1

我結束了使用修改版本的@ sra的如此lution:

Ext.define('My.ComboBox', { 
    extend: 'Ext.form.field.ComboBox', 

    /** 
    * @cfg {Boolean} hideActive=true 
    * When true, hides the currently selected value from the dropdown list 
    */ 
    hideActive: true, 

    /** 
    * @private {Ext.data.Model[]} selectedRecords 
    * A Array of selected records, used when hideActive is true 
    */ 

    initComponent: function() { 
     this.selectedRecords = []; 

     this.callParent(); 
    }, 


    setValue: function(value, doSelect) { 
     var store = this.store; 

     if(this.hideActive) { 
      store.suspendEvents(false); 
      // write the current selected back to the store (you need to suspend autoSync if active) 
      // do this BEFORE callParent so the currently selected record would be found in the store 
      store.add(this.selectedRecords); 
     } 

     this.callParent(arguments); 

     if(this.hideActive) { 
      // set the selected as new recordlist 
      this.selectedRecords = this.valueModels; 
      // remove the selected from the store 
      store.remove(this.valueModels); 
      store.resumeEvents(); 
      store.fireEvent('refresh', store); 
     } 

     return this; 
    } 

}); 

的「隱藏」的邏輯是一樣的,只是我在setValue方法來執行它,以確保它也可以當編程設定組合的價值,包括在組合框與值初始化的情況下, 。

UPD此外,貌似store.add(this.selectedRecords);有被稱爲this.callParent(arguments);之前,否則,如果我們嘗試設置相同值的兩倍(它根本不會發現在店裏的活動記錄組合框將採取行動怪異導致我們刪除它,所以它將重置爲空白)。 我暫停商店的事件,以防止組合框引起的一些怪癖試圖與我的操作與選定的記錄(s)中下拉列表同步和手動觸發商店的'refresh'事件時,我完成了,因此列表最終得到更新。這可能會對性能產生影響,但到目前爲止我還不知道更好的解決方案。

5

我不認爲你有很多選擇這裏...也許你可以做這樣的事情:

Ext.define('Your.company.Combo', { 
    extend: 'Ext.form.field.ComboBox', 
    alias: 'widget.specialcombo', 

    /** 
    * @cfg {boolean} hideActive 
    * True to hide any selected record. Defaults to <tt>true</tt>. 
    */ 
    hideActive: true, 

    /** 
    * @private {Ext.data.Model[]} hideActive 
    * A Array of selected records. 
    */ 


    initComponent: function() { 
     this.selectedRecords = []; 

     this.callParent(arguments); 

     this.on('select', this.onSelectionChange, this); 
    }, 

    /** 
    * @private onChangeSelection 
    * eventhandler selections 
    */ 
    onSelectionChange: function (me, recs) { 
     if(!me.hideActive) 
      return; 
     // write the current selected back to the store (you need to suspend autoSync if active) 
     me.store.add(me.selectedRecords); 
     // set the selected as new recordlist 
     me.selectedRecords = recs; 
     // remove the selected from the store 
     me.store.remove(recs); 
    } 
}); 

這個例子是沒有經過測試。但由於商店主要綁定到不直接連接到文本框的BoundList,因此應該可以工作。你正在這裏做一種緩存。

+0

這個想法看起來不錯我但代碼不起作用。 'this.on('select',function(){this.onSelectionChange();},this);'應該改爲'this.on('select',this.onSelectionChange,this);'讓它工作正確地說'hideActive:false'也沒有效果。 – pllee

+0

感謝您的建議。我監督了這些事情。修復是 – sra

+0

謝謝,這似乎是伎倆!編輯你的代碼一點,現在它的功能。 –

3

我想出了另一種解決方案,看起來更加簡單和快速的測試顯示無副作用:

我們可以把組合框的邏輯不變,而只是通過CSS隱藏選定項目:

.x-boundlist-selected { 
    display: none; 
} 

而且瞧,我們沒有看到選定的項目!不知道怎麼可靠,這將是在生產代碼,但還是值得考慮的,我想......


更新。下面是完整的解決方案,如果你想控制通過組合框的配置將此行爲:

Ext.define('My.ComboBox', { 
    extend: 'Ext.form.field.ComboBox', 

    /** 
    * @cfg {Boolean} hideActive=true 
    * When true, hides the currently selected value from the dropdown list 
    */ 
    hideActive: true, 

    /** 
    * Internal method that creates the BoundList 
    */ 
    createPicker: function() { 
     var picker = this.callParent(arguments); 

     // honor the hideActive flag 
     if(this.hideActive) { 
     picker.addCls('x-boundlist-hideactive'); 
     } 

     return picker; 
    } 
}); 

某處在你的CSS:

.x-boundlist-hideactive .x-boundlist-selected { 
    display: none; 
} 

UPDATE 2.發現一個UI問題我的方法!

從下拉列表中隱藏選定的項目引入了鍵盤導航的怪癖:儘管該元素在視覺上隱藏,但它仍然存在,並且按下UP/DOWN鍵時Ext將選擇它。在視覺上,這意味着你的選擇會在某個時候消失,你將不得不再次按下UP/DOWN來重新顯示下一個可見元素。

到目前爲止,我無法找到一個簡單的解決方案。 我最好的辦法是修改綁定列表(這是一個數據視圖)的itemSelector,將其設置爲.x-boundlist-item:not(.x-boundlist-selected)之類的東西,以便所選元素不會將其添加到查詢中。

而選擇自己的工作,因爲視圖執行之前的任何其他類此選擇查詢(包括所選項目類),它並沒有解決這個問題得到應用到項目(這發生在Ext.view.AbstractView.refresh()

此外,該解決方案將導致下拉列表錯位,當它出現在組合框上面!

我有一種感覺,我的做法是太容易工作得很好:)

+0

好點,我猜更快。從來沒有嘗試過。 – sra

+0

我會留下現在不被接受的答案,好奇是否有人想出其他想法... –

+0

這完全取決於你:)但是你可以晚些時候不接受答案。這就像信息 – sra

1

ExtJS 3我在其他人的基礎上寫了這個答案。對我來說很好,它的一點點改變了你的需求。

Name.space.name = new Ext.extend(Ext.form.ComboBox, { 
    type: 'all', 
    oldrec: null, 
    store: null, 
    constructor: function (config) { 
     var me = this; 
     if (config.type === 'all') { 
      me.store = AllConditionStore; 
     } else { 
      me.store = ?.?('RuleParameterType'); 
     } 
     config = Ext.apply({ 
      store: me.store, 
      valueField: 'id', 
      hideActive: true, 
      triggerAction: 'all', 
      lazyRender: true, 
      allowBlank: false, 
      mode: 'local', 
      displayField: 'text', 
      listeners: { 
       select: function (me, recs, index) { 
        if (me.oldrec !== null) 
         me.store.add(me.oldrec); 
        me.oldrec = recs; 
        // remove the selected from the store 
        me.store.remove(recs); 
        // redo store 
       } 
      } 
     }, config); 
     ?.?.Parameter.superclass.constructor.call(this, config); 
    } 
}); 
0

所以我用@ SRA解決方案,但有一個小的修改,以在適當的地方加上下面的if(!me.hideActive)內容:

if(me.selectedRecords[0]) { 
    me.store.insert(me.selectedRecords[0].index,me.selectedRecords); 
} 

這樣,你只是不將它們添加到鈕。我知道這是一箇舊帖子,但我希望它能幫助尋找解決方案的人。

相關問題