From: Moritz Warning Date: Fri, 22 May 2020 23:43:18 +0000 (+0200) Subject: add autocompletion to package list X-Git-Tag: v2.2.1~17 X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=c6a3ff19a340de39b4e1a91a00bcc6873b945112;p=web%2Ffirmware-selector-openwrt-org.git add autocompletion to package list the package list will autocomplete packages and only allow known packages --- diff --git a/index.css b/index.css index 7569ada..a720337 100644 --- a/index.css +++ b/index.css @@ -4,10 +4,13 @@ body { margin: 0px; } -/*the container must be positioned relative:*/ +#models-autocomplete { + width: 20em; + display: inline-block; +} + .autocomplete { position: relative; - display: inline-block; } .autocomplete > input { @@ -18,10 +21,6 @@ body { border-radius: 4px; } -.autocomplete { - width: 20em; -} - .autocomplete-items { position: absolute; border: 1px solid #d4d4d4; diff --git a/index.html b/index.html index 6feaa67..8ad054d 100644 --- a/index.html +++ b/index.html @@ -40,7 +40,7 @@
-
+
@@ -55,7 +55,9 @@

Customize

- +
+ +
Request Build diff --git a/index.js b/index.js index 894f1a1..ce5f4b4 100644 --- a/index.js +++ b/index.js @@ -13,16 +13,16 @@ function hide(id) { $(id).style.display = 'none'; } +function split(str) { + return str.match(/[^\s,]+/g) || []; +} + function build_asa_request() { if (!current_model || !current_model.id) { alert('bad profile'); return; } - function split(str) { - return str.match(/[^\s,]+/g) || []; - } - function get_model_titles(titles) { return titles.map(e => { if (e.title) { @@ -132,9 +132,7 @@ function translate() { } } -function setupAutocompleteList(input, items, onselection) { - // the setupAutocompleteList function takes two arguments, - // the text field element and an array of possible autocompleted values: +function setupAutocompleteList(input, items, as_list, onbegin, onend) { var currentFocus = -1; // sort numbers and other characters separately @@ -142,12 +140,20 @@ function setupAutocompleteList(input, items, onselection) { items.sort(collator.compare); - // execute a function when someone writes in the text field: input.oninput = function(e) { - // clear images - updateImages(); + onbegin(); + var offset = 0; var value = this.value; + var value_list = []; + + if (as_list) { + // automcomplete last text item + offset = this.value.lastIndexOf(' ') + 1; + value = this.value.substr(offset); + value_list = split(this.value.substr(0, offset)); + } + // close any already open lists of autocompleted values closeAllLists(); @@ -162,7 +168,6 @@ function setupAutocompleteList(input, items, onselection) { // append the DIV element as a child of the autocomplete container: this.parentNode.appendChild(list); - // for each item in the array... var c = 0; for (var i = 0; i < items.length; i += 1) { var item = items[i]; @@ -173,6 +178,11 @@ function setupAutocompleteList(input, items, onselection) { continue; } + // do not offer a duplicate item + if (as_list && value_list.indexOf(item) != -1) { + continue; + } + c += 1; if (c >= 15) { var div = document.createElement('DIV'); @@ -188,13 +198,16 @@ function setupAutocompleteList(input, items, onselection) { + ''; div.addEventListener('click', function(e) { - // set text field to selected value - input.value = this.getElementsByTagName('input')[0].value; + // include selected value + var selected = this.getElementsByTagName('input')[0].value; + if (as_list) { + input.value = value_list.join(' ') + ' ' + selected; + } else { + input.value = selected; + } // close the list of autocompleted values, - // (or any other open lists of autocompleted values: closeAllLists(); - // callback - onselection(input.value); + onend(input); }); list.appendChild(div); @@ -226,7 +239,12 @@ function setupAutocompleteList(input, items, onselection) { }; input.onfocus = function() { - onselection(input.value); + onend(input); + } + + // focus lost + input.onblur = function() { + onend(input); } function setActive(x) { @@ -259,6 +277,21 @@ function setupAutocompleteList(input, items, onselection) { }); } +// for attended sysupgrade +function updatePackageList(target) { + // set available packages + fetch(config.asu_url + '/' + target + '/packages.json') + .then(response => response.json()) + .then(all_packages => { + setupAutocompleteList($('packages'), all_packages, true, _ => {}, textarea => { + textarea.value = split(textarea.value) + .filter((value, index, self) => self.indexOf(value) === index) // make list unique + //.filter((value, index) => all_packages.indexOf(value) !== -1) // limit to available packages + .join(' '); + }); + }); +} + function updateImages(version, code, date, model, url, mobj, is_custom) { // add download button for image function addLink(type, file) { @@ -341,6 +374,10 @@ function updateImages(version, code, date, model, url, mobj, is_custom) { addLink(images[i].type, images[i].name); } + if (config.asu_url) { + updatePackageList(target); + } + show('images'); } else { hide('images'); @@ -351,7 +388,8 @@ function init() { setupSelectList($('versions'), Object.keys(config.versions), version => { fetch(config.versions[version]).then(data => { data.json().then(obj => { - setupAutocompleteList($('models'), Object.keys(obj['models']), model => { + setupAutocompleteList($('models'), Object.keys(obj['models']), false, updateImages, models => { + var model = models.value; if (model in obj['models']) { var url = obj.url || 'unknown'; var code = obj.version_code || 'unknown';