javascript - 在 ExtJs 3.3 组合框中显示多个字段

标签 javascript extjs combobox extjs3

我已经打开了一个 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 属性(“firstname”)。

问题:

  1. 我不希望显示 John,而是希望组合框显示:John Smith (jsmith@company.com)。

  2. 当我有两个 John(John Smith 和 John Ford)并加载表单时,ExtJs 逻辑匹配它在列表中找到的第一个 John,并将字段的值更改为它匹配的第一个 John .

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

用户选择了 John Ford,单击组合菜单项后“John”出现在组合框中,并且 user_id = 2 被写入数据库。

然而,当我重新加载页面时,名称“John”与第一个列表条目匹配(从数据库加载),如果运算符(operator)没有手动更改下拉对话框中的选择,则选择 John Smith并且 user_id = 1 现在被写入数据库(当用户保存表单时)。

任何输入将不胜感激。我的直觉告诉我,在加载和发布列表单击期间应该有几个 Hook ,这将使我能够操纵写入元素的 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);

最佳答案

关于问题 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 的输出。您可以在 Ext.data.Field docs 中找到有关 convert 的文档.

至于问题 #2,如果您使用的是 JsonStore 或 ArrayStore 等方便的商店 + 阅读器组合之一,您可能需要为您的 Ext.data.Reader 或您的商店设置 idProperty . idProperty 告诉 Ext 在哪个字段中寻找唯一标识符。如果您没有 idProperty 或者您选择了一个不唯一的属性,您可能会遇到各种奇怪的行为。文档是 here .

关于javascript - 在 ExtJs 3.3 组合框中显示多个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5862267/

相关文章:

javascript - ExtJS 4.2 动态生成多个相似数据源的Model+Store+View

.net - 分页在 extjs 网格中不起作用,与 Ajax 调用绑定(bind)

css - ExtJS 中禁用组件的样式不一致

javascript - .mousedown() 仅对每个元素调用一次

javascript - 在 Angular 中加载页面时提交表单

javascript - Chrome 中的图像预加载 Canvas

javascript - 编辑记录时显示所选值

Silverlight:ComboBox.ItemTemplate 中的 ContentPresenter 在单击 ComboBox 时会导致所有内容崩溃

c# - 当输入的文本不是数据源的一部分时处理 WPF 可编辑组合框

wpf - wpf datagrid 性能问题中的组合框列