Extjs 带有textfield和grid的表单:将所有值发送到服务器
在创建和更新表单时,有时需要为用户提供向相同类型的值(多个电话、多个地址等)动态添加字段的能力 我正在探索几种可能的方法 其中之一是使用网格作为表单字段 但是,我对如何最好地实现这一想法表示怀疑,尤其是对如何将所有表单字段值(textfield和grid)发送到服务器(以及如何在表单中加载它们以进行编辑)表示怀疑 摆弄一些想法: 一个带有cellediting插件 另一个是roweditin gplugin a不确定“最佳实现”,但我看到了对多值输入的许多要求,因此为了可重用性,我的工具箱中有一个类似于以下的gridfield:Extjs 带有textfield和grid的表单:将所有值发送到服务器,extjs,extjs5,Extjs,Extjs5,在创建和更新表单时,有时需要为用户提供向相同类型的值(多个电话、多个地址等)动态添加字段的能力 我正在探索几种可能的方法 其中之一是使用网格作为表单字段 但是,我对如何最好地实现这一想法表示怀疑,尤其是对如何将所有表单字段值(textfield和grid)发送到服务器(以及如何在表单中加载它们以进行编辑)表示怀疑 摆弄一些想法: 一个带有cellediting插件 另一个是roweditin gplugin a不确定“最佳实现”,但我看到了对多值输入的许多要求,因此为了可重用性,我的工具箱中有一
Ext.define('Ext.ux.GridField', {
extend: 'Ext.form.FieldContainer',
alias: 'widget.gridfield',
initComponent: function () {
var me = this;
if(!me.columns) me.columns = {
dataIndex: 'field1'
};
if(!me.mapFn) me.mapFn = function(value) {
if(Ext.isObject(value)) return value;
return {
field1: value
};
};
if(!me.unmapFn) me.unmapFn = function(record) {
return record.get('field1');
};
me.grid = Ext.widget(Ext.apply({
xtype: 'grid',
viewConfig: {
markDirty: false
},
store: me.store || Ext.create('Ext.data.Store', {
fields: me.columns.map(function(column) {
return {
name: column.dataIndex,
type: column.dataType || 'auto',
defaultValue: column.defaultValue
};
}),
listeners: {
update: me.updateValue,
datachanged: me.updateValue,
scope: me
}
}),
columns: [{
xtype: 'actioncolumn',
getClass: function () {
return 'x-fa fa-times'
},
handler: function(grid, rowIndex, colIndex, item, e, record) {
grid.getStore().remove(record);
},
width: 35
}].concat(me.columns),
bbar: [{
xtype: 'button',
iconCls: 'x-fa fa-pencil',
text: 'Add',
handler: function(btn) {
var grid = btn.up('grid'),
store = grid.getStore(),
record = store.add(Ext.clone(me.emptyRecord) || {})[0];
grid.getPlugin('editor').startEditByPosition({
row: store.indexOf(record),
column: 1
});
}
}],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
pluginId: 'editor',
clicksToEdit: 1
})
]
}, me.gridConfig)); // "gridConfig" config can override everything on each instance.
me.hiddenField = Ext.widget({
xtype: 'hiddenfield',
name: me.name,
value: '',
allowNull: false,
rawToValue: function (raw) {
return raw;
},
valueToRaw: function (value) {
return value;
},
getRawValue: function () {
return Ext.valueFrom(this.rawValue, '')
},
isEqual: function (a, b) {
return Ext.encode(a) == Ext.encode(b)
},
listeners: {
change: function(field, nV, oV) {
if(!Ext.isArray(nV)) nV = [nV];
var store = me.grid.getStore();
store.removeAll();
store.add(nV.map(me.mapFn));
}
}
});
Ext.apply(me, {
layout: 'fit',
items: [{
xtype:'container',
border: 1,
style: {
borderColor: '#d0d0d0',
borderStyle: 'solid'
},
items: [me.grid]
}, me.hiddenField]
});
me.callParent(arguments);
},
updateValue: function() {
var me = this,
grid = me.grid,
hiddenField = me.hiddenField,
nV = grid.getStore().getRange().map(me.unmapFn, me),
oV = me.hiddenField.getValue();
if(!oV || Ext.isArray(oV) && Ext.encode(nV) != Ext.encode(oV)) {
hiddenField.suspendCheckChange++;
hiddenField.setValue(nV);
hiddenField.suspendCheckChange--;
me.fireEvent('change', me, nV, oV);
}
}
});
然后可以这样使用:
},{
xtype: 'gridfield',
fieldLabel: 'Contacts',
name: 'contacts',
columns: [{
text: 'Type',
dataIndex: 'type',
editor:{
xtype: 'combobox',
name: 'type',
valueField: 'name',
displayField: 'name',
store: combostore,
queryMode: 'local'
},
flex: 0.7
},{
text: 'Description',
dataIndex: 'description',
editor:{
xtype: 'textfield',
name: 'description'
},
flex: 1
}],
mapFn: function(value) {
return value;
},
unmapFn: function(record) {
return record.getData();
}
}, {
我已经根据您的小提琴为您做了一个测试,包括表单上的工作加载和保存操作,但是是在ExtJS 6.x中。我有,尽管你必须添加工作图标。为什么不在每个电话字段旁边放一个“添加”按钮,然后在按键时插入另一个电话字段?表单发送内部的所有字段。此外,在表单加载中插入多个电话字段进行编辑也很简单。@abeyaz有时需要多组字段,在这种情况下,最好选择网格组件的巨大潜力。谢谢你的亚历山大。(一如既往)帮了大忙。你的例子非常完整,对我帮助很大。我喜欢这个解决方案。我会逐行研究它(并尝试正确理解一切)。Alexandre,该组件工作正常,但我在更新中有一个问题。我尝试使用一个查询(使用PHP和MYSQL)将记录更新所需的所有数据带到存储中的每一行,但没有得到与gridfield(多值)所需数据相关的数据。你是怎么做到的?数据在存储区中已经全部可用,或者当您选择要编辑的记录时,通过发送该特定记录的id向gridfield发送新请求,以过滤必要的数据?