1(function (global) { 2 'use strict'; 3 4 var RULES = { 5 name: { min: 2, max: 70 }, 6 subject: { min: 10, max: 100 }, 7 message: { min: 20, max: 1500 } 8 }; 9 10 var FIELD_LABELS = { 11 name: 'Name', 12 subject: 'Subject', 13 message: 'Message' 14 }; 15 16 var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 17 18 function getRule(fieldName, overrides) { 19 var baseRule = RULES[fieldName] || {}; 20 var overrideRule = overrides && overrides[fieldName] ? overrides[fieldName] : {}; 21 22 return { 23 min: typeof overrideRule.min === 'number' ? overrideRule.min : baseRule.min, 24 max: typeof overrideRule.max === 'number' ? overrideRule.max : baseRule.max 25 }; 26 } 27 28 function toText(value) { 29 if (value === null || value === undefined) { 30 return ''; 31 } 32 return String(value).trim(); 33 } 34 35 function inRange(value, min, max) { 36 var len = toText(value).length; 37 return len >= min && len <= max; 38 } 39 40 function validateName(value, ruleOverrides) { 41 var text = toText(value); 42 var rule = getRule('name', ruleOverrides); 43 44 if (!inRange(text, rule.min, rule.max)) { 45 return 'Limit ' + rule.min + ' to ' + rule.max + ' characters.'; 46 } 47 return ''; 48 } 49 50 function validateEmail(value) { 51 var text = toText(value); 52 if (!EMAIL_REGEX.test(text)) { 53 return 'Please enter a valid email address.'; 54 } 55 return ''; 56 } 57 58 function validateRequired(value, fieldLabel) { 59 var text = toText(value); 60 if (!text.length) { 61 return 'Please enter your ' + fieldLabel + '.'; 62 } 63 return ''; 64 } 65 66 function validateSubject(value, required, ruleOverrides) { 67 var text = toText(value); 68 var rule = getRule('subject', ruleOverrides); 69 70 if (!required && text.length === 0) { 71 return ''; 72 } 73 if (!inRange(text, rule.min, rule.max)) { 74 return 'Limit ' + rule.min + ' to ' + rule.max + ' characters.'; 75 } 76 return ''; 77 } 78 79 function validateMessage(value, ruleOverrides) { 80 var text = toText(value); 81 var rule = getRule('message', ruleOverrides); 82 83 if (!inRange(text, rule.min, rule.max)) { 84 return 'Limit ' + rule.min + ' to ' + rule.max + ' characters.'; 85 } 86 return ''; 87 } 88 89 function getLimitMessage(fieldName, value, ruleOverrides) { 90 var fieldRule = getRule(fieldName, ruleOverrides); 91 var fieldLabel = FIELD_LABELS[fieldName]; 92 var text = toText(value); 93 94 if (!fieldRule || !fieldRule.max || !fieldLabel) { 95 return ''; 96 } 97 98 if (text.length >= fieldRule.max) { 99 return fieldLabel + ' character limit reached (' + fieldRule.max + ').'; 100 } 101 102 return ''; 103 } 104 105 function validateForm(values, options) { 106 var opts = options || {}; 107 var subjectRequired = !!opts.subjectRequired; 108 var ruleOverrides = opts.ruleOverrides || {}; 109 110 var errors = { 111 name: validateName(values && values.name, ruleOverrides), 112 email: validateEmail(values && values.email), 113 subject: validateSubject(values && values.subject, subjectRequired, ruleOverrides), 114 message: validateMessage(values && values.message, ruleOverrides) 115 }; 116 117 var isValid = !errors.name && !errors.email && !errors.subject && !errors.message; 118 119 return { 120 isValid: isValid, 121 errors: errors, 122 rules: { 123 name: getRule('name', ruleOverrides), 124 subject: getRule('subject', ruleOverrides), 125 message: getRule('message', ruleOverrides) 126 } 127 }; 128 } 129 130 function autoResizeTextarea(element) { 131 if (!element) return; 132 133 element.style.minHeight = '70px'; 134 element.style.height = 'auto'; 135 element.style.height = Math.max(element.scrollHeight, 70) + 'px'; 136 } 137 138 function initTextareaAutoResize(selector) { 139 var textareas = document.querySelectorAll(selector); 140 141 textareas.forEach(function(textarea) { 142 textarea.style.minHeight = '70px'; 143 textarea.style.overflowY = 'hidden'; 144 textarea.style.resize = 'none'; 145 146 // Auto-resize on input 147 textarea.addEventListener('input', function() { 148 autoResizeTextarea(this); 149 }); 150 151 // Initial resize 152 autoResizeTextarea(textarea); 153 }); 154 } 155 156 function setFieldError(fieldSelector, errSelector, message) { 157 if (!global.jQuery) { 158 return; 159 } 160 161 var $field = global.jQuery(fieldSelector); 162 var $error = global.jQuery(errSelector); 163 164 if (message) { 165 $field.addClass('field-error'); 166 $error.text(message).show(); 167 } else { 168 $field.removeClass('field-error'); 169 $error.text('').hide(); 170 } 171 } 172 173 function bindFieldClearOnInput(fieldErrorMap) { 174 if (!global.jQuery || !fieldErrorMap) { 175 return; 176 } 177
178 Object.keys(fieldErrorMap).forEach(function(fieldSelector) { 179 var errSelector = fieldErrorMap[fieldSelector]; 180 global.jQuery(fieldSelector).on('input', function() { 181 setFieldError(fieldSelector, errSelector, ''); 182 }); 183 }); 184 } 185 186 global.CommonFormValidation = { 187 rules: RULES, 188 validateName: validateName, 189 validateEmail: validateEmail, 190 validateRequired: validateRequired, 191 validateSubject: validateSubject, 192 validateMessage: validateMessage, 193 getLimitMessage: getLimitMessage, 194 validateForm: validateForm, 195 autoResizeTextarea: autoResizeTextarea, 196 initTextareaAutoResize: initTextareaAutoResize, 197 setFieldError: setFieldError, 198 bindFieldClearOnInput: bindFieldClearOnInput 199 }; 200})(window);
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.