diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2010-04-26 21:42:10 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2010-04-26 21:42:10 +0000 |
commit | ee36ef41700af6941ed8d2ad8b0d94e68e43e9a6 (patch) | |
tree | 904882534a14f0a193a9880e129129b7282b3585 /libs/cbi | |
parent | d311e5ebcd30bdca656af89c20cea9de34934a79 (diff) |
libs/cbi: implement realtime client side input validation for Value and DynamicList fields
Diffstat (limited to 'libs/cbi')
-rw-r--r-- | libs/cbi/htdocs/luci-static/resources/cbi.js | 75 | ||||
-rw-r--r-- | libs/cbi/luasrc/view/cbi/header.htm | 4 | ||||
-rw-r--r-- | libs/cbi/luasrc/view/cbi/value.htm | 9 |
3 files changed, 59 insertions, 29 deletions
diff --git a/libs/cbi/htdocs/luci-static/resources/cbi.js b/libs/cbi/htdocs/luci-static/resources/cbi.js index 3840456ca..7cdca642d 100644 --- a/libs/cbi/htdocs/luci-static/resources/cbi.js +++ b/libs/cbi/htdocs/luci-static/resources/cbi.js @@ -304,6 +304,9 @@ function cbi_combobox(id, values, def, man) { 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'; + } if (obj.nextSibling) { obj.parentNode.insertBefore(sel, obj.nextSibling); } else { @@ -351,6 +354,8 @@ 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 { @@ -447,43 +452,63 @@ function cbi_t_update() { } -function cbi_validate_disable_form(form, onoff) +function cbi_validate_form(form, errmsg) { - for( var i = 0; i < form.elements.length; i++ ) + if( form.cbi_validators ) { - if( form.elements[i].type == 'submit' ) + for( var i = 0; i < form.cbi_validators.length; i++ ) { - form.elements[i].disabled = onoff; - break; + var validator = form.cbi_validators[i]; + if( !validator() && errmsg ) + { + alert(errmsg); + return false; + } } } + + return true; } -function cbi_validate_field(type, optional, field) +function cbi_validate_reset(form) { - field.className = field.className.replace(/ cbi-input-invalid/g, ''); + window.setTimeout( + function() { cbi_validate_form(form, null) }, 100 + ); + + return true; +} +function cbi_validate_field(cbid, optional, type) +{ + var field = document.getElementById(cbid); var vldcb = cbi_validators[type]; - if( vldcb ) - { - var value = (field.options) ? field.options[field.options.selectedIndex].value : field.value; - if( ((value.length == 0) && optional) || vldcb(value) ) - { - // OK - cbi_validate_disable_form(field.form, false); - } - else - { - // Invalid - field.className += ' cbi-input-invalid'; - cbi_validate_disable_form(field.form, true); - } - } - else + if( field && vldcb ) { - // OK - cbi_validate_disable_form(field.form, false); + var validator = function(reset) + { + 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)) ) + { + // invalid + field.className += ' cbi-input-invalid'; + return false; + } + + return true; + }; + + if( ! field.form.cbi_validators ) + field.form.cbi_validators = [ ]; + + field.form.cbi_validators.push(validator); + field.onblur = field.onkeyup = field.validate = validator; + + validator(); } } diff --git a/libs/cbi/luasrc/view/cbi/header.htm b/libs/cbi/luasrc/view/cbi/header.htm index bece16bb2..fd1ab8bd1 100644 --- a/libs/cbi/luasrc/view/cbi/header.htm +++ b/libs/cbi/luasrc/view/cbi/header.htm @@ -1,7 +1,7 @@ <%# LuCI - Lua Configuration Interface Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> +Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ $Id$ -%> <%+header%> -<form method="post" name="cbi" action="<%=REQUEST_URI%>" enctype="multipart/form-data"> +<form method="post" name="cbi" action="<%=REQUEST_URI%>" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, '<%:Some fields are invalid, cannot save values!%>')"> <div> <script type="text/javascript" src="<%=resource%>/cbi.js"></script> <input type="hidden" name="cbi.submit" value="1" /> diff --git a/libs/cbi/luasrc/view/cbi/value.htm b/libs/cbi/luasrc/view/cbi/value.htm index 8bdebd902..a7b49de7f 100644 --- a/libs/cbi/luasrc/view/cbi/value.htm +++ b/libs/cbi/luasrc/view/cbi/value.htm @@ -1,7 +1,7 @@ <%# LuCI - Lua Configuration Interface Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> +Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,8 +15,9 @@ $Id$ <%+cbi/valueheader%> <input type="<%=self.password and 'password" class="cbi-input-password' or 'text" class="cbi-input-text' %>" onchange="cbi_d_update(this.id)"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self:cfgvalue(section) or self.default) .. ifattr(self.size, "size")%> /> <% if self.password then %><img src="<%=resource%>/cbi/reload.gif" style="vertical-align:middle" title="<%:Reveal/hide password%>" onclick="var e = document.getElementById('<%=cbid%>'); e.type = (e.type=='password') ? 'text' : 'password';" /><% end %> - <% if #self.keylist > 0 then -%> + <% if #self.keylist > 0 or self.datatype then -%> <script type="text/javascript"> + <% if #self.keylist > 0 then -%> cbi_combobox_init('<%=cbid%>', { <%- for i, k in ipairs(self.keylist) do @@ -34,6 +35,10 @@ $Id$ <%- else -%> <%-: -- custom -- -%> <%- end -%>'); + <%- end %> + <% if self.datatype then -%> + cbi_validate_field('<%=cbid%>', <%=tostring(self.optional == true)%>, '<%=self.datatype%>'); + <%- end %> </script> <% end -%> <%+cbi/valuefooter%> |