(function () { /* -- Function to restrict French and English Charachters - By Razi --*/ $(document).ready(function() { const ALLOWED_CHARS_SET = 'a-zA-Z0-9À-ÿ\\s\\._~,\'"`\\-\\(\\)\\/&!?:;%@#$*+=\\[\\]{}<>«»'; const regexToRemoveInvalidChars = new RegExp(`[^${ALLOWED_CHARS_SET}]`, 'gu'); const excludedFields = [ // 'logical_name_of_legal_field', // 'logical_name_of_operating_field' ]; // This selector targets all text and textarea inputs on the form. $('input:text, textarea').on('input', function() { const $this = $(this); const logicalName = $this.attr('data-logicalname'); // Check if the field is in the exclusion list if (excludedFields.includes(logicalName)) { return; } const originalValue = $this.val(); const cleanedValue = originalValue.replace(regexToRemoveInvalidChars, ''); if (cleanedValue !== originalValue) { $this.val(cleanedValue); // alert("Only French and English characters are allowed."); const alertMessage = "Only French and English characters are allowed in the portal."; alert(alertMessage); // const message = ""; // validationMessage.text(message).show(); //alert(alertMessage); } }); }); /* -- END Function to restrict French and English Charachters - By Razi --*/ /* --- MaxLength Counter -- */ maxLengthTargets = `body > form textarea[maxlength]:not([readonly="readonly"]), body > form input[maxlength]:not([readonly="readonly"]), #mainContent > form textarea[maxlength]:not([readonly="readonly"]), #mainContent > form input[maxlength]:not([readonly="readonly"])`; const maxCharCounterTranslations = { remaining: { en: (remaining) => `${remaining} characters remaining`, fr: (remaining) => `${remaining} caractères restants` } }; let maxLengthInputs = document.querySelectorAll(maxLengthTargets); maxLengthInputs.forEach((input) => { let maxChar = input.getAttribute('maxlength'); let inputCounterDisplay = document.createElement('span'); inputCounterDisplay.classList.add('maxcharcounter'); inputCounterDisplay.setAttribute('aria-live', "polite"); // Announces character count but politely ie: only when idle and only the last instance let remainingNum = maxChar - input.value.length; let remainingText = maxCharCounterTranslations.remaining[LANG](remainingNum); inputCounterDisplay.innerHTML = `${remainingText}`; input.closest('.control').insertAdjacentElement('afterend', inputCounterDisplay); const MAX_CHAR_STRING = `Maximum ${maxChar} characters`; let srOnlyLabel = document.createElement('span'); srOnlyLabel.classList.add('sr-only'); srOnlyLabel.innerHTML = MAX_CHAR_STRING; input.label.appendChild(srOnlyLabel); let boundingControlCell = input.closest('.form-control-cell'); //Parent cell that nest if (boundingControlCell) { boundingControlCell.setAttribute('maxChar', maxChar); } input.addEventListener("input", updateCharCount); input.addEventListener("change", updateCharCount); function updateCharCount(eOrEl) { let target = eOrEl.target ? eOrEl.target : eOrEl; let remainingNum = maxChar - input.value.length; let remainingText = maxCharCounterTranslations.remaining[LANG](remainingNum); inputCounterDisplay.innerHTML = `${remainingText}`; } }); function LimitPaste(targetField, sourceEvent) { try { const selectionLength = GetSelectionLength(targetField); if (GetMaxLength(targetField) != null) { const currentFieldLength = targetField.value.length; const maximumFieldLength = parseInt(GetMaxLength(targetField)); const clipboardText = (window.clipboardData || sourceEvent.clipboardData).getData("Text"); const resultantLength = currentFieldLength + clipboardText.length - selectionLength; if (resultantLength > maximumFieldLength) { TriggerOverlimitFeedback(targetField); } } } catch {} sourceEvent.returnValue = true; return true; } function LimitInput(targetField, sourceEvent) { let inputAllowed = true; try { const selectionLength = parseInt(GetSelectionLength(targetField)); const currentFieldLength = targetField.value.length; const maximumFieldLength = parseInt(GetMaxLength(targetField)); if (maximumFieldLength != null) { const enteredKeystroke = window.event ? sourceEvent.keyCode : sourceEvent.which; const isCtrl = sourceEvent.ctrlKey || sourceEvent.metaKey; const isShortcut = isCtrl && ( enteredKeystroke === 65 || // Ctrl+A enteredKeystroke === 67 || // Ctrl+C enteredKeystroke === 88 || // Ctrl+X enteredKeystroke === 86 || // Ctrl+V enteredKeystroke === 90 // Ctrl+Z ); const isPermittedKeystroke = ( enteredKeystroke < 32 || // non-printables (enteredKeystroke >= 33 && enteredKeystroke <= 40) || // arrows enteredKeystroke === 46 // delete ); const isExceedingLimit = currentFieldLength + 1 > maximumFieldLength; const isAdditiveKeystroke = !isPermittedKeystroke && enteredKeystroke !== 8 && // backspace enteredKeystroke !== 46 && // delete !isShortcut; if (isAdditiveKeystroke && isExceedingLimit) { TriggerOverlimitFeedback(targetField); inputAllowed = false; } else { targetField.cell.classList.remove('overlimit'); } } } catch {} sourceEvent.returnValue = inputAllowed; return inputAllowed; } function TriggerOverlimitFeedback(targetField) { targetField.cell?.classList.add("overlimit"); setTimeout(() => targetField.cell?.classList.remove("overlimit"), 2000); DisplayOverlimitMessage(targetField, 'Maximum character limit reached.'); } function DisplayOverlimitMessage(targetField, message) { // screen reader region let region = document.getElementById("overlimit-announcer"); if (!region) { region = document.createElement("div"); region.id = "overlimit-announcer"; Object.assign(region.style, { position: "absolute", width: "1px", height: "1px", overflow: "hidden", clip: "rect(0 0 0 0)" }); region.setAttribute("aria-live", "polite"); region.setAttribute("role", "status"); document.body.appendChild(region); } region.textContent = message; // visual message let msgEl = targetField.parentElement.querySelector(".overlimit-msg"); if (!msgEl) { msgEl = document.createElement("div"); msgEl.className = "overlimit-msg"; Object.assign(msgEl.style, { color: "#d00", fontSize: "0.85em", top: "-16px", position: "relative" }); targetField.parentElement.appendChild(msgEl); } msgEl.textContent = message; msgEl.style.display = "block"; clearTimeout(msgEl._hideTimer); msgEl._hideTimer = setTimeout(() => msgEl.style.display = "none", 2000); } const style = document.createElement('style'); style.textContent = ` .cell.overlimit .control{ animation: shake 0.4s ease-in-out forwards; } @keyframes shake { 0% { transform: translateX(0); } 25% { transform: translateX(-5px); } 50% { transform: translateX(5px); } 75% { transform: translateX(-5px); } 100% { transform: translateX(0); } } .cell.overlimit .control textarea { --border-color: var(--gcds-input-danger-border)!important; --outline-color: var(--gcds-input-danger-border)!important; } `; document.head.appendChild(style); })();