luci-base: fix dependency handling of optionals (#645)
[project/luci.git] / modules / luci-base / htdocs / luci-static / resources / cbi.js
index 81cc657..a8d323d 100644 (file)
@@ -490,6 +490,10 @@ function cbi_d_update() {
 
                        state = true;
                }
+
+               // hide optionals widget if no choices remaining
+               if (parent.parentNode && parent.getAttribute('data-optionals'))
+                       parent.parentNode.style.display = (parent.options.length <= 1) ? 'none' : '';
        }
 
        if (entry && entry.parent) {
@@ -506,14 +510,24 @@ function cbi_init() {
        var nodes = document.querySelectorAll('[data-depends]');
 
        for (var i = 0, node; (node = nodes[i]) !== undefined; i++) {
-               var deps = JSON.parse(node.getAttribute('data-depends'));
-               if (deps.length > 0) {
-                       for (var alt = 0; alt < deps.length; alt++) {
-                               cbi_d_add(node, deps[alt], i);
+               var index = parseInt(node.getAttribute('data-index'), 10);
+               var depends = JSON.parse(node.getAttribute('data-depends'));
+               if (!isNaN(index) && depends.length > 0) {
+                       for (var alt = 0; alt < depends.length; alt++) {
+                               cbi_d_add(node, depends[alt], index);
                        }
                }
        }
 
+       nodes = document.querySelectorAll('[data-update]');
+
+       for (var i = 0, node; (node = nodes[i]) !== undefined; i++) {
+               var events = node.getAttribute('data-update').split(' ');
+               for (var j = 0, event; (event = events[j]) !== undefined; j++) {
+                       cbi_bind(node, event, cbi_d_update);
+               }
+       }
+
        cbi_d_update();
 }
 
@@ -535,7 +549,7 @@ function cbi_bind(obj, type, callback, mode) {
        return obj;
 }
 
-function cbi_combobox(id, values, def, man) {
+function cbi_combobox(id, values, def, man, focus) {
        var selid = "cbi.combobox." + id;
        if (document.getElementById(selid)) {
                return
@@ -595,6 +609,7 @@ function cbi_combobox(id, values, def, man) {
        cbi_bind(sel, "change", function() {
                if (sel.selectedIndex == sel.options.length - 1) {
                        obj.style.display = "inline";
+                       sel.blur();
                        sel.parentNode.removeChild(sel);
                        obj.focus();
                } else {
@@ -609,16 +624,18 @@ function cbi_combobox(id, values, def, man) {
        })
 
        // Retrigger validation in select
-       sel.focus();
-       sel.blur();
+       if (focus) {
+               sel.focus();
+               sel.blur();
+       }
 }
 
 function cbi_combobox_init(id, values, def, man) {
        var obj = document.getElementById(id);
        cbi_bind(obj, "blur", function() {
-               cbi_combobox(id, values, def, man)
+               cbi_combobox(id, values, def, man, true);
        });
-       cbi_combobox(id, values, def, man);
+       cbi_combobox(id, values, def, man, false);
 }
 
 function cbi_filebrowser(id, url, defpath) {
@@ -934,9 +951,8 @@ function cbi_t_update() {
                {
                        var t = cbi_t[sid][tid].tab;
                        var c = cbi_t[sid][tid].container;
-                       var n = c.getElementsByTagName('div');
 
-                       if (n.length === 0) {
+                       if (!c.firstElementChild) {
                                t.style.display = 'none';
                        }
                        else if (t.style.display == 'none') {