1/** 2 * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> 3 * @license GNU General Public License version 2 or later; see LICENSE.txt 4 */ 5 6/** 7 * Unobtrusive Form Validation library 8 * 9 * Inspired by: Chris Campbell <www.particletree.com> 10 * 11 * @since 1.5 12 */ 13var JFormValidator = function() { 14 "use strict"; 15 var handlers, inputEmail, custom, 16 17 setHandler = function(name, fn, en) { 18 en = (en === '') ? true : en; 19 handlers[name] = { 20 enabled : en, 21 exec : fn 22 }; 23 }, 24 25 findLabel = function(id, form){ 26 var $label, $form = jQuery(form); 27 if (!id) { 28 return false; 29 } 30 $label = $form.find('#' + id + '-lbl'); 31 if ($label.length) { 32 return $label; 33 } 34 $label = $form.find('label[for="' + id + '"]'); 35 if ($label.length) { 36 return $label; 37 } 38 return false; 39 }, 40 41 handleResponse = function(state, $el) { 42 // Get a label 43 var $label = $el.data('label'); 44 if ($label === undefined) { 45 $label = findLabel($el.attr('id'), $el.get(0).form); 46 $el.data('label', $label); 47 } 48 49 // Set the element and its label (if exists) invalid state 50 if (state === false) { 51 $el.addClass('invalid').attr('aria-invalid', 'true'); 52 if ($label) { 53 $label.addClass('invalid'); 54 } 55 } else { 56 $el.removeClass('invalid').attr('aria-invalid', 'false'); 57 if ($label) { 58 $label.removeClass('invalid'); 59 } 60 } 61 }, 62 63 validate = function(el) { 64 var $el = jQuery(el), tagName, handler; 65 // Ignore the element if its currently disabled, because are not submitted for the http-request. For those case return always true. 66 if ($el.attr('disabled')) { 67 handleResponse(true, $el); 68 return true; 69 } 70 // If the field is required make sure it has a value 71 if ($el.attr('required') || $el.hasClass('required')) { 72 tagName = $el.prop("tagName").toLowerCase(); 73 if (tagName === 'fieldset' && ($el.hasClass('radio') || $el.hasClass('checkboxes'))) { 74 if (!$el.find('input:checked').length){ 75 handleResponse(false, $el); 76 return false; 77 } 78 //If element has class placeholder that means it is empty. 79 } else if (!$el.val() || $el.hasClass('placeholder') || ($el.attr('type') === 'checkbox' && !$el.is(':checked'))) { 80 handleResponse(false, $el); 81 return false; 82 } 83 } 84 // Only validate the field if the validate class is set 85 handler = ($el.attr('class') && $el.attr('class').match(/validate-([a-zA-Z0-9\_\-]+)/)) ? $el.attr('class').match(/validate-([a-zA-Z0-9\_\-]+)/)[1] : ""; 86 87 // Try HTML5 pattern first then the handlers 88 if ($el.attr('pattern') && $el.attr('pattern') != '') { 89 if ($el.val().length) { 90 var isValid = new RegExp('^'+$el.attr('pattern')+'$').test($el.val()); 91 handleResponse(isValid, $el); 92 return isValid; 93 } 94 if ($el.attr('required') || $el.hasClass('required')) { 95 handleResponse(false, $el); 96 return false; 97 } 98 handleResponse(true, $el); 99 return true; 100 } else { 101 if (handler === '') { 102 handleResponse(true, $el); 103 return true; 104 } 105 // Check the additional validation types 106 if ((handler) && (handler !== 'none') && (handlers[handler]) && $el.val()) { 107 // Execute the validation handler and return result 108 if (handlers[handler].exec($el.val(), $el) !== true) { 109 handleResponse(false, $el); 110 return false; 111 } 112 } 113 // Return validation state 114 handleResponse(true, $el); 115 return true; 116 } 117 }, 118 119 isValid = function(form) { 120 var fields, valid = true, message, error, label, invalid = [], i, l; 121 122 // Validate form fields 123 fields = jQuery(form).find('input, textarea, select, fieldset'); 124 for (i = 0, l = fields.length; i < l; i++) { 125 // Ignore Rule/Filters/Assigned field for spead up validation 126 // And other fields that has class="novalidate" 127 if(jQuery(fields[i]).hasClass('novalidate')) { 128 continue; 129 } 130 if (validate(fields[i]) === false) { 131 valid = false; 132 invalid.push(fields[i]); 133 } 134 } 135 136 // Run custom form validators if present 137 jQuery.each(custom, function(key, validator) { 138 if (validator.exec() !== true) { 139 valid = false;
140 } 141 }); 142 143 if (!valid && invalid.length > 0) { 144 message = Joomla.JText._('JLIB_FORM_FIELD_INVALID'); 145 error = {"error": []}; 146 for (i = invalid.length - 1; i >= 0; i--) { 147 label = jQuery(invalid[i]).data("label"); 148 if (label) { 149 error.error.push(message + label.text().replace("*", "")); 150 } 151 } 152 Joomla.renderMessages(error); 153 } 154 return valid; 155 }, 156 157 attachToForm = function(form) { 158 var inputFields = [], elements, 159 $form = jQuery(form); 160 // Iterate through the form object and attach the validate method to all input fields. 161 elements = $form.find('input, textarea, select, fieldset, button'); 162 for (var i = 0, l = elements.length; i < l; i++) { 163 var $el = jQuery(elements[i]), tagName = $el.prop("tagName").toLowerCase(); 164 // Attach isValid method to submit button 165 if ((tagName === 'input' || tagName === 'button') && ($el.attr('type') === 'submit' || $el.attr('type') === 'image')) { 166 if ($el.hasClass('validate')) { 167 $el.on('click', function() { 168 return isValid(form); 169 }); 170 } 171 } 172 // Attach validate method only to fields 173 else if (tagName !== 'button' && !(tagName === 'input' && $el.attr('type') === 'button')) { 174 if ($el.hasClass('required')) { 175 $el.attr('aria-required', 'true').attr('required', 'required'); 176 } 177 if (tagName !== 'fieldset') { 178 $el.on('blur', function() { 179 return validate(this); 180 }); 181 if ($el.hasClass('validate-email') && inputEmail) { 182 elements[i].setAttribute('type', 'email'); 183 } 184 } 185 inputFields.push($el); 186 } 187 } 188 $form.data('inputfields', inputFields); 189 }, 190 191 initialize = function() { 192 handlers = {}; 193 custom = custom || {}; 194 195 inputEmail = (function() { 196 var input = document.createElement("input"); 197 input.setAttribute("type", "email"); 198 return input.type !== "text"; 199 })(); 200 // Default handlers 201 setHandler('username', function(value, element) { 202 var regex = new RegExp("[\<|\>|\"|\'|\%|\;|\(|\)|\&]", "i"); 203 return !regex.test(value); 204 }); 205 setHandler('password', function(value, element) { 206 var regex = /^\S[\S ]{2,98}\S$/; 207 return regex.test(value); 208 }); 209 setHandler('numeric', function(value, element) { 210 var regex = /^(\d|-)?(\d|,)*\.?\d*$/; 211 return regex.test(value); 212 }); 213 setHandler('email', function(value, element) { 214 value = punycode.toASCII(value); 215 var regex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; 216 return regex.test(value); 217 }); 218 // Attach to forms with class 'form-validate' 219 var forms = jQuery('form.form-validate'); 220 for (var i = 0, l = forms.length; i < l; i++) { 221 attachToForm(forms[i]); 222 } 223 }; 224 225 // Initialize handlers and attach validation to form 226 initialize(); 227 228 return { 229 isValid : isValid, 230 validate : validate, 231 setHandler : setHandler, 232 attachToForm : attachToForm, 233 custom: custom 234 }; 235}; 236 237document.formvalidator = null; 238jQuery(function() { 239 document.formvalidator = new JFormValidator(); 240});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.