/** * A specialized NavigationModel to navigate between chips in a * {@link Ext.dataview.ChipView ChipView}. * * This handles selection and deletion of chips. * * @private * @since 6.7.0 */Ext.define('Ext.field.ChipViewNavigationModel', { extend: 'Ext.dataview.BoundListNavigationModel', alias: 'navmodel.fieldchipview', privates: { getKeyNavCfg: function(view) { var me = this, eventEl; if (this.keyboard !== false) { // Drive the KeyNav off the View's ownerField's focusEl if possible. // If there's no ownerField, try the view's focusEl. If that is not focusable // then we are not keyboard navigable. eventEl = (view.ownerField || view).getFocusEl(); // If we are not linked if (eventEl) { return { target: eventEl, eventName: 'keydown', processEvent: view.ownerField ? me.processViewEvent : undefined, processEventScope: me, defaultEventAction: 'stopEvent', delete: me.onKeyDelete, backspace: me.onKeyDelete, right: me.onKeyRight, left: me.onKeyLeft, A: { ctrl: true, // Need a separate function because we don't want the key // events passed on to selectAll (causes event suppression). handler: me.onSelectAllKeyPress }, // This object has to get its key processing in first. // Specifically, before any Editor's key handling. priority: 1002, scope: me }; } } }, processViewEvent: function(e) { var me = this, ownerField = me.getView().ownerField; if (ownerField) { // No Chip navigation if there is raw input, or there are no chips if (ownerField.inputElement.dom.value.length || !ownerField.getValueCollection().getCount()) { me.clearLocation(); return; } } return e; }, onKeyLeft: function(e) { var me = this, view = me.getView(), location = me.location, options = { event: e }; // Do not scroll e.preventDefault(); if (location) { if (!location.isFirstDataItem()) { if (!e.shiftKey) { view.getSelectable().deselectAll(); } me.movePrevious(options); } } else { me.setLocation(view.getLastDataItem(), options); } return true; }, onKeyRight: function(e) { var me = this, view = me.getView(), location = me.location; // Do not scroll e.preventDefault(); if (location) { if (location.isLastDataItem()) { view.getSelectable().deselectAll(); me.clearLocation(); } else { if (!e.shiftKey) { view.getSelectable().deselectAll(); } me.moveNext({ event: e }); } } return true; }, onKeyDelete: function(e) { var view = this.getView(), ownerField = view.ownerField, selModel, selected, location, isLast; if (ownerField) { selModel = view.getSelectable(); selected = selModel.getSelectedRecords(); if (selected.length) { selModel.deselect(selected); ownerField.getValueCollection().remove(selected); location = this.getLocation(); if (location) { isLast = location.isLast(); if (isLast && e.keyCode === e.DELETE) { this.clearLocation(); } else if (view.dataItems.length) { selModel.select(location.refresh().record); } } } else if (e.keyCode === e.BACKSPACE) { this.onKeyLeft(e); } } }, onNavigate: function(event) { var view = this.getView(), ownerField = view.ownerField, location = this.getLocation; if (ownerField) { // If the location we have navigated to is not selected then // go directly to NavigationModel base class to process the navigation. // We definitely want to navigate the view (which is to say select) // upon any form of navigation. if (!location || !view.getSelectable().isSelected(location.record)) { Ext.dataview.NavigationModel.prototype.onNavigate.call(this, event); } } else { // Process the same as BoundList this.callParent([event]); } } }});