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:
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;
+
+ },
});