Form with textfield and grid: send all values to the server

匆匆过客 提交于 2019-12-11 05:17:14

问题


In create and update forms, it is sometimes necessary to give the user the ability to dynamically add fields to values of the same type (more than one phone, more than one address, etc.).

I'm exploring several possibilities to do this.

One of them is to use a grid as a form field.

However, I have doubts about how best to implement this idea, especially on how to send all the form field values (textfield and grid) to the server (and then how to load them later in the form to edit).

Fiddles with some ideas:

One with cellediting plugin https://fiddle.sencha.com/#view/editor&fiddle/2ftp

Another one with roweditin gplugin a https://fiddle.sencha.com/#view/editor&fiddle/2fto


回答1:


Not sure about the "best to implement", but I have seen so many requirements for multivalue input, that for reusability I have in my toolbox a gridfield similar to the following one:

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

which can then be used like this:

},{
    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();
    }
}, {

I have made a fiddle for you based on your fiddle, including working load and save operations on the form, but in ExtJS 6.x. And I have checked that it works with ExtJS 5 as well, although you have to add working icons.



来源:https://stackoverflow.com/questions/49958374/form-with-textfield-and-grid-send-all-values-to-the-server

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!