outlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplace
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
9.1 KiB
299 lines
9.1 KiB
/** |
|
* Internal utility class that provides default configuration for cell editing. |
|
* @private |
|
*/ |
|
Ext.define('Ext.grid.CellEditor', { |
|
extend: 'Ext.Editor', |
|
|
|
alignment: 'l-l?', |
|
|
|
hideEl : false, |
|
|
|
cls: Ext.baseCSSPrefix + 'small-editor ' + |
|
Ext.baseCSSPrefix + 'grid-editor ' + |
|
Ext.baseCSSPrefix + 'grid-cell-editor', |
|
|
|
treeNodeSelector: '.' + Ext.baseCSSPrefix + 'tree-node-text', |
|
|
|
shim: false, |
|
|
|
shadow: false, |
|
|
|
constructor: function(config) { |
|
var field; |
|
|
|
// Editor must appear at the top so that it does not contribute to scrollbars. |
|
this.y = 0; |
|
|
|
config = Ext.apply({}, config); |
|
field = config.field; |
|
|
|
if (field) { |
|
field.monitorTab = false; |
|
} |
|
|
|
this.callParent([config]); |
|
}, |
|
|
|
// Set the grid that owns this editor. |
|
// Usually this will only *change* once, and the renderTo will cause |
|
// rendering into the owning grid. |
|
// However in a Lockable assembly the editor has to swap sides if the column is moved across. |
|
// Called by CellEditing#getEditor |
|
setGrid: function(grid) { |
|
var me = this, |
|
oldGrid = me.grid, |
|
view, |
|
viewListeners; |
|
|
|
if (grid !== oldGrid) { |
|
viewListeners = { |
|
beforerefresh: me.beforeViewRefresh, |
|
refresh: me.onViewRefresh, |
|
scope: me |
|
}; |
|
// Remove previous refresh listener |
|
if (oldGrid) { |
|
oldGrid.getView().un(viewListeners); |
|
} |
|
|
|
// Set the renderTo target to reflect new grid view ownership |
|
view = grid.getView(); |
|
me.renderTo = view.getTargetEl().dom; |
|
me.grid = grid; |
|
|
|
// On view refresh, we need to copy our DOM into the detached body to prevent it from being garbage collected. |
|
view.on(viewListeners); |
|
} |
|
}, |
|
|
|
afterFirstLayout: function(width, height) { |
|
// After we've been laid out, we can get rid of the y property, we don't want |
|
// to be positioned now |
|
delete this.y; |
|
this.callParent([width, height]); |
|
}, |
|
|
|
beforeViewRefresh: function() { |
|
var me = this, |
|
dom = me.el && me.el.dom; |
|
|
|
if (dom) { |
|
if (me.editing && !(me.field.column && me.field.column.sorting)) { |
|
|
|
// Clear the Panel's cellFocused flag prior to removing it from the DOM |
|
// This will prevent the Panels onFocusLeave from processing the resulting blurring. |
|
me.grid.view.cellFocused = false; |
|
|
|
// Set the Editor.allowBlur setting so that it does not process the upcoming field blur event and terminate the edit |
|
me.wasAllowBlur = me.allowBlur; |
|
me.allowBlur = false; |
|
} |
|
|
|
// Remove the editor from the view to protect it from anihilation: https://sencha.jira.com/browse/EXTJSIV-11713 |
|
if (dom.parentNode) { |
|
dom.parentNode.removeChild(dom); |
|
} |
|
} |
|
}, |
|
|
|
onViewRefresh: function() { |
|
var me = this, |
|
dom = me.el && me.el.dom, |
|
sorting; |
|
|
|
if (dom) { |
|
sorting = me.field.column && me.field.column.sorting; |
|
|
|
// If the view was refreshed while we were editing, replace it. |
|
if (me.editing && !sorting) { |
|
me.allowBlur = me.wasAllowBlur; |
|
me.renderTo.appendChild(dom); |
|
|
|
// The removal will have blurred, so avoid the processing in onFocusEnter by restoring the previous |
|
// cellFocused setting |
|
me.grid.view.cellFocused = true; |
|
|
|
me.field.focus(); |
|
} else if (!sorting) { |
|
Ext.getDetachedBody().dom.appendChild(dom); |
|
} |
|
|
|
// If the column was sorted while editing, we must detect that and complete the edit |
|
// because the view will be refreshed and the editor will be removed from the dom. |
|
if (me.editing && sorting) { |
|
me.completeEdit(); |
|
} |
|
} |
|
}, |
|
|
|
startEdit: function(boundEl, value) { |
|
this.context = this.editingPlugin.context; |
|
this.callParent([boundEl, value]); |
|
}, |
|
|
|
/** |
|
* @private |
|
* Shows the editor, end ensures that it is rendered into the correct view |
|
* Hides the grid cell inner element when a cell editor is shown. |
|
*/ |
|
onShow: function() { |
|
var me = this, |
|
innerCell = me.boundEl.first(); |
|
|
|
// If we have had our owning grid changed (by a column switching sides in a Lockable assembly) |
|
// or, if a view refresh has removed us from the DOM |
|
// append this component into its renderTo target. |
|
if (me.el.dom.parentNode !== me.renderTo) { |
|
me.renderTo.appendChild(me.el.dom); |
|
} |
|
|
|
if (innerCell) { |
|
if (me.isForTree) { |
|
innerCell = innerCell.child(me.treeNodeSelector); |
|
} |
|
innerCell.hide(); |
|
} |
|
|
|
me.callParent(arguments); |
|
}, |
|
|
|
onEditComplete: function(remainVisible) { |
|
// When being asked to process edit completion, if we are not hiding, restore the cell now |
|
if (remainVisible) { |
|
this.restoreCell(); |
|
} |
|
this.callParent(arguments); |
|
}, |
|
|
|
/** |
|
* @private |
|
* Shows the grid cell inner element when a cell editor is hidden |
|
*/ |
|
onHide: function() { |
|
this.restoreCell(); |
|
this.callParent(arguments); |
|
}, |
|
|
|
restoreCell: function() { |
|
var me = this, |
|
innerCell = me.boundEl.first(); |
|
|
|
if (innerCell) { |
|
if (me.isForTree) { |
|
innerCell = innerCell.child(me.treeNodeSelector); |
|
} |
|
innerCell.show(); |
|
} |
|
}, |
|
|
|
/** |
|
* @private |
|
* Fix checkbox blur when it is clicked. |
|
*/ |
|
afterRender: function() { |
|
var me = this, |
|
field = me.field; |
|
|
|
me.callParent(arguments); |
|
|
|
if (field.isCheckbox) { |
|
field.mon(field.inputEl, { |
|
mousedown: me.onCheckBoxMouseDown, |
|
click: me.onCheckBoxClick, |
|
scope: me |
|
}); |
|
} |
|
}, |
|
|
|
/** |
|
* @private |
|
* Because when checkbox is clicked it loses focus completeEdit is bypassed. |
|
*/ |
|
onCheckBoxMouseDown: function() { |
|
this.completeEdit = Ext.emptyFn; |
|
}, |
|
|
|
/** |
|
* @private |
|
* Restore checkbox focus and completeEdit method. |
|
*/ |
|
onCheckBoxClick: function() { |
|
delete this.completeEdit; |
|
this.field.focus(false, 10); |
|
}, |
|
|
|
/** |
|
* @private |
|
* Realigns the Editor to the grid cell, or to the text node in the grid inner cell |
|
* if the inner cell contains multiple child nodes. |
|
*/ |
|
realign: function(autoSize) { |
|
var me = this, |
|
boundEl = me.boundEl, |
|
innerCell = boundEl.first(), |
|
innerCellTextNode = innerCell.dom.firstChild, |
|
width = boundEl.getWidth(), |
|
offsets = Ext.Array.clone(me.offsets), |
|
grid = me.grid, |
|
xOffset, |
|
v = '', |
|
|
|
// innerCell is empty if there are no children, or there is one text node, and it contains whitespace |
|
isEmpty = !innerCellTextNode || (innerCellTextNode.nodeType === 3 && !(Ext.String.trim(v = innerCellTextNode.data).length)); |
|
|
|
if (me.isForTree) { |
|
// When editing a tree, adjust the width and offsets of the editor to line |
|
// up with the tree cell's text element |
|
xOffset = me.getTreeNodeOffset(innerCell); |
|
width -= Math.abs(xOffset); |
|
offsets[0] += xOffset; |
|
} |
|
|
|
if (grid.columnLines) { |
|
// Subtract the column border width so that the editor displays inside the |
|
// borders. The column border could be either on the left or the right depending |
|
// on whether the grid is RTL - using the sum of both borders works in both modes. |
|
width -= boundEl.getBorderWidth('rl'); |
|
} |
|
|
|
if (autoSize === true) { |
|
me.field.setWidth(width); |
|
} |
|
|
|
// https://sencha.jira.com/browse/EXTJSIV-10871 Ensure the data bearing element has a height from text. |
|
if (isEmpty) { |
|
innerCell.dom.innerHTML = 'X'; |
|
} |
|
|
|
me.alignTo(innerCell, me.alignment, offsets); |
|
|
|
if (isEmpty) { |
|
innerCell.dom.firstChild.data = v; |
|
} |
|
}, |
|
|
|
// private |
|
getTreeNodeOffset: function(innerCell) { |
|
return innerCell.child(this.treeNodeSelector).getOffsetsTo(innerCell)[0]; |
|
}, |
|
|
|
onEditorTab: function(e){ |
|
var field = this.field; |
|
if (field.onEditorTab) { |
|
field.onEditorTab(e); |
|
} |
|
}, |
|
|
|
onFocusLeave : function(e) { |
|
// We are going to hide because of this focus exit. |
|
// Ensure that hide processing does not throw focus back to the previously focused element. |
|
this.previousFocus = null; |
|
|
|
this.callParent([e]); |
|
|
|
// Reset the flag that may have been set by CellEditing#startEdit to prevent |
|
// Ext.Editor#onFieldBlur from canceling editing. |
|
this.selectSameEditor = false; |
|
} |
|
});
|
|
|