diff options
author | Jo-Philipp Wich <jo@mein.io> | 2019-12-30 14:04:18 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2019-12-30 14:51:40 +0100 |
commit | b0836b037e55bfc9201e60a9446f2f7800d7f195 (patch) | |
tree | 47871f8002e8d7b34b12e66b53ef48d520e4673b /modules | |
parent | 0d0a3f4d0df44387fe9bec0c5597f6c491f44eec (diff) |
luci-base: ui.js: implement UIDropdown.{add,clear}Choices()
The new `addChoices()` and `clearChoices()` functions allow clearing and
adding new options to existing dropdown instances respectively.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/luci-base/htdocs/luci-static/resources/ui.js | 90 |
1 files changed, 77 insertions, 13 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/ui.js b/modules/luci-base/htdocs/luci-static/resources/ui.js index 684d984ad..5fa75c3f6 100644 --- a/modules/luci-base/htdocs/luci-static/resources/ui.js +++ b/modules/luci-base/htdocs/luci-static/resources/ui.js @@ -917,6 +917,33 @@ var UIDropdown = UIElement.extend({ } }, + createChoiceElement: function(sb, value, label) { + var tpl = sb.querySelector(this.options.create_template), + markup = null; + + if (tpl) + markup = (tpl.textContent || tpl.innerHTML || tpl.firstChild.data).replace(/^<!--|-->$/, '').trim(); + else + markup = '<li data-value="{{value}}"><span data-label-placeholder="true" /></li>'; + + var new_item = E(markup.replace(/{{value}}/g, '%h'.format(value))), + placeholder = new_item.querySelector('[data-label-placeholder]'); + + if (placeholder) { + var content = E('span', {}, label || this.choices[value] || [ value ]); + + while (content.firstChild) + placeholder.parentNode.insertBefore(content.firstChild, placeholder); + + placeholder.parentNode.removeChild(placeholder); + } + + if (this.options.multiple) + this.transformItem(sb, new_item); + + return new_item; + }, + createItems: function(sb, value) { var sbox = this, val = (value || '').trim(), @@ -936,20 +963,9 @@ var UIDropdown = UIElement.extend({ }); if (!new_item) { - var markup, - tpl = sb.querySelector(sbox.options.create_template); - - if (tpl) - markup = (tpl.textContent || tpl.innerHTML || tpl.firstChild.data).replace(/^<!--|-->$/, '').trim(); - else - markup = '<li data-value="{{value}}">{{value}}</li>'; - - new_item = E(markup.replace(/{{value}}/g, '%h'.format(item))); + new_item = sbox.createChoiceElement(sb, item); - if (sbox.options.multiple) { - sbox.transformItem(sb, new_item); - } - else { + if (!sbox.options.multiple) { var old = ul.querySelector('li[created]'); if (old) ul.removeChild(old); @@ -965,6 +981,54 @@ var UIDropdown = UIElement.extend({ }); }, + clearChoices: function(reset_value) { + var ul = this.node.querySelector('ul'), + lis = ul ? ul.querySelectorAll('li[data-value]') : [], + len = lis.length - (this.options.create ? 1 : 0), + val = reset_value ? null : this.getValue(); + + for (var i = 0; i < len; i++) { + var lival = lis[i].getAttribute('data-value'); + if (val == null || + (!this.options.multiple && val != lival) || + (this.options.multiple && val.indexOf(lival) == -1)) + ul.removeChild(lis[i]); + } + + if (reset_value) + this.setValues(this.node, {}); + }, + + addChoices: function(values, labels) { + var sb = this.node, + ul = sb.querySelector('ul'), + lis = ul ? ul.querySelectorAll('li[data-value]') : []; + + if (!Array.isArray(values)) + values = L.toArray(values); + + if (!L.isObject(labels)) + labels = {}; + + for (var i = 0; i < values.length; i++) { + var found = false; + + for (var j = 0; j < lis.length; j++) { + if (lis[j].getAttribute('data-value') === values[i]) { + found = true; + break; + } + } + + if (found) + continue; + + ul.insertBefore( + this.createChoiceElement(sb, values[i], labels[values[i]]), + ul.lastElementChild); + } + }, + closeAllDropdowns: function() { document.querySelectorAll('.cbi-dropdown[open]').forEach(function(s) { s.dispatchEvent(new CustomEvent('cbi-dropdown-close', {})); |