diff --git a/Gruntfile.js b/Gruntfile.js index a5a43d053..83637cbed 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -162,6 +162,7 @@ module.exports = function(grunt) { "packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js", "packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js", "packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/autoComplete.js", "packages/node_modules/@node-red/editor-client/src/js/ui/actions.js", "packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js", "packages/node_modules/@node-red/editor-client/src/js/ui/diff.js", diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/autoComplete.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/autoComplete.js new file mode 100644 index 000000000..d66cd26a0 --- /dev/null +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/autoComplete.js @@ -0,0 +1,108 @@ +(function($) { + +/** + * options: + * + * methods: + * + */ + + $.widget( "nodered.autoComplete", { + _create: function() { + var that = this; + this.completionMenuShown = false; + this.options.search = this.options.search || function() { return [] } + this.element.addClass("red-ui-autoComplete") + this.element.on("keydown.red-ui-autoComplete", function(evt) { + if ((evt.keyCode === 13 || evt.keyCode === 9) && that.completionMenuShown) { + var opts = that.menu.options(); + that.element.val(opts[0].value); + that.menu.hide(); + evt.preventDefault(); + } + }) + this.element.on("keyup.red-ui-autoComplete", function(evt) { + if (evt.keyCode === 13 || evt.keyCode === 9 || evt.keyCode === 27) { + // ENTER / TAB / ESCAPE + return + } + if (evt.keyCode === 8 || evt.keyCode === 46) { + // Delete/Backspace + if (!that.completionMenuShown) { + return; + } + } + that._updateCompletions(this.value); + }); + }, + _showCompletionMenu: function(completions) { + if (this.completionMenuShown) { + return; + } + this.menu = RED.popover.menu({ + tabSelect: true, + width: 300, + maxHeight: 200, + class: "red-ui-autoComplete-container", + options: completions, + onselect: (opt) => { this.element.val(opt.value); this.element.focus() }, + onclose: () => { this.completionMenuShown = false; delete this.menu; this.element.focus()} + }); + this.menu.show({ + target: this.element + }) + this.completionMenuShown = true; + }, + _updateCompletions: function(val) { + var that = this; + if (val.trim() === "") { + if (this.completionMenuShown) { + this.menu.hide(); + } + return; + } + function displayResults(completions,requestId) { + if (requestId && requestId !== that.pendingRequest) { + // This request has been superseded + return + } + if (!completions || completions.length === 0) { + if (that.completionMenuShown) { + that.menu.hide(); + } + return + } + if (that.completionMenuShown) { + that.menu.options(completions); + } else { + that._showCompletionMenu(completions); + } + } + if (this.options.search.length === 2) { + var requestId = 1+Math.floor(Math.random()*10000); + this.pendingRequest = requestId; + this.options.search(val,function(completions) { displayResults(completions,requestId);}) + } else { + displayResults(this.options.search(val)) + } + }, + _destroy: function() { + this.element.removeClass("red-ui-autoComplete") + this.element.off("keydown.red-ui-autoComplete") + this.element.off("keyup.red-ui-autoComplete") + if (this.completionMenuShown) { + this.menu.hide(); + } + }, + // disable: function(val) { + // if(val === undefined || !!val ) { + // + // } else { + // this.uiSelect.attr("disabled", null); //remove attr + // } + // }, + // enable: function() { + // this.uiSelect.attr("disabled", null); //remove attr + // }, + }); +})(jQuery); diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js index c40570626..17969061c 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js @@ -340,20 +340,47 @@ RED.popover = (function() { } var menuOptions = options.options || []; var first; - menuOptions.forEach(function(opt) { - var item = $('