jeges

formChecker live example v2

Nov 29th, 2014
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
  5. <title>teszt</title>
  6. <style type="text/css">
  7.  
  8. #fm {width:500px;display:block;margin:0; padding:0;}
  9. #fm label, #fm input {display:inline;float:left;position:relative;margin:0 0 5px 5px; padding:0;font:normal 12px Verdana;}
  10. #fm label {width:200px; font-weight:700; text-align:right;}
  11. #fm input {width:250px; text-align:left;}
  12. #send {width:60px !important;font-weight:700 !important;text-align:center !important; margin-left:200px !important;}
  13. #log {width:500px;height:100px;display:block;float:left;position:relative;}
  14. #errorMsg {
  15.     width:300px;height:100px;left:300px;top:200px;display:block;position:fixed;
  16.     text-align:center;vertical-align:middle; border:2px solid #F5F5F5; background:#DDD;
  17. }
  18. .failed{background:#FEE;}
  19. .succeeded{background:#EFE;}
  20. </style>
  21.  
  22. <script type="text/javascript">
  23.  
  24. // Necessary functions for formChecker
  25.  
  26. // shorthand for getElementById
  27. function $lm(obj){
  28.   if ( document.getElementById(obj) ) return document.getElementById(obj);
  29.   else return false;
  30. }
  31.  
  32. // object's first child with the given class
  33. function firstChildofClass(p,cl) {
  34.   if (!p || !p.childNodes.length)return;
  35.   var ch = p.childNodes;
  36.   for ( var i = 0; i < ch.length; i++ ){
  37.     if (gotClass(ch[i],cl))return ch[i];
  38.   }
  39.   return;
  40. }
  41.  
  42. // shorthand for firstChildOfClass
  43. function $fc(p, cl){
  44.   return firstChildofClass(p,cl);
  45. }
  46.  
  47. function gotClass(obj,cl) {
  48.     var r = new RegExp("\\b" + cl + "\\b", "i");
  49.     var ob = ( typeof(obj) == "object" ) ? obj : $lm(obj);
  50.     if ( ob && ob.className && ob.className.match(r) !== null ) return true;
  51.     return false;
  52. }
  53.  
  54. // object's all children with given class
  55. function getChildElementsByClassName(obj,cl){
  56.   var oc = ( obj != undefined ) ? obj.childNodes : document.body.childNodes;
  57.   var ch = [];
  58.   for ( var i = 0; i < oc.length; i++ ){
  59.     if (gotClass(oc[i],cl)) ch.push(oc[i]);
  60.   }
  61.   return ch;
  62. }
  63.  
  64. // shorthand for getChildElementsByClassName
  65. function $cc(obj,cl){
  66.   return getChildElementsByClassName(obj,cl);
  67. }
  68.  
  69. // shorthand for parseFloat
  70. function pf(n){return parseFloat(n);}
  71.  
  72. // set object's css style
  73. function setStyle(obj,st,vl){
  74.     var a = obj.style.cssText;
  75.     obj.style.cssText = (a.length>0) ? a + ";" + st + ":" + vl : st + ":" + vl ;
  76. }
  77.  
  78. // trim and compress spaces
  79. String.prototype.clean = function(){
  80.     return this.replace(/^(\s+)/g,"").replace(/(\s+)$/g , "").replace(/\s\s+/g , " ");
  81. }
  82.  
  83. // add given class to object's className
  84. function addClass(obj,c){
  85.     obj.className = (obj.className.length > 0) ? obj.className + " " + c : c;
  86. }
  87.  
  88. // remove given class from object's className
  89. function removeClass(obj,c){
  90.     var r = new RegExp("(\\b" + c + "\\b)", "gi");
  91.     obj.className = obj.className.replace( r , " " ).clean();
  92. }
  93.  
  94. /* formChecker class definition
  95.  * parameters:
  96.  * fm - the form to be verified
  97.  * rule - form rules in JSON format
  98.  * rule record (object) properties:
  99.  * sbj - input class
  100.  *      if the form contains more than one input of the same class, each one will be verified
  101.  * fnc - verifier function (these are methods of the chk() object class)
  102.  *      see functions for more details
  103.  * prm - value to verify against
  104.  *      can be a fixed value or a form elem value defined by class or id (css-like definitions -> ".myclass" or "#myid")
  105.  *
  106.  * usage:
  107.  *      1) design your own checker functions into chk() class definition if necessary
  108.  *      2) design your own rules
  109.  *      3) design callback functions (init, success, failure, error)
  110.  *      4) insert init code
  111.  *
  112.  *      for live example see my pastebin
  113.  *
  114. **/
  115.  
  116. function formChecker(fm,rule,cf,sf,ff,ef){
  117.  
  118.     if (!fm) return;
  119.  
  120.     this.fm = fm;       // form DOM object
  121.     this.rule = rule;   // rule JSON object-list
  122.     this.res = [];      // result array
  123.     this.nof = 0;       // number of fails
  124.  
  125.     if ( cf == undefined || typeof cf != "function" )cf = null;
  126.     if ( sf == undefined || typeof sf != "function" )sf = null;
  127.     if ( ff == undefined || typeof ff != "function" )ff = null;
  128.     if ( ef == undefined || typeof ef != "function" )ef = null;
  129.  
  130.     this.chk = function(){
  131.  
  132.         var r,val,lm,c,prm;
  133.  
  134.         // clear earlier results
  135.         cf(this.fm);
  136.  
  137.         // rules
  138.         for (var i in this.rule){
  139.  
  140.             r = this.rule[i];
  141.  
  142.             // check only if object exists
  143.             if ( $fc(this.fm,r.sbj) ){
  144.  
  145.                 // handle parameters
  146.                 // only try to find css-like object reference, if not number and not regexp
  147.                 // css-style DOM reference lookup with ".myclass" and "#myid"
  148.  
  149.                 prm = r.prm;
  150.  
  151.                 if ( isNaN(prm) && r.fnc != "rg" ){
  152.  
  153.                     // ".myclass"
  154.                     if ( /^\.\w+$/i.test(prm) ){
  155.  
  156.                         var tst = true;
  157.                         // only first object of the same class
  158.                         if ( $fc( this.fm , prm.substr(1) ) )prm = $fc( this.fm , prm.substr(1) ).value;
  159.  
  160.                     }
  161.  
  162.                     // "#myid"
  163.                     else if ( /^#\w+$/i.test(prm) ){
  164.  
  165.                         var tst = true;
  166.                         if ( $lm( prm.substr(1) ) )prm = $lm( prm.substr(1) ).value;
  167.  
  168.                     }
  169.  
  170.                 }
  171.  
  172.                 // if there's more than one input of the same class, verify each
  173.                 lm = $cc(this.fm,r.sbj);
  174.                 for (var i = 0; i < lm.length; i++){
  175.  
  176.                     c = new chk(lm[i]);
  177.                     try{
  178.  
  179.                         val = c.exec(r.fnc,prm);
  180.  
  181.                         // fail
  182.                         if(!val){
  183.                        
  184.                             // use "&prm" in msg to feedback actual value from "prm"
  185.                             var msg = r.msg.replace( new RegExp("&prm", "gi"), prm);
  186.  
  187.                             ff(lm[i],msg);
  188.                             this.nof++;
  189.  
  190.                         }
  191.  
  192.                         // success
  193.                         else sf(lm[i],"");
  194.  
  195.                     } catch(er) {
  196.  
  197.                         // error
  198.                         val = ef(er);
  199.  
  200.                     }
  201.  
  202.                     this.res.push(val);
  203.  
  204.                 }
  205.  
  206.             }
  207.  
  208.         }
  209.  
  210.         return this.nof;
  211.  
  212.     }
  213.  
  214. }
  215.  
  216. // Compare functions for formChecker
  217.  
  218. function chk(obj){
  219.  
  220.     this.v = (obj.value) ? obj.value : obj.innerHTML;
  221.  
  222.     // numeric "equals"
  223.     this.eq = function(b){
  224.         if (pf(this.v) == pf(b))return true;
  225.         return false;
  226.     }
  227.  
  228.     // string equals ("exact")
  229.     this.ex = function(b){
  230.       if (this.v == b)return true;
  231.       return false;
  232.     }
  233.  
  234.     // numeric "lesser than"
  235.     this.lt = function(b){
  236.         if (pf(this.v) < pf(b))return true;
  237.         return false;
  238.     }
  239.  
  240.     // numeric "lesser or equals"
  241.     this.le = function(b){
  242.       if (pf(this.v) <= pf(b))return true;
  243.         return false;
  244.     }
  245.  
  246.     // numeric "greater than"
  247.     this.gt = function(b){
  248.       if (pf(this.v) > pf(b))return true;
  249.         return false;
  250.     }
  251.  
  252.     // numeric "greater or equals"
  253.     this.ge = function(b){
  254.       if (pf(this.v) >= pf(b))return true;
  255.         return false;
  256.     }
  257.  
  258.     // empty ?
  259.     this.nn = function(){
  260.         if (this.v.toString().length > 0)return true;
  261.         return false;
  262.     }
  263.  
  264.     // regexp pattern
  265.     this.rg = function(b){
  266.         var bb = new RegExp(b[0],b[1]);
  267.         return bb.test(this.v);
  268.     }
  269.  
  270.     this.exec = function(f, arg) {
  271.  
  272.         return this[f](arg);
  273.  
  274.     }
  275.  
  276. }
  277.  
  278. // End of formChecker class definition
  279.  
  280. /* Rule examples
  281.  
  282. Notes:
  283. The first example refers to both inputs named "nm". It checks if inputs called "nm" are empty.
  284. The second one has a param that refers to the value of the elements with "minyr" css class. If there are more than one, formChecker tries to check against each.
  285. Numeric checks are:
  286. eq = equals
  287. ne = not equals
  288. gt = greater than
  289. ge = greater than or equal
  290. lt = less than
  291. le = less than or equal
  292. The third one has a param that refers to the value of the element with "maxyr" css id. Since css id is supposed to be unique, formChecker does not try to search for more than one.
  293. The fifth rule sets a pattern to use regexp comparison.
  294. If you are not familiar with regexp, you can use simple string comparison like in the sixth rule. "ex" means "exact" - just like in ms excel.
  295. The seventh rule should raise an error, since there is no comparison function like "dd".
  296.  
  297. Note that one of the major advantage of using JSON is that it can be sent to the client by the server.
  298. This structure allows you to download rules and check locally before sending the form's data back.
  299. This design can lift some weight from your backend (of course you can not spare checks on the server side).
  300.  
  301. */
  302.  
  303. myRule = {
  304.  
  305.     first: {
  306.         sbj: "nm",
  307.         fnc: "nn",
  308.         prm: "",
  309.         msg: "Name can not be empty."
  310.     },
  311.  
  312.     second: {
  313.         sbj: "yr",
  314.         fnc: "gt",
  315.         prm: ".minyr",
  316.         msg: "Must be over &prm."
  317.     },
  318.  
  319.     third: {
  320.         sbj: "yr",
  321.         fnc: "lt",
  322.         prm: "#maxyr",
  323.         msg: "Must be under &prm."
  324.     },
  325.  
  326.     fourth: {
  327.         sbj: "cn",
  328.         fnc: "nn",
  329.         prm: "",
  330.         msg: "Country can not be empty."
  331.     },
  332.  
  333.     fifth: {
  334.         sbj: "cn",
  335.         fnc: "rg",
  336.         prm: ["^hu\s*$","i"],
  337.         msg: "Only for hungarian residents."
  338.     },
  339.  
  340.     sixth: {
  341.         sbj: "cn",
  342.         fnc: "ex",
  343.         prm: "hu",
  344.         msg: "Only for citizens of republic of Hungary."
  345.     }/*,
  346.  
  347.     seventh: {
  348.         sbj: "cn",
  349.         fnc: "dd",
  350.         prm: "hu",
  351.         msg: "Errorous rule."
  352.     }*/
  353.  
  354. }
  355.  
  356. window.onload = function(){
  357.  
  358.     setElem = function(o,msg,cl){
  359.         var s = "\n";
  360.         if (!o.title || o.title == "" || msg == undefined || msg == "")s = "";
  361.         o.title += s + msg;
  362.         removeClass(o,"succeeded");
  363.         removeClass(o,"failed");
  364.         addClass(o,cl);
  365.     }
  366.  
  367.     // function to clear given form's inputs
  368.     // defined for formChecker to run on reset
  369.     clear = function(fm){
  370.         var lm = fm.getElementsByTagName("*");
  371.         for (var i = 0; i < lm.length; i++){
  372.             try {
  373.                     lm[i].title = "";
  374.                     removeClass(lm[i],"succeeded");
  375.                     removeClass(lm[i],"failed");
  376.  
  377.             }catch(e){
  378.                 continue;
  379.             }
  380.         }
  381.     }
  382.     // callback to execute on successful check
  383.     success = function(o,msg){
  384.         var c = "succeeded";
  385.         if(gotClass(o,"failed"))c = "failed";
  386.         setElem(o,msg,c);
  387.     }
  388.     // callback to execute on failed check
  389.     fail = function(o,msg){
  390.         setElem(o,msg,"failed");
  391.     }
  392.     // callback to execute on error
  393.     error = function(er){
  394.  
  395.         if ( !$fc(document.body,"errorMsg") ){
  396.             var ed = document.createElement("div");
  397.             ed.className = "errorMsg";
  398.             ed.title = "click to disappear";
  399.             ed.innerHTML = er;
  400.             document.body.appendChild(ed);
  401.             ed.onclick = function(){ document.body.removeChild(ed); }
  402.         }
  403.         else $fc(document.body,"errorMsg").innerHTML += "<br>" + er;
  404.     }
  405.  
  406.     var sn = $lm("send");
  407.     var fm = $lm("fm");
  408.     var lg = $lm("log");
  409.  
  410.     sn.onclick = function(){
  411.  
  412.         lg.innerHTML = "";
  413.  
  414.         var fc = new formChecker(fm,myRule,clear,success,fail,error);
  415.  
  416.         if (fc.chk() == 0){lg.innerHTML = "All checks are ok";}
  417.  
  418.     }
  419.  
  420. }
  421.  
  422. </script>
  423. </head>
  424. <body>
  425.  
  426. <form id="fm" name="fm" method="post">
  427.  
  428. <label for="fnm">Firstname</label><input type="text" name="fnm" id="fnm" class="nm" value="fname" />
  429. <label for="lnm">Lastname</label><input type="text" name="lnm" id="lnm" class="nm" value="lname" />
  430. <label for="yr">Age</label><input type="text" name="yr" id="yr" class="yr" value="25" />
  431. <label for="minyr">Minimum age</label><input type="text" name="minyr" id="minyr" class="minyr" value="18" />
  432. <label for="maxyr">Maximum age</label><input type="text" name="maxyr" id="maxyr" class="maxyr" value="99" />
  433. <label for="cn">Country</label><input type="text" name="cn" id="cn" class="cn" value="country (short, i.e. hu or en)" />
  434. <input type="button" name="send" id="send" value="send" />
  435.  
  436. </form>
  437. <br>
  438. <div id="log"></log>
  439. </body>
  440. </html>
Add Comment
Please, Sign In to add comment