1 2$(document).ready(function () { 3 function debounce(func, delay) { 4 let timer; 5 return function (...args) { 6 const context = this; 7 clearTimeout(timer); 8 timer = setTimeout(() => func.apply(context, args), delay); 9 }; 10 } 11 12 function clearFieldError(fieldId) { 13 const field = $(`#${fieldId}`); 14 field.removeClass('is-invalid'); 15 field.next('.field-validation-error').remove(); 16 field.closest('.iti').next('.field-validation-error').remove(); 17 field.closest('.mb-3').find('.field-validation-error').remove(); 18 } 19 20 function showFieldError(fieldId, message) { 21 clearFieldError(fieldId); 22 const field = $(`#${fieldId}`); 23 field.addClass('is-invalid'); 24 const itiContainer = field.closest('.iti'); 25 const target = itiContainer.length ? itiContainer : field; 26 $(`<span class="text-danger field-validation-error d-block mt-1">${message}</span>`).insertAfter(target); 27 } 28 29 // Username validation 30 function checkUsername() { 31 const userName = $('#UserName').val()?.trim(); 32 33 if (!userName) { 34 clearFieldError('UserName'); 35 return; 36 } 37 38 $.ajax({
39 type: "POST", 40 url: '/Admin/UserManagement/CheckUsernameExists', 41 data: JSON.stringify({ UserName: userName }), 42 contentType: "application/json", 43 success: function (response) { 44 clearFieldError('UserName'); 45 if (response.error) { 46 showFieldError('UserName', response.error); 47 } else if (response.exists) { 48 showFieldError('UserName', 'This username is already taken.'); 49 } 50 }, 51 error: function () { 52 console.error('Error checking username'); 53 } 54 }); 55 } 56 57 // Mobile validation 58 function checkMobile() { 59 const mobileNumber = $('#MobileNumber').val()?.trim(); 60 const countryId = $('#countryIdInput').val(); 61 62 if (!mobileNumber) { 63 clearFieldError('MobileNumber'); 64 return; 65 } 66 67 if (!countryId || countryId === "0") { 68 // country not resolved yet â nothing to check against 69 return; 70 } 71 72 $.ajax({
73 type: "POST", 74 url: '/Admin/UserManagement/CheckMobileExists', 75 data: JSON.stringify({ MobileNumber: mobileNumber, CountryId: countryId }), 76 contentType: "application/json", 77 success: function (response) { 78 clearFieldError('MobileNumber'); 79 if (response.error) { 80 showFieldError('MobileNumber', response.error); 81 } else if (response.exists) { 82 showFieldError('MobileNumber', 'This mobile number is already registered.'); 83 } 84 }, 85 error: function () { 86 console.error('Error checking mobile number'); 87 } 88 }); 89 } 90 91 // Email validation 92 function checkEmail() { 93 const emailId = $('#EmailId').val()?.trim(); 94 95 if (!emailId) { 96 clearFieldError('EmailId'); 97 return; 98 } 99 100 $.ajax({ 101 type: "POST", 102 url: '/Admin/UserManagement/CheckEmailExists', 103 data: JSON.stringify({ EmailId: emailId }), 104 contentType: "application/json", 105 success: function (response) { 106 clearFieldError('EmailId'); 107 if (response.exists) { 108 showFieldError('EmailId', 'This email is already registered.'); 109 } 110 }, 111 error: function () { 112 console.error('Error checking email'); 113 } 114 }); 115 } 116 117 // Debounced functions 118 const debouncedCheckUsername = debounce(checkUsername, 600); 119 const debouncedCheckMobile = debounce(checkMobile, 600); 120 const debouncedCheckEmail = debounce(checkEmail, 600); 121 122 // Event bindings - each field handles its own validation 123 $('#UserName').on('blur', checkUsername).on('input', debouncedCheckUsername); 124 $('#MobileNumber').on('blur', checkMobile).on('input', debouncedCheckMobile); 125 $('#EmailId').on('blur', checkEmail).on('input', debouncedCheckEmail); 126}); 127 128 129document.addEventListener('DOMContentLoaded', function () { 130 // Select2 for products dropdown 131 $('#ddlProducts').select2({ 132 placeholder: "Select products", 133 allowClear: true 134 }); 135 136 // const passwordInput = document.getElementById('NewPassword'); 137 // const passwordToggleCheck = document.querySelector('.password-toggle-check'); 138 // const passwordIndicator = document.querySelector('.password-indicator i'); 139 140 // passwordToggleCheck.addEventListener('change', function () { 141 // if (passwordToggleCheck.checked) { 142 // passwordInput.type = 'text'; 143 // passwordIndicator.classList.remove('fa-eye'); 144 // passwordIndicator.classList.add('fa-eye-slash'); 145 // } else { 146 // passwordInput.type = 'password'; 147 // passwordIndicator.classList.remove('fa-eye-slash'); 148 // passwordIndicator.classList.add('fa-eye'); 149 // } 150 // }); 151 152 // // Add an event listener to the label to toggle the checkbox 153 // document.querySelector('.password-toggle-btn').addEventListener('click', function () { 154 // passwordToggleCheck.checked = !passwordToggleCheck.checked; 155 // passwordToggleCheck.dispatchEvent(new Event('change')); 156 // }); 157 158 const password = document.getElementById("NewPassword"); 159 const email = document.getElementById("EmailId"); 160 const role = document.getElementById("RoleId"); 161 const products = document.getElementById("ddlProducts"); 162 163 const passwordRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@@#$%^&*()_+\\-=\\[\\]{};:<>|./?,-]).{8,15}$"); 164 165 function validatePassword() { 166 if (password.value && !passwordRegex.test(password.value)) { 167 showError(password, "Password must be 8â15 characters, include uppercase, lowercase, number, and special character."); 168 } else { 169 clearError(password); 170 } 171 } 172 173 function validateEmail() { 174 if (email.value === "") { 175 showError(email, "Please enter a valid email address."); 176 } else { 177 clearError(email); 178 } 179 } 180 181 function validateRole() { 182 if (role.value === "") { 183 showError(role, "Please select an account type."); 184 } else { 185 clearError(role); 186 } 187 } 188 189 function validateProducts() { 190 if ([...products.selectedOptions].length === 0) { 191 showError(products, "Please select at least one product."); 192 } else { 193 clearError(products); 194 } 195 } 196 197 // Event listeners for interaction 198 password.addEventListener("blur", validatePassword); 199 password.addEventListener("input", validatePassword); 200 201 email.addEventListener("blur", validateEmail); 202 email.addEventListener("input", validateEmail); 203 204 role.addEventListener("change", validateRole); 205 206 products.addEventListener("change", validateProducts); 207}); 208 209function showError(element, message) { 210 const parent = element.closest(".mb-3") || element.parentElement; 211 let errorSpan = parent.querySelector(".text-danger"); 212 213 if (!errorSpan) { 214 errorSpan = document.createElement("span"); 215 errorSpan.className = "text-danger"; 216 parent.appendChild(errorSpan); 217 } 218 219 errorSpan.textContent = message; 220 element.classList.add("is-invalid"); 221} 222 223function clearError(element) { 224 const parent = element.closest(".mb-3") || element.parentElement; 225 const errorSpan = parent.querySelector(".text-danger"); 226 227 if (errorSpan) errorSpan.textContent = ""; 228 element.classList.remove("is-invalid"); 229} 230 231function clearErrors() { 232 document.querySelectorAll(".text-danger").forEach(el => el.textContent = ""); 233 document.querySelectorAll(".form-control").forEach(el => el.classList.remove("is-invalid")); 234}
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.