我有一个ExtJS Combobox,并且需要有一个额外的值,用户可以从第一个值中选择所有选项,如下所示:
Ext.onReady(function () {
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbreviation', 'name'],
data: [{
name: 'Select all',
abbreviation: 'ALL'
},
{
name: 'ALABAMA',
abbreviation: 'AL'
}, {
name: 'ALASKA',
abbreviation: 'AK'
}, {
name: 'AMERICAN SAMOA',
abbreviation: 'AS'
}, {
name: 'ARIZONA',
abbreviation: 'AZ'
}, {
name: 'ARKANSAS',
abbreviation: 'AR'
}, {
name: 'CALIFORNIA',
abbreviation: 'CA'
}, {
name: 'COLORADO',
abbreviation: 'CO'
}, {
name: 'CONNECTICUT',
abbreviation: 'CT'
}, {
name: 'DELAWARE',
abbreviation: 'DE'
}, {
name: 'DISTRICT OF COLUMBIA',
abbreviation: 'DC'
}, {
name: 'FEDERATED STATES OF MICRONESIA',
abbreviation: 'FM'
}, {
name: 'FLORIDA',
abbreviation: 'FL'
}, {
name: 'GEORGIA',
abbreviation: 'GA'
}, {
name: 'GUAM',
abbreviation: 'GU'
}, {
name: 'HAWAII',
abbreviation: 'HI'
}, {
name: 'IDAHO',
abbreviation: 'ID'
}, {
name: 'ILLINOIS',
abbreviation: 'IL'
}, {
name: 'INDIANA',
abbreviation: 'IN'
}, {
name: 'IOWA',
abbreviation: 'IA'
}, {
name: 'KANSAS',
abbreviation: 'KS'
}, {
name: 'KENTUCKY',
abbreviation: 'KY'
}, {
name: 'LOUISIANA',
abbreviation: 'LA'
}, {
name: 'MAINE',
abbreviation: 'ME'
}, {
name: 'MARSHALL ISLANDS',
abbreviation: 'MH'
}, {
name: 'MARYLAND',
abbreviation: 'MD'
}, {
name: 'MASSACHUSETTS',
abbreviation: 'MA'
}, {
name: 'MICHIGAN',
abbreviation: 'MI'
}, {
name: 'MINNESOTA',
abbreviation: 'MN'
}, {
name: 'MISSISSIPPI',
abbreviation: 'MS'
}, {
name: 'MISSOURI',
abbreviation: 'MO'
}, {
name: 'MONTANA',
abbreviation: 'MT'
}, {
name: 'NEBRASKA',
abbreviation: 'NE'
}, {
name: 'NEVADA',
abbreviation: 'NV'
}, {
name: 'NEW HAMPSHIRE',
abbreviation: 'NH'
}, {
name: 'NEW JERSEY',
abbreviation: 'NJ'
}, {
name: 'NEW MEXICO',
abbreviation: 'NM'
}, {
name: 'NEW YORK',
abbreviation: 'NY'
}, {
name: 'NORTH CAROLINA',
abbreviation: 'NC'
}, {
name: 'NORTH DAKOTA',
abbreviation: 'ND'
}, {
name: 'NORTHERN MARIANA ISLANDS',
abbreviation: 'MP'
}, {
name: 'OHIO',
abbreviation: 'OH'
}, {
name: 'OKLAHOMA',
abbreviation: 'OK'
}, {
name: 'OREGON',
abbreviation: 'OR'
}, {
name: 'PALAU',
abbreviation: 'PW'
}, {
name: 'PENNSYLVANIA',
abbreviation: 'PA'
}, {
name: 'PUERTO RICO',
abbreviation: 'PR'
}, {
name: 'RHODE ISLAND',
abbreviation: 'RI'
}, {
name: 'SOUTH CAROLINA',
abbreviation: 'SC'
}, {
name: 'SOUTH DAKOTA',
abbreviation: 'SD'
}, {
name: 'TENNESSEE',
abbreviation: 'TN'
}, {
name: 'TEXAS',
abbreviation: 'TX'
}, {
name: 'UTAH',
abbreviation: 'UT'
}, {
name: 'VERMONT',
abbreviation: 'VT'
}, {
name: 'VIRGIN ISLANDS',
abbreviation: 'VI'
}, {
name: 'VIRGINIA',
abbreviation: 'VA'
}, {
name: 'WASHINGTON',
abbreviation: 'WA'
}, {
name: 'WEST VIRGINIA',
abbreviation: 'WV'
}, {
name: 'WISCONSIN',
abbreviation: 'WI'
}, {
name: 'WYOMING',
abbreviation: 'WY'
}]
});
Ext.define('comboSelectedCount', {
alias: 'plugin.selectedCount',
init: function (combo) {
var fl = combo.getFieldLabel();
combo.on({
select: function (me, records) {
var len = records.length,
store = combo.getStore();
// toggle all selections
Ext.each(records, function (obj, i, recordsItself) {
if (records[i].data.abbreviation === 'ALL') {
len = store.getCount();
combo.select(store.getRange());
}
});
me.setFieldLabel(fl + ' (' + len + ' selected)');
},
beforedeselect: function (me, record, index) {
me.setFieldLabel(fl);
}
})
}
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
disabled: false,
plugins: ['selectedCount'],
fieldLabel: 'Choose State',
labelAlign: 'top',
store: states,
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'abbreviation',
renderTo: Ext.getBody(),
multiSelect: true,
maxSelections: 3,
width: 400,
displayTpl: '<tpl for=".">' +
'{name}' +
'<tpl if="xindex < xcount">, </tpl>' +
'</tpl>',
listConfig: {
itemTpl: '{name} <div class="chkbox"></div>'
},
listeners: {
}
});
});
当用户取消选中“全选”或选择除“全选”之外的任何其他项目时,我希望能够取消全部选择。
无法弄清楚如何做到这一点?
JSFiddle:http://jsfiddle.net/dFEsc/1/
答案 0 :(得分:5)
我认为在combo存储中添加“全选”项是个坏主意 - 插件依赖于商店中的数据。 最好将其添加到下拉列表并编辑插件,添加触发器:
afterrender: function () {
combo.container.on({
click: function(e) {
var el = e.getTarget('div', 3, true);
if(el.getAttribute('action') == 'select-all') {
if( ! allSelected) {
combo.select(combo.getStore().getRange());
combo.setSelectedCount(combo.getStore().getRange().length);
el.setHTML('Deselect all...');
allSelected = true;
}else{
combo.reset();
el.setHTML('Select all...');
allSelected = false;
}
}
}
})
}
Ext.each(记录...... - 这都是胡说八道......
请参阅 jsfiddle
上的完整示例<强>更新强>
我还认为在字段中添加一个tpl也更好,可以将一个插件添加到任何组合框中以添加插件。
在插件'init'函数中:
Ext.apply(combo, {
listConfig: {
tpl : new Ext.XTemplate(
'<div action="select-all" class="sel-all">Select all...</div><tpl for="."><div class="x-boundlist-item">{name} <div class="chkbox"></div></div></tpl>'
)
}
});
然后不必描述每个组合框的listConfig。 jsfiddle上的链接也更新了。
<强> UPDATE2:强>
答案 1 :(得分:2)
这并不是您所要求的,因为如果您在单击全选后单击任何其他内容,则不会取消全选。但我认为这是一种更常见的行为。如果单击全部选中两次,您仍然可以取消选择全部。
这是代码(快速脏了。我相信它可以稍微调整一下)
Ext.define('comboSelectedCount', {
alias: 'plugin.selectedCount',
init: function (combo) {
var fl = combo.getFieldLabel();
combo.on({
select: function (me, records) {
var len = records.length,
store = combo.getStore(),
diff = records.length != store.count,
newAll = false,
all = false,
newRecords = [];
// toggle all selections
Ext.each(records, function (obj, i, recordsItself) {
if (records[i].data.abbreviation === 'ALL') {
allRecord = records[i];
if (!combo.allSelected) {
len = store.getCount();
combo.select(store.getRange());
combo.allSelected = true;
all = true;
newAll = true;
} else {
all = true;
}
} else {
if (diff && !newAll)
newRecords.push(records[i]);
}
});
if (combo.allSelected && !all) {
combo.clearValue();
combo.allSelected = false;
} else if (diff && !newAll) {
combo.select(newRecords);
combo.allSelected = false;
}
me.setFieldLabel(fl + ' (' + len + ' selected)');
},
beforedeselect: function (me, record, index) {
me.setFieldLabel(fl);
}
})
}
});
<强> JSFiddle 强>
答案 2 :(得分:2)
//它的组合商店,其中由服务器,它的全球商店加载的数据
Ext.Ajax.request({
url: '/myProject/api/teams',
success: function (response, opts) {
var responseObj = Ext.decode(response.responseText);
var dataTeam = new Array();
dataTeam[0] = new Array();
dataTeam[0]['name'] = 'All';
dataTeam[0]['value'] = -1;
var j=0;
for(var i=1; i<=responseObj.length; i++){
dataTeam[i] = new Array();
dataTeam[i]['name'] = responseObj[j].TEAMDESC;
dataTeam[i]['value'] = responseObj[j].TEAMID;
j++;
}
teamAllStore = Ext.create('Ext.data.Store', {
autoDestroy: false,
fields: ['name', 'value'],
data: dataTeam
});
}
});
//its my combo
{
xtype: 'combo',
fieldLabel: 'Teams',
name: 'myTeam',
itemid: 'myTeam',
store: teamAllStore,
width:255,
labelWidth : 70,
displayField: 'name',
valueField: 'value',
queryMode: 'local',
mode: 'local',
emptyText:'Select Team',
triggerAction: 'all',
forceSelection: true,
allowBlank: false,
editable: true,
margins: '5 0 0 5',
myValue:0, // initialized your variable..
multiSelect:true,
listConfig : {
getInnerTpl : function() {
return '<div class="chkCombo"> {name} </div>';
}
},
// this listeners for select all and de-select combo valuesall..
listeners: {
select: function (combo, eOpts) {
var store = combo.getStore();
if(combo.myValue==1){
combo.reset();
combo.myValue=0;
}
for (var i = 0; i < store.data.items.length; i++) {
if(combo.value[i]==-1) {
combo.myValue=1;
combo.select(combo.getStore().collect(combo.valueField));
}
}
}
}
}