PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/media/js/custom.validateForm.js

https://bitbucket.org/vlad_teodorescu/jupp
JavaScript | 361 lines | 312 code | 40 blank | 9 comment | 92 complexity | d856c6a0b48c7700ddd2e83a6620a475 MD5 | raw file
  1. if (typeof('isset')!='function')//so we havent declared the function isset
  2. {
  3. function isset(obj)
  4. {
  5. if (typeof(obj)=='undefined')
  6. return false;
  7. if (obj==null)
  8. return false;
  9. return true;
  10. }
  11. }
  12. if (typeof('String.prototype.trim')!='function')
  13. {
  14. String.prototype.trim = function()
  15. {
  16. return this.replace(/^\s+|\s+$/g,"");
  17. }
  18. }
  19. function morph_phone(tel)
  20. {
  21. var i=0, expr = [/^\+407\d{8}$/,/^[0]{0,1}7\d{8}$/,/^0[23]\d{8}$/];
  22. for (i=0;i<expr.length;i++)
  23. if (expr[i].test(tel))
  24. return true;
  25. return false;
  26. }
  27. function morph_registration_number(reg)
  28. {
  29. if (reg.length<4)//yeah, numbers with less than 4 characters, sure.
  30. return false;
  31. var i=0;
  32. var exprs = [
  33. /^[a-z]{2}\-[\d]{2}\-[a-pr-z]{3}$/i,//match a permanent number (not Bucharest), eg GR-03-UNU. Note, the letter Q is excluded from the 3-letter group
  34. /^B\-[\d]{2,3}\-[a-pr-z]{3}$/i,//match a permanent number(Bucharest), eg B-664-KKO. Note, the letter Q is excluded from the 3-letter group
  35. /^[a-z]{1,2}[\d]{3,6}$/i//try to match a temporary number, eg AG045546
  36. ];
  37. for (i=0;i<exprs.length;i++)
  38. if (exprs[i].test(reg))
  39. return true;
  40. return false;
  41. }
  42. function morph_cnp(k)
  43. {
  44. var cnp = new Array();
  45. for (i = 0; i <=12; i++)
  46. {
  47. cnp[i] = k[i];
  48. }
  49. suma = cnp[0] * 2 + cnp[1] * 7 + cnp[2] * 9 + cnp[3] * 1 + cnp[4] * 4 + cnp[5] * 6 + cnp[6] * 3 + cnp[7] * 5 + cnp[8] * 8 + cnp[9] * 2 + cnp[10] * 7 + cnp[11] * 9;
  50. rest = suma % 11;
  51. if ((rest < 10 && rest == cnp[12]) || (rest == 10 && cnp[12]==1))
  52. validare = true;
  53. else
  54. validare = false;
  55. return validare;
  56. }
  57. function morph_ci_serie(k)
  58. {
  59. if (k.length!=2)
  60. return false;
  61. return true;
  62. }
  63. function morph_ci_numar(k)
  64. {
  65. if (k.length!=6)
  66. return false;
  67. for (i=0;i<k.length;i++)
  68. if (k[i]<'0' && k[i]>'9')
  69. return false;
  70. return true;
  71. }
  72. function morph_cui(cui)
  73. {
  74. //return true;//fuck that,we'll edit this out later
  75. var nr = cui.length, total = 0
  76. if (nr < 2 || nr > 10) {return false}
  77. pondere = "7532175321".substr(10-nr,nr)
  78. for (x=0; x < nr -1 ; ++x) {total += cui.charAt(x) * pondere.charAt(x)}
  79. return (cui.substr(nr-1,1) == ((total * 10) % 11 ) % 10 )
  80. }
  81. function morph_email(email)
  82. {
  83. var matches = email.match(/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i);
  84. if (!isset(matches))
  85. return false;
  86. return (matches.length==1);
  87. }
  88. function morph_url(url)
  89. {
  90. var matches = url.match(/^(https?:\/\/)?(www\.)?((?!www)[a-z0-9][a-z0-9.-]*\.[a-z]{2,4})$/i);
  91. if (!isset(matches))
  92. return false;
  93. return (matches.length>=1);
  94. }
  95. function morph_age(age)
  96. {
  97. age = parseInt(age);
  98. if (isNaN(age) || age<1)
  99. return false;
  100. if (age>130)
  101. return false;
  102. return true;
  103. }
  104. function morph_date(date)
  105. {
  106. var matches = date.match(/^[0-9]{1,2}\-[0-9]{1,2}\-[0-9]{2,4}$/);
  107. if (!isset(matches))
  108. return false;
  109. if (matches.length!=1)
  110. return false;
  111. var spl = date.split('-');
  112. var day = parseInt(spl[0]);
  113. var month = parseInt(spl[1]);
  114. var year = parseInt(spl[2]);
  115. if (isNaN(day) || isNaN(month) || isNaN(year))
  116. return false;
  117. if (year<100)
  118. year = 1900+year;
  119. if (day<1 || day>31)
  120. return false;
  121. if (month<1 || month>12)
  122. return false;
  123. if (year<1900)
  124. return false;
  125. var d = new Date();
  126. if (year>d.getFullYear())
  127. return false;
  128. return true;
  129. }
  130. function validate_element(element)
  131. {
  132. var value_type;
  133. var value;
  134. var tag_name = element[0].tagName;
  135. if (isset(tag_name))
  136. tag_name = tag_name.toLowerCase();
  137. else
  138. {
  139. return 4;//depending element doesn't exist
  140. }
  141. //first, we need to check if the refered element is an input, or a div
  142. if (tag_name=='div' || tag_name=='fieldset')//so we have a div/fieldset, we need to scan it for the value
  143. {//thanks to nice naming, we can get to the input elements pretty easy
  144. if (element.find('input[type=radio], input[type=checkbox]').length)//it's a buttonset/fieldset full of inputs
  145. value = $('#'+element.attr('id')+' input:checked').val();
  146. }
  147. else//or else, it's simple stuff
  148. {
  149. value = element.val();
  150. if (tag_name=='input')
  151. {
  152. if ((element.attr('type')=='checkbox' || element.attr('type')=='radio') && !element.is(':checked'))//if we don't have the checked attribute on it, don't acknowledge
  153. value=null;//the result as being valid
  154. }
  155. }
  156. if (!isset(value))
  157. return 1;
  158. if (element.attr('xsd-type'))
  159. value_type = element.attr('xsd-type');
  160. else
  161. value_type = 'string';
  162. value_type = value_type.toLowerCase();
  163. switch(value_type)
  164. {
  165. case 'number':
  166. value = parseInt(value);
  167. if (!isset(value) || isNaN(value) || value<=0)
  168. return 1;
  169. break;
  170. case 'float':
  171. value = Number(value);
  172. if (!isset(value) || value<=0)
  173. return 1;
  174. //element.attr('xsd-allow','digits|.');//we force the xsd-allow attribute to digits|., since digits are the only thing we should be interested in
  175. break;
  176. case 'string':
  177. default:
  178. value = String(value);
  179. if (!isset(value) || !value.length)
  180. return 1;
  181. break;
  182. }//ok, that was validation against value type
  183. if (element.attr('xsd-length'))//this is validation against length
  184. {
  185. if (String(value).length!=parseInt(element.attr('xsd-length')))
  186. {
  187. return 2;
  188. }
  189. }
  190. if (element.attr('xsd-allow'))//watch this, it should be pretty good | validation against allowed/disallowed characters
  191. {
  192. var allowed_array = Array();//holds the allowed elements
  193. var v = element.attr('xsd-allow').split('|');//split against an unfamiliar character, like vertical bar, so we can allow spaces and other stuff in
  194. for (i=0;i<v.length;i++)
  195. {
  196. switch(v[i].toLowerCase())//in case somebody tries to validate against retarded stuff like DiGIts
  197. {
  198. case 'digits':
  199. for (j=0;j<10;j++)
  200. allowed_array.push(j);
  201. break;
  202. case 'alphanumeric':
  203. for (j=0;j<10;j++)
  204. allowed_array.push(j);
  205. case 'letters':
  206. for (j=asc('a');j<=asc('z');j++)
  207. allowed_array.push(chr(j));
  208. for (j=asc('A');j<=asc('Z');j++)
  209. allowed_array.push(chr(j));
  210. break;
  211. default:
  212. allowed_array.push(v[i]);
  213. break;
  214. }
  215. }
  216. value = String(value);//cast value to string, we don't need it anymore anyway
  217. for (i=0;i<value.length;i++)
  218. {
  219. var ch = value.charAt(i);
  220. found=false;
  221. for (j=0;j<allowed_array.length;j++)
  222. {
  223. if ( String(ch)==String(allowed_array[j]) )//found it
  224. {
  225. found=true;
  226. }
  227. }
  228. if (!found)
  229. return 3;
  230. }
  231. }
  232. if (element.attr('xsd-morph'))//this is validation against a certain shape(or morph);
  233. {//it calls the function morph_{xsd-morph}(value) which must return true(for valid shape) or false otherwise; more morphs can be added by adding more functions
  234. eval( 'var morph_ok = morph_'+element.attr('xsd-morph')+"('"+element.val()+"');" );
  235. if (!morph_ok)
  236. return 4;
  237. }
  238. return 0;//unix-style return code for OK, we're good
  239. }
  240. function validate_form(containerId, breakOnFirstError)//containerId is the id of the container which holds the elements, can be anything, from a form to a div
  241. {
  242. var validated = true;
  243. if (typeof breakOnFirstError=='undefined' || breakOnFirstError===null)
  244. breakOnFirstError = false;
  245. else
  246. breakOnFirstError = Boolean(breakOnFirstError);
  247. var msg = '';
  248. var container = $('#' + containerId);
  249. container.find('label.required').each(function()
  250. {
  251. if (!isset($(this).attr('for')) || !$(this).attr('for').length)
  252. return true;
  253. var element = $('#'+$(this).attr('for')).filter('select.styled-select, :visible');//we get the element refered in the for attribute of the label, and we make sure the element is visible,
  254. //we also select "select"s, which is a trick bypassing styled select's display none on the selects themselves
  255. //makes no sense trying to validate a hidden element. If the user couldn't see it to fill it with data, why would we validate it?
  256. if (!element.length)//so if the element doesn't exist, ignore it
  257. return true;
  258. var skip_validation=false;
  259. if (isset($(this).attr('xsd-skip')))
  260. skip_validation = true;
  261. if (!skip_validation && $(this).attr('xsd-depends'))
  262. {
  263. var depends = $(this).attr('xsd-depends');
  264. var negated = false;
  265. if (depends.trim().indexOf('!')==0)
  266. {
  267. negated= true;
  268. depends = depends.substr(1);
  269. }
  270. if ( !validate_element($('#'+ depends)) )
  271. skip_validation = negated;
  272. else
  273. skip_validation = !negated;
  274. }
  275. if (!skip_validation)
  276. {
  277. code = validate_element(element);//linux-style: 0 means success, others mean like following:
  278. if (code>0)
  279. {
  280. var str = $('label[for="'+element.attr('id')+'"]', container);
  281. if (str.find('.label_text').length)
  282. str = str.find('.label_text').html();
  283. else
  284. str = str.html();
  285. if (str.indexOf('<')!=-1)//get the text from char 0 until we find the first opening tag brace
  286. str = str.substr(0,str.indexOf('<'));//so we trim the string to the textnode only(cutting out the span)
  287. str = str.replace(':','').replace('_',' ').toLowerCase();
  288. if (msg.length)
  289. msg+='<br />';
  290. switch(code)
  291. {
  292. case 1://form field empty
  293. msg+='{$ERROR_VALIDATION_FIELD_EMPTY}'.replace('$1', str);
  294. break;
  295. case 2://form field doesn't have the required length(for fixed-length values)
  296. msg+='{$ERROR_VALIDATION_FIELD_WRONG_LENGTH}'.replace('$1', str);
  297. //'Campul "'+str+'" nu are lungimea corespunzatoare';
  298. break;
  299. case 3://form field has disallowed characters
  300. msg+='{$ERROR_VALIDATION_FIELD_INVALID_CHARACTERS}'.replace('$1',str);
  301. //Campul "'+str+'" contine caractere invalide';
  302. break;
  303. case 4://form field doesn't have the shape we wanted it to have
  304. msg+='{$ERROR_VALIDATION_FIELD_COMPLETED_FALSE}'.replace('$1',str);
  305. // Campul "'+str+'" nu este completat corespunzator';
  306. break;
  307. }
  308. validated=false;
  309. if (typeof _add_highlight_handler == 'function')
  310. _add_highlight_handler('error', element.attr('id'));
  311. //if we break on first error, then error and stop the iteration
  312. if (breakOnFirstError)
  313. return false;
  314. }
  315. }
  316. return true;
  317. });
  318. if (!validated)
  319. error(msg);
  320. return validated;//prevents the submit
  321. }