簡體   English   中英

Extjs組合框:從下拉列表中隱藏選定的值

[英]Extjs combobox: hide selected value from dropdown list

我正在使用ExtJS 4並尋找一種方法可以隱藏當前從combo的下拉列表中選擇的值?

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

默認的組合框行為

我希望值列表看起來像這樣:

在此輸入圖像描述

在我的情況下,組合框是不可編輯的 (即你不能輸入任意值),我認為顯示所選值兩次沒有多大意義:一次在輸入字段中,一次在下拉列表中。 我已經看到了所選內容,我希望下拉列表只顯示我可以選擇的其他選項。

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

有人考慮過這個問題嗎? 我想做一些奇怪的事嗎? 我很驚訝我找不到任何相關主題。

我不認為你在這里有太多的選擇...也許你可以這樣做:

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,而BoundList沒有直接連接到文本字段,因此這應該可行。 你在這里做一些緩存。

我提出了另一個看起來更簡單的解決方案,快速測試顯示沒有副作用:

我們可以保持Combobox邏輯不變,只需通過CSS隱藏所選項:

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

瞧,我們沒有看到所選項目! 不知道這在生產代碼中有多可靠,但仍值得考慮,我認為......


UPDATE。 如果您想通過Combobox的config標志控制此行為,這是完整的解決方案:

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

更新2.發現我的方法的UI問題!

隱藏下拉列表中的所選項目會引入鍵盤導航的怪癖:盡管元素在視覺上是隱藏的,但它仍然存在,當您按向上/向下鍵時,Ext將選擇它。 視覺上這意味着您的選擇將在某個時刻消失,您將不得不再次向上/向下按下以使其返回到下一個可見元素。

到目前為止,我無法找到一個簡單的解決方案。 我最好的辦法是修改綁定列表的itemSelector (這是一個數據視圖),將其設置為.x-boundlist-item:not(.x-boundlist-selected)這樣所選元素就不會成功進入查詢。

當選擇器本身工作時,它不能解決問題,因為View在任何其他類(包括選定的項類)應用於項之前執行此選擇器查詢(這發生在Ext.view.AbstractView.refresh()中

此外,此解決方案在組合框上方出現時會導致下拉列表錯誤放置!

我有一種感覺,我的方法很容易完美地工作:)

我最終使用@ sra解決方案的修改版本:

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); 之前 this.callParent(arguments); 如果我們試圖將相同的值設置兩次 (它只是在商店中找不到活動記錄,因為我們將其刪除,因此它將重置為空白),否則組合框將表現得很奇怪。 我暫停了商店的事件,以防止組合框在我操作選擇的記錄時試圖與其下拉列表同步導致的一些怪癖,並在我完成時手動觸發商店的'refresh'事件,最終更新列表。 這可能會對性能產生影響,但到目前為止我還不知道更好的解決方案。

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

所以我使用了@ sra的解決方案,但是經過一些小修改,將內容添加到if(!me.hideActive)下面的正確位置:

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

這樣你就不會把它們添加到按鈕中。 我知道這是一個老帖子,但我希望它可以幫助人們尋找解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM