luci2: add utility functions
[project/luci2/ui.git] / luci2 / htdocs / luci2 / luci2.js
index 6481c0b..6c7db67 100644 (file)
@@ -214,7 +214,7 @@ function LuCI2()
                _class.prototype = prototype;
                _class.prototype.constructor = _class;
 
-               _class.extend = arguments.callee;
+               _class.extend = Class.extend;
 
                return _class;
        };
@@ -364,8 +364,10 @@ function LuCI2()
                        h += keys[i] + ':' + data[keys[i]];
                }
 
-               if (h)
+               if (h.length)
                        location.hash = '#' + h;
+               else
+                       location.hash = '';
        };
 
        this.getHash = function(key)
@@ -386,6 +388,103 @@ function LuCI2()
                return data;
        };
 
+       this.toArray = function(x)
+       {
+               switch (typeof(x))
+               {
+               case 'number':
+               case 'boolean':
+                       return [ x ];
+
+               case 'string':
+                       var r = [ ];
+                       var l = x.split(/\s+/);
+                       for (var i = 0; i < l.length; i++)
+                               if (l[i].length > 0)
+                                       r.push(l[i]);
+                       return r;
+
+               case 'object':
+                       if ($.isArray(x))
+                       {
+                               var r = [ ];
+                               for (var i = 0; i < x.length; i++)
+                                       r.push(x[i]);
+                               return r;
+                       }
+                       else if ($.isPlainObject(x))
+                       {
+                               var r = [ ];
+                               for (var k in x)
+                                       if (x.hasOwnProperty(k))
+                                               r.push(k);
+                               return r.sort();
+                       }
+               }
+
+               return [ ];
+       };
+
+       this.toObject = function(x)
+       {
+               switch (typeof(x))
+               {
+               case 'number':
+               case 'boolean':
+                       return { x: true };
+
+               case 'string':
+                       var r = { };
+                       var l = x.split(/\x+/);
+                       for (var i = 0; i < l.length; i++)
+                               if (l[i].length > 0)
+                                       r[l[i]] = true;
+                       return r;
+
+               case 'object':
+                       if ($.isArray(x))
+                       {
+                               var r = { };
+                               for (var i = 0; i < x.length; i++)
+                                       r[x[i]] = true;
+                               return r;
+                       }
+                       else if ($.isPlainObject(x))
+                       {
+                               return x;
+                       }
+               }
+
+               return { };
+       };
+
+       this.filterArray = function(array, item)
+       {
+               if (!$.isArray(array))
+                       return [ ];
+
+               for (var i = 0; i < array.length; i++)
+                       if (array[i] === item)
+                               array.splice(i--, 1);
+
+               return array;
+       };
+
+       this.toClassName = function(str, suffix)
+       {
+               var n = '';
+               var l = str.split(/[\/.]/);
+
+               for (var i = 0; i < l.length; i++)
+                       if (l[i].length > 0)
+                               n += l[i].charAt(0).toUpperCase() + l[i].substr(1).toLowerCase();
+
+               if (typeof(suffix) == 'string')
+                       n += suffix;
+
+               return n;
+       };
+
        this.globals = {
                timeout:  15000,
                resource: '/luci2',
@@ -451,7 +550,7 @@ function LuCI2()
                                                if (typeof(ret) != 'undefined' && key != '')
                                                        ret = ret[key];
 
-                                               if (type.call(ret) != type.call(req.expect[key]))
+                                               if (typeof(ret) == 'undefined' || type.call(ret) != type.call(req.expect[key]))
                                                        ret = req.expect[key];
 
                                                break;
@@ -2920,7 +3019,7 @@ function LuCI2()
                                                                else if (typeof types[label] == 'function')
                                                                {
                                                                        stack.push(types[label]);
-                                                                       stack.push(null);
+                                                                       stack.push([ ]);
                                                                }
                                                                else
                                                                {
@@ -2939,7 +3038,7 @@ function LuCI2()
                                                                throw "Syntax error, argument list follows non-function";
 
                                                        stack[stack.length-1] =
-                                                               arguments.callee(code.substring(pos, i));
+                                                               _luci2.cbi.validation.compile(code.substring(pos, i));
 
                                                        pos = i+1;
                                                }
@@ -3389,6 +3488,7 @@ function LuCI2()
                        }
 
                        i.error = $('<div />')
