partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit e980832819b30d9a8a553b6e6ac80fb29e3b866e
parent ea10f5bfc714c61a0c2f379e5ab926c59da0d94c
Author: Felicitus <felicitus@felicitus.org>
Date:   Sun, 15 Nov 2015 15:47:43 +0100

Implemented typeahead category selection, also implemented validation. Fixes #464

Diffstat:
Msrc/PartKeepr/FrontendBundle/Resources/public/js/Components/Widgets/CategoryComboBox.js | 155++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 154 insertions(+), 1 deletion(-)

diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Widgets/CategoryComboBox.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Widgets/CategoryComboBox.js @@ -2,6 +2,36 @@ Ext.define("PartKeepr.CategoryComboBox", { extend: "PartKeepr.Widgets.TreePicker", alias: 'widget.CategoryComboBox', + + editable: true, + + /** + * @cfg {Number} typeAheadDelay + * The length of time in milliseconds to wait until the typeahead function is called + */ + typeAheadDelay: 250, + + /** + * @var {Ext.util.DelayedTask} typeAheadTask + * The internal task for the typeAhead delay + */ + typeAheadTask: null, + + /** + * @var {PartKeepr.StorageLocationBundle.Entity.StorageLocation} selectedStorageLocation + * The selected storage location + */ + selectedCategory: null, + + enableKeyEvents: true, + + listeners: { + 'specialkey': { + fn: 'keyHandler', + scope: 'this' + } + }, + triggers: { reload: { cls: "x-form-reload-trigger", @@ -18,6 +48,11 @@ Ext.define("PartKeepr.CategoryComboBox", { initComponent: function () { + this.store = Ext.create("PartKeepr.data.store.PartCategoryStore"); + + this.on("keyup", Ext.bind(this.onFieldChange, this)); + this.on("blur", Ext.bind(this.onBlur, this)); + this.listenersStore = this.store.on({ scope: this, // Workaround to remember the value when loading @@ -35,5 +70,123 @@ Ext.define("PartKeepr.CategoryComboBox", { }); this.callParent(); - } + }, + onBlur: function () + { + this.applySelection(); + this.validate(); + }, + onFieldChange: function (field, e) + { + var newValue = this.inputEl.getValue(); + + if (!this.typeAheadTask) { + this.typeAheadTask = new Ext.util.DelayedTask(this.onTypeAhead, this, [newValue]); + } + + this.typeAheadTask.delay(this.typeAheadDelay, false, false, [newValue]); + }, + setValue: function (value) + { + this.textValue = value.get("name"); + this.callParent(arguments); + this.validate(); + + }, + onTypeAhead: function (newValue) + { + if (newValue !== this.textValue) { + var picker = this.getPicker(); + var store = picker.getStore(); + + var node = store.findNode("name", newValue, false, false); + this.expand(); + + if (node !== null) { + picker.getSelectionModel().select(node); + } else { + picker.getSelectionModel().deselectAll(); + } + + this.inputEl.focus(); + + this.textValue = newValue; + } + }, + /** + * Handles special keys used in this field. + * + * Enter: Starts the search + * Escape: Removes the search and clears the field contents + */ + keyHandler: function (field, e) + { + var picker = this.getPicker(); + switch (e.getKey()) { + case e.DOWN: + var currentSelection = picker.getSelectionModel().getSelection(); + + if (currentSelection.length === 0) { + picker.getSelectionModel().select(0); + } else { + var index = picker.getStore().indexOf(currentSelection[0]) + 1; + + if (index < picker.getStore().count()) { + picker.getSelectionModel().select(index); + } + } + break; + case e.UP: + var currentSelection = picker.getSelectionModel().getSelection(); + + if (currentSelection.length === 0) { + picker.getSelectionModel().select(0); + } else { + var index = picker.getStore().indexOf(currentSelection[0]) - 1; + + if (index >= 0) { + picker.getSelectionModel().select(index); + } + } + break; + case e.ENTER: + if (!this.isExpanded) { + this.expand(); + return; + } else { + this.applySelection(); + } + break; + case e.TAB: + this.applySelection(); + break; + } + + this.inputEl.focus(); + }, + applySelection: function () + { + var currentSelection = this.getPicker().getSelectionModel().getSelection(); + + if (currentSelection.length === 1) { + this.setValue(currentSelection[0]); + } + + this.collapse(); + }, + getErrors: function (value) { + var errors = this.callParent(arguments); + + if (!this.inputEl) { + return errors; + } + + if (!(this.getValue() instanceof PartKeepr.PartBundle.Entity.PartCategory) || + this.inputEl.getValue() !== this.getValue().get("name")) { + errors.push(i18n("A category must be selected")); + } + + return errors; + + }, });