1export function validation(formId, showAlert = true, keepMask = false) { 2 let result = { 3 status: false, 4 msg: '', 5 data: {}, 6 }; 7 const $form = $("#" + formId); 8 $form.find('[aria-invalid]').removeAttr('aria-invalid'); 9 let isPrint = $form.attr('data-print') ? true : false; 10 if (isPrint) { 11 $(".__error-msg").remove(); 12 $form.find('[aria-errormessage]').removeAttr('aria-errormessage'); 13 } 14 if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances) { 15 for (let instance in CKEDITOR.instances) { 16 CKEDITOR.instances[instance].updateElement(); 17 } 18 } 19 let formData = new FormData($form[0]); 20 const key = $form.attr("data-validation"); 21 if (!key) { 22 return true; 23 } 24 const edit = $("#edit").val() == 1 ? 1 : 0; 25 formData.append('key', key); 26 formData.append('edit', edit); 27 formData.append('lang', langCode); 28 $.ajax({ 29 type: 'post', 30 async: false, 31 url: base_url + '/action/validation', 32 data: formData, 33 processData: false, 34 contentType: false, 35 dataType: "json", 36 success: function (data) { 37 result.status = data.status; 38 result.data = data; 39 if (!result.status && showAlert) { 40 result.msg = data.data; 41 printErrorMsg(formId, data.data, isPrint); 42 if (keepMask) $("#" + loaderID).remove(); 43 } 44 }, 45 error: function (result) { 46 nx.alert("Error", 'DB', 'e'); 47 return false; 48 }, 49 }); 50 return result; 51} 52 53export function initValidation() { 54 55 // Keyup : text, tel, Email 56 $("form[data-validation]").on('input', '.__renew-validation-text', function () { 57 const $wrap = $(this).closest('.__input-wrap'); 58 $wrap.find('.__renew-validation-text') 59 .removeAttr('aria-invalid') 60 .removeAttr('aria-errormessage') 61 .removeClass('__renew-validation-text'); 62 $wrap.removeClass('fail'); 63 $wrap.parent().find('.__error-msg').remove(); 64 }); 65 66 // Change : Select, File 67 $("form[data-validation]").on('change', '.__renew-validation-change', function () { 68 $(this).removeAttr('aria-invalid') 69 .removeAttr('aria-errormessage') 70 .removeClass('__renew-validation-change'); 71 const $wrap = $(this).closest('.__input-wrap'); 72 $wrap.removeClass('fail'); 73 $wrap.parent().find('.__error-msg').remove(); 74 }); 75 76 // Click : Radio, Checkbox 77 $("form[data-validation]").on('click', '.__renew-validation-click', function () { 78 const $wrap = $(this).closest('.__input-wrap'); 79 $wrap.find('.__renew-validation-click') 80 .removeAttr('aria-invalid') 81 .removeAttr('aria-errormessage') 82 .removeClass('__renew-validation-click'); 83 $wrap.removeClass('fail'); 84 $wrap.parent().find('.__error-msg').remove(); 85 }); 86 87 // Submit 88 $("form[data-validation]").on("submit", function () { 89 const formId = $(this).attr('id'); 90 addLoader(); 91 let result = validation(formId); 92 removeLoader(); 93 return result.status; 94 }); 95} 96 97export function printErrorMsg(formId, data, isPrint) { 98 let msg = []; 99 let $firstTarget; 100 Object.keys(data).forEach(key => { 101 let value = data[key]; 102 let $target; 103 if ($("#" + formId + " [name=" + key + "]").length == 0) { 104 $target = $("#" + formId + " [name='" + key + "[]']"); 105 } else { 106 $target = $("#" + formId + " [name=" + key + "]"); 107 } 108 let type = $target.attr('type'); 109 if (type === undefined) { 110 if ($target.is('select')) { 111 type = 'select'; 112 } 113 else if ($target.is('textarea')) { 114 if ($target.hasClass('__ckeditor')) { 115 type = 'ckeditor'; 116 } else { 117 type = 'textarea'; 118 } 119 } 120 } 121 else if (type === 'hidden') { 122 const inputType = $target.attr('data-input-type'); 123 if (inputType) type = inputType; 124 } 125 if ($target.hasClass('__date-pick')) { 126 type = 'date_pick'; 127 } 128 else if ($target.hasClass('__agree')) { 129 type = 'agree'; 130 } 131 132 const $wrap = $target.closest('.__input-wrap'); 133 if (value.includes('%s')) { 134 const $label = $target.closest('.__item').find(".__label"); 135 value = value.replace('%s', $label.text()); 136 } 137 msg.push(value); 138 139 // Radio, Checkbox 140 if (type == 'radio' || type == 'checkbox' || type == 'agree') { 141 $target.addClass('__renew-validation-click'); 142 $target.attr('aria-invalid', 'true'); 143 if (isPrint) $target.attr('aria-errormessage', 'msg_' + key); 144 } 145 146 // Select, DatePick 147 else if (type == 'select' || type == 'date_pick') { 148 $target.addClass('__renew-validation-change'); 149 $target.attr('aria-invalid', 'true'); 150 if (isPrint) $target.attr('aria-errormessage', 'msg_' + key); 151 } 152 153 // Email Form , Tel Form 154 else if (type == 'email_form' || type == 'tel_form') { 155 const $inputWrap = $wrap.find('input[type=text], input[type=tel]'); 156 $inputWrap.addClass('__renew-validation-text'); 157 $inputWrap.attr('aria-invalid', 'true'); 158 if (isPrint) $inputWrap.attr('aria-errormessage', 'msg_' + key); 159 } 160 161 // File 162 else if (type == 'file') { 163 const $files = $target.siblings('.__file'); 164 $files.addClass('__renew-validation-change'); 165 $files.attr('aria-invalid', 'true'); 166 if (isPrint) $target.attr('aria-errormessage', 'msg_' + key); 167 } 168 169 // Text, Email, Tel, textarea 170 else { 171 $target.addClass('__renew-validation-text'); 172 $target.attr('aria-invalid', 'true'); 173 if (isPrint) $target.attr('aria-errormessage', 'msg_' + key); 174 } 175 $wrap.addClass('fail'); 176 177 // Print 178 if (isPrint) { 179 const errorMsg = `<em id="msg_${key}" class="error-msg __error-msg" role="alert" aria-live="assertive">${value}</em>`; 180 $wrap.parent().append(errorMsg); 181 } 182 if (!$firstTarget) $firstTarget = $target; 183 }); 184 185 // Focus 186 let focus = false;
187 188 if ($firstTarget.attr('type') == 'hidden') { 189 190 // Email Form 191 if ($firstTarget.attr('data-input-type') == 'email_form') { 192 const $email = $firstTarget.closest('.__input-wrap').find('input[type=text]'); 193 if ($email[0].value.length == 0) { 194 focus = '#' + $($email[0]).attr('id'); 195 } else if ($email[1].value.length == 0) { 196 focus = '#' + $($email[1]).attr('id'); 197 } else { 198 focus = '#' + $($email[0]).attr('id'); 199 } 200 } 201 // Tel Form 202 else if ($firstTarget.attr('data-input-type') == 'tel_form') { 203 const $tel = $firstTarget.closest('.__input-wrap').find('input[type=tel]'); 204 if ($tel[0].value.length == 0) { 205 focus = '#' + $($tel[0]).attr('id'); 206 } else if ($tel[1].value.length == 0) { 207 focus = '#' + $($tel[1]).attr('id'); 208 } else if ($tel[2].value.length == 0) { 209 focus = '#' + $($tel[2]).attr('id'); 210 } else { 211 focus = '#' + $($tel[0]).attr('id'); 212 } 213 } else { 214 const $firstInput = $firstTarget.closest('.__input-wrap').find('input').first(); 215 if ($firstInput.length > 0) { 216 focus = '#' + $firstInput.attr('id'); 217 } 218 } 219 } else if ($firstTarget.hasClass('__ckeditor')) { 220 const id = $firstTarget.attr('id'); 221 focus = CKEDITOR.instances[id]; 222 } else { 223 focus = '#' + $firstTarget.attr('id'); 224 } 225 226 // Alert 227 nx.alert("Error", msg.join('<br>'), 'e', false, focus); 228}
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.