+                               .hide()
                                .addClass('label label-danger');
 
                        i.widget = $('<div />')
@@ -3525,7 +3625,7 @@ function LuCI2()
                                        d.elem.parents('div.form-group, td').first().addClass('luci2-form-error');
                                        d.elem.parents('div.input-group, div.form-group, td').first().addClass('has-error');
 
-                                       d.inst.error.text(_luci2.tr('Field must not be empty'));
+                                       d.inst.error.text(_luci2.tr('Field must not be empty')).show();
                                        rv = false;
                                }
                                else if (val.length > 0 && !vstack[0].apply(val, vstack[1]))
@@ -3533,7 +3633,7 @@ function LuCI2()
                                        d.elem.parents('div.form-group, td').first().addClass('luci2-form-error');
                                        d.elem.parents('div.input-group, div.form-group, td').first().addClass('has-error');
 
-                                       d.inst.error.text(validation.message.format.apply(validation.message, vstack[1]));
+                                       d.inst.error.text(validation.message.format.apply(validation.message, vstack[1])).show();
                                        rv = false;
                                }
                                else
@@ -3544,7 +3644,7 @@ function LuCI2()
                                        if (d.multi && d.inst.widget && d.inst.widget.find('input.error, select.error').length > 0)
                                                rv = false;
                                        else
-                                               d.inst.error.text('');
+                                               d.inst.error.text('').hide();
                                }
                        }
 
@@ -3749,7 +3849,6 @@ function LuCI2()
                        if (typeof(o.disabled) == 'undefined') o.disabled = '0';
 
                        var i = $('<input />')
-                               .addClass('form-control')
                                .attr('id', this.id(sid))
                                .attr('type', 'checkbox')
                                .prop('checked', this.ucivalue(sid));
@@ -4424,13 +4523,12 @@ function LuCI2()
 
                                        $('<li />')
                                                .append($('<label />')
-                                                       .addClass('radio inline')
+                                                       .addClass(itype + ' inline')
                                                        .append($('<input />')
                                                                .attr('name', itype + id)
                                                                .attr('type', itype)
                                                                .attr('value', iface['interface'])
-                                                               .prop('checked', !!check[iface['interface']])
-                                                               .addClass('form-control'))
+                                                               .prop('checked', !!check[iface['interface']]))
                                                        .append(badge))
                                                .appendTo(ul);
                                }
@@ -4440,13 +4538,12 @@ function LuCI2()
                        {
                                $('<li />')
                                        .append($('<label />')
-                                               .addClass('radio inline text-muted')
+                                               .addClass(itype + ' inline text-muted')
                                                .append($('<input />')
                                                        .attr('name', itype + id)
                                                        .attr('type', itype)
                                                        .attr('value', '')
-                                                       .prop('checked', !value)
-                                                       .addClass('form-control'))
+                                                       .prop('checked', !value))
                                                .append(_luci2.tr('unspecified')))
                                        .appendTo(ul);
                        }
@@ -4611,19 +4708,21 @@ function LuCI2()
                                                inval++;
 
                                if (inval > 0)
-                                       stbadge.text(inval)
+                                       stbadge.show()
+                                               .text(inval)
                                                .attr('title', _luci2.trp('1 Error', '%d Errors', inval).format(inval));
                                else
-                                       stbadge.text('');
+                                       stbadge.hide();
 
                                invals += inval;
                        }
 
                        if (invals > 0)
-                               badge.text(invals)
+                               badge.show()
+                                       .text(invals)
                                        .attr('title', _luci2.trp('1 Error', '%d Errors', invals).format(invals));
                        else
-                               badge.text('');
+                               badge.hide();
 
                        return invals;
                },
@@ -4645,10 +4744,11 @@ function LuCI2()
                        var badge = $('#' + this.id('sectiontab')).children('span:first');
 
                        if (this.error_count > 0)
-                               badge.text(this.error_count)
+                               badge.show()
+                                       .text(this.error_count)
                                        .attr('title', _luci2.trp('1 Error', '%d Errors', this.error_count).format(this.error_count));
                        else
-                               badge.text('');
+                               badge.hide();
 
                        return (this.error_count == 0);
                }