问题
I have upgraded my project from Sencha touch to extjs universal app , Most of the things are workng but no the MultiSelect field. It was working fine in sencha touch but not working in extjs 6 modern toolkit
Ext.define('Ext.ux.field.Multiselect', {
extend: 'Ext.field.Select',
alias : 'widget.multiselectfield',
config: {
delimiter: ',',
mode: 'MULTI',
doneButton: true
},
/**
* Updates the {@link #doneButton} configuration. Will change it into a button when appropriate, or just update the text if needed.
* @param {Object} config
* @return {Object}
*/
applyDoneButton: function(config) {
if (config) {
if (Ext.isBoolean(config)) {
config = {};
}
if (typeof config == "string") {
config = {
text: config
};
}
Ext.applyIf(config, {
text: 'Done',
ui: 'action',
height: '20px',
margin: '5px auto 0px auto',
width: '50%',
docked: 'bottom',
listeners: {
tap: this.onButtonTap,
scope: this
}
});
}
return Ext.factory(config, 'Ext.Button', this.getDoneButton());
},
/**
* @private
*/
getTabletPicker: function() {
var me = this,
config = me.getDefaultTabletPickerConfig(),
listMode = me.getMode();
if (!me.listPanel) {
me.listPanel = Ext.create('Ext.Panel', Ext.apply({
left: 0,
top: 0,
modal: true,
cls: Ext.baseCSSPrefix + 'select-overlay',
layout: 'fit',
hideOnMaskTap: true,
width: Ext.os.is.Phone ? '14em' : '18em',
height: (Ext.os.is.BlackBerry && Ext.os.version.getMajor() === 10) ? '12em' : (Ext.os.is.Phone ? '12.5em' : '22em'),
items: [{
xtype: 'list',
mode: listMode,
store: me.getStore(),
itemTpl: '<span class="x-list-label">{' + me.getDisplayField() + ':htmlEncode}</span>'
}]
}, config));
if(listMode === 'SINGLE'){
me.listPanel.down('list').on('itemtap',me.onListTap,me);
}else{
me.listPanel.add(this.getDoneButton());
}
}
return me.listPanel;
},
/**
* @private
*/
onListTap : function(list,index,target,record) {
this.setValue(record);
this.callParent();
},
/**
* @private
*/
onButtonTap: function(){
var records = this.listPanel.down('list').getSelection();
this.setValue(records);
this.superclass.onListTap.call(this);
},
/**
* @private
*/
applyValue: function(value) {
this.getOptions();
return this.getValueFromRecords(value,this.getValueField());
},
/**
* @private
*/
updateValue: function(newValue, oldValue) {
var me = this,
value = me.convertValue(newValue,me.getValueField(),me.getDisplayField());
value = value.join(me.getDelimiter());
me.superclass.superclass.updateValue.call(me,[value]);
},
/**
* @private
*/
convertValue: function(value,fieldIn,fieldOut){
var delimiter = this.getDelimiter(),
store = this.getStore(),
i = 0,
out = [],
len,
item;
if (value) {
if (delimiter && Ext.isString(value)) {
value = value.split(delimiter);
} else if (!Ext.isArray(value)) {
value = [value];
}
for (len = value.length; i < len; ++i) {
item = store.findRecord(fieldIn,value[i]);
if(item)
out.push(item.get(fieldOut));
}
}
return out;
},
/**
* @private
* Returns the value in array form from records
*/
getValueFromRecords: function(value){
var delimiter = this.getDelimiter(),
valueField = this.getValueField(),
i = 0,
out = [],
len,
item;
if (value) {
if (delimiter && Ext.isString(value)) {
value = value.split(delimiter);
} else if (!Ext.isArray(value)) {
value = [value];
}
for (len = value.length; i < len; ++i) {
item = value[i];
if (item && item.isModel) {
out.push(item.get(valueField));
}
}
out = Ext.Array.unique(out);
}
return out.length > 0 ? out : value;
},
/**
* @private
*/
getRecordsFromValue: function(value){
var records = [],
all = this.getStore().getRange(),
valueField = this.getValueField(),
i = 0,
allLen = all.length,
rec,
j,
valueLen;
if(value){
for (valueLen = value.length; i < valueLen; ++i) {
for (j = 0; j < allLen; ++j) {
rec = all[j];
if (rec.get(valueField) == value[i]) {
records.push(rec);
break;
}
}
}
}
return records;
},
/**
* Returns the current selected {@link Ext.data.Model records} instances selected in this field.
* @return {Ext.data.Model[]} An array of Records.
*/
getSelection: function() {
return this.listPanel.down('list').getSelection();
},
/**
* Returns the current selected records as an array of their valueFields.
* @return {Array} An array of valueFields
*/
getValue: function() {
return this._value;
},
/**
* @private
*/
onChange: function(component, newValue, oldValue) {
var me = this,
old = me.convertValue(oldValue,me.getDisplayField(),me.getValueField());
me.fireEvent('change', me, me.getValue(), old);
},
/**
* Shows the picker for the select field, whether that is a {@link Ext.picker.Picker} or a simple
* {@link Ext.List list}.
*/
showPicker: function() {
var me = this,
store = this.getStore();
//check if the store is empty, if it is, return
if (!store || store.getCount() === 0) {
return;
}
if (me.getReadOnly()) {
return;
}
me.isFocused = true;
var listPanel = me.getTabletPicker(),
list = listPanel.down('list'),
index, records,
value = me.getValue();
if (!listPanel.getParent()) {
Ext.Viewport.add(listPanel);
}
if(value){
records = me.getRecordsFromValue(value);
list.select(records, null, true);
}else{
list.deselectAll();
}
listPanel.showBy(me.getComponent(), (Ext.os.is.BlackBerry && Ext.os.version.getMajor() === 10) ? 't-b' : null);
},
/**
* Called when the internal {@link #store}'s data has changed.
*/
onStoreDataChanged: function(store) {
var me = this,
initialConfig = me.getInitialConfig(),
value = me.getValue();
if (value || value === 0) {
me.updateValue(me.applyValue(value));
}
if (me.getValue() === null) {
if (initialConfig.hasOwnProperty('value')) {
me.setValue(initialConfig.value);
}
if (me.getValue() === null && me.getAutoSelect()) {
if (store.getCount() > 0) {
//me.setValue(store.getAt(0));
}
}
}
}
});
when i click on done it doesn't hide the list and doesn't add the multiple values to the inut field
the error in console
回答1:
Here is the code for mutliselect in Extjs 6 modern toolkit
create a file inside ext\modern\modern\src\ux\field
, named MutliSelect.js
and copy the following code to it
Ext.define('Ext.ux.field.Multiselect', {
extend: 'Ext.field.Select',
alias : 'widget.multiselectfield',
require:['Ext.field.Select'],
config: {
delimiter: ',',
mode: 'MULTI',
doneButton: true
},
/**
* Updates the {@link #doneButton} configuration. Will change it into a button when appropriate, or just update the text if needed.
* @param {Object} config
* @return {Object}
*/
applyDoneButton: function(config) {
if (config) {
if (Ext.isBoolean(config)) {
config = {};
}
if (typeof config == "string") {
config = {
text: config
};
}
Ext.applyIf(config, {
text: 'Done',
ui: 'action',
height: '20px',
margin: '5px auto 0px auto',
width: '50%',
docked: 'bottom',
listeners: {
tap: this.onButtonTap,
scope: this
}
});
}
return Ext.factory(config, 'Ext.Button', this.getDoneButton());
},
/**
* @private
*/
getTabletPicker: function() {
var me = this,
config = me.getDefaultTabletPickerConfig(),
listMode = me.getMode();
if (!me.listPanel) {
me.listPanel = Ext.create('Ext.Panel', Ext.apply({
left: 0,
top: 0,
modal: true,
cls: Ext.baseCSSPrefix + 'select-overlay',
layout: 'fit',
hideOnMaskTap: true,
width: Ext.os.is.Phone ? '14em' : '18em',
height: (Ext.os.is.BlackBerry && Ext.os.version.getMajor() === 10) ? '12em' : (Ext.os.is.Phone ? '12.5em' : '22em'),
items: [{
xtype: 'list',
mode: listMode,
store: me.getStore(),
itemTpl: '<span class="x-list-label">{' + me.getDisplayField() + ':htmlEncode}</span>'
}]
}, config));
if(listMode === 'SINGLE'){
me.listPanel.down('list').on('itemtap',me.onListTap,me);
}else{
me.listPanel.add(this.getDoneButton());
}
}
return me.listPanel;
},
/**
* @private
*/
onListTap : function(list,index,target,record) {
this.setValue(record);
this.callParent();
},
/**
* @private
*/
onButtonTap: function(){
var records = this.listPanel.down('list');
this.setValue(records.selected.keys);
this.updateValue(records.selected.keys, this.getValue());
this.listPanel.hide();
},
/**
* @private
*/
applyValue: function(value) {
this.getOptions();
return this.getValueFromRecords(value,this.getValueField());
},
/**
* @private
*/
updateValue: function(newValue, oldValue) {
var me = this,
value = me.convertValue(newValue,me.getValueField(),me.getDisplayField());
value = value.join(me.getDelimiter());
me.superclass.superclass.updateValue.call(me,[value]);
},
/**
* @private
*/
convertValue: function(value,fieldIn,fieldOut){
var delimiter = this.getDelimiter(),
store = this.getStore(),
i = 0,
out = [],
len,
item;
if (value) {
if (delimiter && Ext.isString(value)) {
value = value.split(delimiter);
} else if (!Ext.isArray(value)) {
value = [value];
}
for (len = value.length; i < len; ++i) {
item = store.findRecord(fieldIn,value[i]);
if(item)
out.push(item.get(fieldOut));
}
}
return out;
},
/**
* @private
* Returns the value in array form from records
*/
getValueFromRecords: function(value){
var delimiter = this.getDelimiter(),
valueField = this.getValueField(),
i = 0,
out = [],
len,
item;
if (value) {
if (delimiter && Ext.isString(value)) {
value = value.split(delimiter);
} else if (!Ext.isArray(value)) {
value = [value];
}
for (len = value.length; i < len; ++i) {
item = value[i];
if (item && item.isModel) {
out.push(item.get(valueField));
}
}
out = Ext.Array.unique(out);
}
return out.length > 0 ? out : value;
},
/**
* @private
*/
getRecordsFromValue: function(value){
var records = [],
all = this.getStore().getRange(),
valueField = this.getValueField(),
i = 0,
allLen = all.length,
rec,
j,
valueLen;
if(value){
for (valueLen = value.length; i < valueLen; ++i) {
for (j = 0; j < allLen; ++j) {
rec = all[j];
if (rec.get(valueField) == value[i]) {
records.push(rec);
break;
}
}
}
}
return records;
},
/**
* Returns the current selected {@link Ext.data.Model records} instances selected in this field.
* @return {Ext.data.Model[]} An array of Records.
*/
getSelection: function() {
return this.listPanel.down('list').getSelection();
},
/**
* Returns the current selected records as an array of their valueFields.
* @return {Array} An array of valueFields
*/
getValue: function() {
return this._value;
},
/**
* @private
*/
onChange: function(component, newValue, oldValue) {
var me = this,
old = me.convertValue(oldValue,me.getDisplayField(),me.getValueField());
me.fireEvent('change', me, me.getValue(), old);
},
/**
* Shows the picker for the select field, whether that is a {@link Ext.picker.Picker} or a simple
* {@link Ext.List list}.
*/
showPicker: function() {
var me = this,
store = this.getStore();
//check if the store is empty, if it is, return
if (!store || store.getCount() === 0) {
return;
}
if (me.getReadOnly()) {
return;
}
me.isFocused = true;
var listPanel = me.getTabletPicker(),
list = listPanel.down('list'),
index, records,
value = me.getValue();
if (!listPanel.getParent()) {
Ext.Viewport.add(listPanel);
}
if(value){
records = me.getRecordsFromValue(value);
list.select(records, null, true);
}else{
list.deselectAll();
}
listPanel.showBy(me.getComponent(), (Ext.os.is.BlackBerry && Ext.os.version.getMajor() === 10) ? 't-b' : null);
},
/**
* Called when the internal {@link #store}'s data has changed.
*/
onStoreDataChanged: function(store) {
var me = this,
initialConfig = me.getInitialConfig(),
value = me.getValue();
if (value || value === 0) {
me.updateValue(me.applyValue(value));
}
if (me.getValue() === null) {
if (initialConfig.hasOwnProperty('value')) {
me.setValue(initialConfig.value);
}
if (me.getValue() === null && me.getAutoSelect()) {
if (store.getCount() > 0) {
//me.setValue(store.getAt(0));
}
}
}
}
});
and than use the xtype
as multiselectfield
,
来源:https://stackoverflow.com/questions/44112929/extjs-6-modern-toolkit-multiselect-field