X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fweb%2Fhtdocs%2Fluci-static%2Fresources%2Fcbi.js;h=059d27a1b921ae92bc7ff907ef35f4a19fb671de;hp=7c5dd4ef464bf112efd822c9cdd6ba15959ad953;hb=c20dcb3612de13eeb870de31d83e816d93bdc830;hpb=5e45e4107b6f944942cfc31a4f408395a3361835 diff --git a/libs/web/htdocs/luci-static/resources/cbi.js b/libs/web/htdocs/luci-static/resources/cbi.js index 7c5dd4ef4..059d27a1b 100644 --- a/libs/web/htdocs/luci-static/resources/cbi.js +++ b/libs/web/htdocs/luci-static/resources/cbi.js @@ -70,34 +70,25 @@ var cbi_validators = { addr = addr.substr(0, off) + ':0:0'; } - if( addr.indexOf('::') < 0 ) + if( addr.indexOf('::') >= 0 ) { - return (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null); - } + var colons = 0; + var fill = '0'; - var fields = 0; + for( var i = 0; i < addr.length; i++ ) + if( addr.charAt(i) == ':' ) + colons++; - for( var i = 0, last = 0, comp = false; i <= addr.length; i++ ) - { - if( (addr.charAt(i) == ':') || (i == addr.length) ) - { - if( (i == last) && !comp ) - { - comp = true; - } - else - { - var f = addr.substring(last, i); - if( !(f && f.match(/^[a-fA-F0-9]{1,4}$/)) ) - return false; - } - - fields++; - last = i + 1; - } + if( colons > 7 ) + return false; + + for( var i = 0; i < (7 - colons); i++ ) + fill += ':0'; + + addr = addr.replace(/::/, ':' + fill + ':'); } - return (fields == 8); + return (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null); } } @@ -161,6 +152,22 @@ var cbi_validators = { return (v.length == 5) || (v.length == 13); }, + 'uciname': function(v) + { + return (v.match(/^[a-zA-Z0-9_]+$/) != null); + }, + + 'range': function(v, args) + { + var min = parseInt(args[0]); + var max = parseInt(args[1]); + var val = parseInt(v); + + if (!isNaN(min) && !isNaN(max) && !isNaN(val)) + return ((val >= min) && (val <= max)); + + return false; + } }; @@ -274,22 +281,19 @@ function cbi_d_update() { } function cbi_bind(obj, type, callback, mode) { - if (typeof mode == "undefined") { - mode = false; - } if (!obj.addEventListener) { - ieCallback = function(){ - var e = window.event; - if (!e.target && e.srcElement) { - e.target = e.srcElement; - }; - e.target['_eCB' + type + callback] = callback; - e.target['_eCB' + type + callback](e); - e.target['_eCB' + type + callback] = null; - }; - obj.attachEvent('on' + type, ieCallback); + obj.attachEvent('on' + type, + function(){ + var e = window.event; + + if (!e.target && e.srcElement) + e.target = e.srcElement; + + return !!callback(e); + } + ); } else { - obj.addEventListener(type, callback, mode); + obj.addEventListener(type, callback, !!mode); } return obj; } @@ -302,17 +306,21 @@ function cbi_combobox(id, values, def, man) { var obj = document.getElementById(id) var sel = document.createElement("select"); - sel.id = selid; - sel.className = 'cbi-input-select'; - if (obj.className && obj.className.match(/cbi-input-invalid/)) { - sel.className += ' cbi-input-invalid'; - } + sel.id = selid; + sel.className = 'cbi-input-select'; + if (obj.nextSibling) { obj.parentNode.insertBefore(sel, obj.nextSibling); } else { obj.parentNode.appendChild(sel); } + var dt = obj.getAttribute('cbi_datatype'); + var op = obj.getAttribute('cbi_optional'); + + if (dt) + cbi_validate_field(sel, op == 'true', dt); + if (!values[obj.value]) { if (obj.value == "") { var optdef = document.createElement("option"); @@ -354,8 +362,6 @@ function cbi_combobox(id, values, def, man) { obj.focus(); } else { obj.value = sel.options[sel.selectedIndex].value; - sel.className = (!obj.validate || obj.validate()) - ? 'cbi-input-select' : 'cbi-input-select cbi-input-invalid'; } try { @@ -384,6 +390,152 @@ function cbi_filebrowser(id, url, defpath) { browser.focus(); } +function cbi_dynlist_init(name) +{ + function cbi_dynlist_renumber(e) + { + var count = 1; + var childs = e.parentNode.childNodes; + + for( var i = 0; i < childs.length; i++ ) + if( childs[i].name == name ) + childs[i].id = name + '.' + (count++); + + e.focus(); + } + + function cbi_dynlist_keypress(ev) + { + ev = ev ? ev : window.event; + + var se = ev.target ? ev.target : ev.srcElement; + + if (se.nodeType == 3) + se = se.parentNode; + + switch (ev.keyCode) + { + /* backspace, delete */ + case 8: + case 46: + if (se.value.length == 0) + { + if (ev.preventDefault) + ev.preventDefault(); + + return false; + } + + return true; + + /* enter, arrow up, arrow down */ + case 13: + case 38: + case 40: + if (ev.preventDefault) + ev.preventDefault(); + + return false; + } + + return true; + } + + function cbi_dynlist_keydown(ev) + { + ev = ev ? ev : window.event; + + var se = ev.target ? ev.target : ev.srcElement; + + if (se.nodeType == 3) + se = se.parentNode; + + var prev = se.previousSibling; + while (prev && prev.name != name) + prev = prev.previousSibling; + + var next = se.nextSibling; + while (next && next.name != name) + next = next.nextSibling; + + switch (ev.keyCode) + { + /* backspace, delete */ + case 8: + case 46: + var jump = (ev.keyCode == 8) + ? (prev || next) : (next || prev); + + if (se.value.length == 0 && jump) + { + se.parentNode.removeChild(se.nextSibling); + se.parentNode.removeChild(se); + + cbi_dynlist_renumber(jump); + + if (ev.preventDefault) + ev.preventDefault(); + + return false; + } + + break; + + /* enter */ + case 13: + var n = document.createElement('input'); + n.name = se.name; + n.type = se.type; + + cbi_bind(n, 'keydown', cbi_dynlist_keydown); + cbi_bind(n, 'keypress', cbi_dynlist_keypress); + + if (next) + { + se.parentNode.insertBefore(n, next); + se.parentNode.insertBefore(document.createElement('br'), next); + } + else + { + se.parentNode.appendChild(n); + se.parentNode.appendChild(document.createElement('br')); + } + + var dt = se.getAttribute('cbi_datatype'); + var op = se.getAttribute('cbi_optional') == 'true'; + + if (dt) + cbi_validate_field(n, op, dt); + + cbi_dynlist_renumber(n); + break; + + /* arrow up */ + case 38: + if (prev) + prev.focus(); + + break; + + /* arrow down */ + case 40: + if (next) + next.focus(); + + break; + } + + return true; + } + + var inputs = document.getElementsByName(name); + for( var i = 0; i < inputs.length; i++ ) + { + cbi_bind(inputs[i], 'keydown', cbi_dynlist_keydown); + cbi_bind(inputs[i], 'keypress', cbi_dynlist_keypress); + } +} + //Hijacks the CBI form to send via XHR (requires Prototype) function cbi_hijack_forms(layer, win, fail, load) { var forms = layer.getElementsByTagName('form'); @@ -462,6 +614,10 @@ function cbi_t_update() { function cbi_validate_form(form, errmsg) { + /* if triggered by a section removal or addition, don't validate */ + if( form.cbi_state == 'add-section' || form.cbi_state == 'del-section' ) + return true; + if( form.cbi_validators ) { for( var i = 0; i < form.cbi_validators.length; i++ ) @@ -489,12 +645,20 @@ function cbi_validate_reset(form) function cbi_validate_field(cbid, optional, type) { - var field = document.getElementById(cbid); + var field = (typeof cbid == "string") ? document.getElementById(cbid) : cbid; + var vargs; + + if( type.match(/^(\w+)\(([^\(\)]+)\)/) ) + { + type = RegExp.$1; + vargs = RegExp.$2.split(/\s*,\s*/); + } + var vldcb = cbi_validators[type]; if( field && vldcb ) { - var validator = function(reset) + var validator = function() { // is not detached if( field.form ) @@ -502,8 +666,10 @@ function cbi_validate_field(cbid, optional, type) field.className = field.className.replace(/ cbi-input-invalid/g, ''); // validate value - var value = (field.options) ? field.options[field.options.selectedIndex].value : field.value; - if( !(((value.length == 0) && optional) || vldcb(value)) ) + var value = (field.options && field.options.selectedIndex > -1) + ? field.options[field.options.selectedIndex].value : field.value; + + if( !(((value.length == 0) && optional) || vldcb(value, vargs)) ) { // invalid field.className += ' cbi-input-invalid'; @@ -518,9 +684,25 @@ function cbi_validate_field(cbid, optional, type) field.form.cbi_validators = [ ]; field.form.cbi_validators.push(validator); - field.onblur = field.onkeyup = field.validate = validator; + + cbi_bind(field, "blur", validator); + cbi_bind(field, "keyup", validator); + + if (field.nodeName == 'SELECT') + { + cbi_bind(field, "change", validator); + cbi_bind(field, "click", validator); + } + + field.setAttribute("cbi_validate", validator); + field.setAttribute("cbi_datatype", type); + field.setAttribute("cbi_optional", (!!optional).toString()); validator(); + + var fcbox = document.getElementById('cbi.combobox.' + field.id); + if (fcbox) + cbi_validate_field(fcbox, optional, type); } }