ExtJs has row and cell editing plugins. Unfortunately they do not allow the cells in bulk/batch mode. I have tried to implement bulk edit using custom selection replicator. and popup form for single and multiple columns edit.
Custom selection replicator will replicate all the cells regardless if cell is editable or not. So I had to extend and create new plugin to implement this feature.
Ext.define('app.view.selection.Replicator', { extend: 'Ext.grid.selection.Replicator', alias: 'plugin.customselectionreplicator', replicateSelection: function (ownerGrid, sel, extension) { // This can only handle extending rows if (extension.columns || sel.isColumns) { return; } // eslint-disable-next-line vars-on-top var me = this, columns = me.columns, selFirstRowIdx = sel.getFirstRowIndex(), selLastRowIdx = sel.getLastRowIndex(), selectedRowCount = selLastRowIdx - selFirstRowIdx + 1, lastTwoRecords = [], colCount, i, j, column, values, startIdx, endIdx, increment, store, record, prevValues, prevValue, x, y; colCount = columns.length; store = columns[0].getView().dataSource; // Single row, just duplicate values into extension if (selectedRowCount === 1) { values = me.getColumnValues(sel.view.dataSource.getAt(selFirstRowIdx)); } // Multiple rows, take the numeric values from the closest two rows, // calculate an array of differences and propagate it else { values = new Array(colCount); if (extension.rows < 0) { lastTwoRecords = [ store.getAt(selFirstRowIdx + 1), store.getAt(selFirstRowIdx) ]; } else { lastTwoRecords = [ store.getAt(selLastRowIdx - 1), store.getAt(selLastRowIdx) ]; } lastTwoRecords[0] = me.getColumnValues(lastTwoRecords[0]); lastTwoRecords[1] = me.getColumnValues(lastTwoRecords[1]); // The values array will be the differences between all numeric columns // in the selection of the closet two records. for (j = 0; j < colCount; j++) { x = lastTwoRecords[1][j]; y = lastTwoRecords[0][j]; if (!isNaN(x) && !isNaN(y)) { values[j] = Number(x) - Number(y); } } } // Loop from end to start of extension area if (extension.rows < 0) { startIdx = extension.end.rowIdx; endIdx = extension.start.rowIdx - 1; increment = -1; } else { startIdx = extension.start.rowIdx; endIdx = extension.end.rowIdx + 1; increment = 1; } // Replicate single selected row if (selectedRowCount === 1) { for (i = startIdx; i !== endIdx; i += increment) { record = store.getAt(i); for (j = 0; j < colCount; j++) { column = columns[j]; if (column.dataIndex && column.editor) { record.set(column.dataIndex, values[j]); } } } } // Add differences from closest two rows else { for (i = startIdx; i !== endIdx; i += increment) { record = store.getAt(i); prevValues = me.getColumnValues(store.getAt(i - increment)); for (j = 0; j < colCount; j++) { column = columns[j]; if (column.dataIndex) { prevValue = prevValues[j]; if (!isNaN(prevValue)) { record.set( column.dataIndex, Ext.coerce(Number(prevValue) + values[j], prevValue) ); } } } } } }, });
As you can see I just check if column has editor and allow the record edit.
The second method is to use popup forms to edit single or all the edited columns.