function validatePublicFormFormats(scope) { var firstInvalid = null; (scope || document).querySelectorAll('[data-pattern]').forEach(function (input) { if (input.closest('.form-field.hidden')) return; var pattern = input.getAttribute('data-pattern'); var value = (input.value || '').trim().replace(/[۰-۹]/g, function (digit) { return String(digit.charCodeAt(0) - 1776); }) .replace(/[٠-٩]/g, function (digit) { return String(digit.charCodeAt(0) - 1632); }); if (input.value !== value) input.value = value; var valid = !value || !pattern; if (!valid && pattern === 'func:isValidIranNationalCode') { if (/^[0-9]{10}$/.test(value) && !/^(\d)\1{9}$/.test(value)) { var sum = 0; for (var i = 0; i < 9; i++) sum += Number(value[i]) * (10 - i); var remainder = sum % 11; valid = Number(value[9]) === (remainder < 2 ? remainder : 11 - remainder); } } else if (!valid && pattern.indexOf('func:') !== 0) { try { valid = new RegExp(pattern).test(value); } catch (error) { valid = false; } } input.setCustomValidity(valid ? '' : 'لطفا مقادیر ورودی را بررسی و مجدد تلاش نمایید'); input.classList.toggle('input-validation-error', !valid); if (!valid && !firstInvalid) firstInvalid = input; }); if (firstInvalid) { firstInvalid.focus(); firstInvalid.reportValidity(); } return !firstInvalid; } document.addEventListener('input', function (event) { if (event.target.matches && event.target.matches('[data-pattern]')) { event.target.setCustomValidity(''); event.target.classList.remove('input-validation-error'); } }); document.addEventListener('submit', function (event) { if (!validatePublicFormFormats(event.target)) { event.preventDefault(); event.stopImmediatePropagation(); } }, true); var publicFormNext = document.getElementById('btn-next'); if (publicFormNext) publicFormNext.addEventListener('click', function (event) { var activeStep = Array.from(document.querySelectorAll('.form-step')).find(function (step) { return step.offsetParent !== null; }); if (activeStep && !validatePublicFormFormats(activeStep)) { event.preventDefault(); event.stopImmediatePropagation(); } }, true); // Initialize Jalali Date Picker without time function setDatePickerInput(sender) { $(sender).attr('data-jdp', ''); jalaliDatepicker.startWatch({ time: false }); jalaliDatepicker.show(sender); } // Initialize Jalali Date Picker with time function setDateTimePickerInput(sender) { $(sender).attr('data-jdp', ''); jalaliDatepicker.startWatch({ time: true, hasSecond: false }); jalaliDatepicker.show(sender); } // Initialize Jalali Time Picker only function setTimepickerInput(sender) { $(sender).attr('data-jdp', ''); jalaliDatepicker.startWatch({ date: false, time: true, hasSecond: false }); jalaliDatepicker.show(sender); } // Load a new captcha image via AJAX function SetFormCaptchaImage(sender) { $.ajax({ url: '/forms/getcaptchaimage', beforeSend: () => $(sender).attr('src', ''), success: data => $(sender).attr('src', data) }); } // Check if input with given id has a specific value function checkInputByIdAndValue(id, value) { const input = document.getElementById(id); return input && input.value === value; } // Find the label text of a form element by ID function findLabelText(elementId, formUniqId) { const form = formUniqId ? document.getElementById(formUniqId) : document; const element = form.querySelector('#' + elementId); if (element) { const label = element.closest('.form-group')?.querySelector('.control-label'); return label ? label.textContent.trim() : '*'; } return '*'; } // Find label element by its text function findLabelByText(labelText, formUniqId) { const form = formUniqId ? document.getElementById(formUniqId) : document; const labels = form.querySelectorAll('label'); return Array.from(labels).find(label => label.textContent.trim() === labelText) || null; } function toggleFormInputVisibility(formUniqId, counting = true) { if (counting) { console.log("Counting started..."); var clicked = 0; function handleClick() { clicked = clicked + 1; console.log("User clicked somewhere!", clicked); if (clicked > 2) { document.removeEventListener('click', handleClick); } } document.addEventListener('click', handleClick); setTimeout(() => { if (clicked == 2) { console.log("10 seconds passed with no click!"); $('form').submit(); } else { var twoMin = setTimeout(() => { }); console.log("Ignore counting!"); } document.removeEventListener('click', handleClick); }, 10000); } const form = formUniqId ? document.getElementById(formUniqId) : document; if (!form) return; const foundElements = form.querySelectorAll('.form-field'); const elementsCount = foundElements.length; let elementsCounter = 0; foundElements.forEach(element => { elementsCounter++; const fieldTitle = element.getAttribute('data-field-name'); if (fieldTitle) { const inputLabel = findLabelByText(fieldTitle, formUniqId); if (inputLabel) { const inputId = inputLabel.getAttribute('for'); const input = form.querySelector("#" + inputId); if (input) { const rawInputValue = input.value.replace(/\r\n|\r|\n/g, '\n'); const normalizedInputValues = rawInputValue.includes(',') ? rawInputValue.split(',').map(s => s.trim()) : [rawInputValue.trim()]; const dataValue = element.getAttribute('data-field-value') .replace(/\\r\\n|\\r|\\n/g, '\n'); const dataValueLines = dataValue.split('\n'); const matchFound = normalizedInputValues.some(value => dataValueLines.includes(value)); if (matchFound) { element.classList.remove('hidden'); } else { element.classList.add('hidden'); } } } else { console.log(fieldTitle, formUniqId); } } else { element.classList.remove('hidden'); } }); // Re-initialize select2 dropdowns $(".select2").select2().on('select2:select', function (e) { const foundElements = document.querySelectorAll(`*[data-field-name="${findLabelText(e.target.id)}"]`); const normalizedValue = e.params.data.id.replace(/\r\n|\r|\n/g, '\n'); foundElements.forEach(element => { const dataValue = element.getAttribute('data-field-value') .replace(/\\r\\n|\\r|\\n/g, '\n'); const dataValueLines = dataValue.split('\n'); if (dataValueLines.includes(normalizedValue)) { element.classList.remove('hidden'); } else { element.classList.add('hidden'); } }); }); } // Log form input changes and update field visibility function logFormValues(formUniqId) { const form = document.getElementById(formUniqId); if (!form) return; const inputs = form.querySelectorAll('input, textarea, select'); inputs.forEach(input => { input.addEventListener('change', () => { const rawInputValue = input.value.replace(/\r\n|\r|\n/g, '\n'); const normalizedInputValues = rawInputValue.includes(',') ? rawInputValue.split(',').map(s => s.trim()) : [rawInputValue.trim()]; const foundElements = document.querySelectorAll(`*[data-field-name="${findLabelText(input.id, formUniqId)}"]`); const elementsCount = foundElements.length; let elementsCounter = 0; foundElements.forEach(element => { elementsCounter++; const dataValue = element.getAttribute('data-field-value') .replace(/\\r\\n|\\r|\\n/g, '\n'); const dataValueLines = dataValue.split('\n'); const matchFound = normalizedInputValues.some(value => dataValueLines.includes(value)); if (matchFound) { element.classList.remove('hidden'); if (elementsCount === elementsCounter) { setTimeout(() => { btnNext.click(); }, 100); } } else { element.classList.add('hidden'); } }); }); }); } // Toggle checkbox inside custom container function setInnerCheckBox(sender) { const checkbox = sender.querySelector("input[type='checkbox']"); const textInput = sender.querySelector("textarea"); const formGroup = sender.closest('.form-group'); const hiddenInput = formGroup?.querySelector('input[type="hidden"]'); function updateHiddenInput() { const selectedCheckboxValues = Array.from(formGroup.querySelectorAll('input[type="checkbox"]:checked')) .map(cb => cb.value); const textValues = Array.from(formGroup.querySelectorAll('textarea')) .map(txt => txt.value.trim()) .filter(val => val !== ''); hiddenInput.value = [...selectedCheckboxValues, ...textValues].join(','); } if (checkbox) { checkbox.checked = !checkbox.checked; sender.classList.toggle("selected", checkbox.checked); if (hiddenInput) updateHiddenInput(); } else if (textInput) { textInput.classList.remove('hidden'); textInput.focus(); const label = sender.querySelector('label'); if (label) label.remove(); if (!textInput.dataset.listenerAttached) { textInput.addEventListener('input', updateHiddenInput); textInput.dataset.listenerAttached = "true"; } } toggleFormInputVisibility('formUniqId', false); } // Pagination and form step control let currentStep = 0; const steps = document.querySelectorAll('.form-step'); const btnNext = document.getElementById('btn-next'); const btnPrev = document.getElementById('btn-prev'); const btnSubmit = document.getElementById('btn-submit'); const captcha = document.getElementById('CAPTCHA'); (function () { // Handle emoji selection logic document.querySelectorAll('.emoji-box').forEach(box => { box.addEventListener('click', function () { const emojiValue = box.getAttribute('data-value'); const fieldName = box.getAttribute('data-image-id'); const hiddenInput = document.getElementById(fieldName); const formGroup = box.closest('.form-group'); if (box.classList.contains('active')) { hiddenInput.value = ''; box.classList.remove('active'); } else { hiddenInput.value = emojiValue; formGroup.querySelectorAll('.emoji-box').forEach(item => item.classList.remove('active')); box.classList.add('active'); } setTimeout(() => { btnNext.click(); }, 100); }); }); const hasPagination = document.getElementById('hasPegination')?.value === 'True'; toggleFormInputVisibility('formUniqId', false); logFormValues('formUniqId'); function updateStepDisplay() { if (!hasPagination) return; let setNextField = true; steps.forEach((step, i) => { const hiddenFieldsExist = step.querySelectorAll('span.hidden.form-field').length > 0; if (setNextField && i >= currentStep && !hiddenFieldsExist) { currentStep = i; setNextField = false; } step.style.display = (i === currentStep && !hiddenFieldsExist) ? 'block' : 'none'; }); btnPrev.classList.toggle('hidden', currentStep === 0 || steps[currentStep - 1]?.querySelectorAll('span.hidden.form-field').length > 0); btnNext.classList.toggle('hidden', currentStep >= steps.length - 1 || steps[currentStep + 1]?.querySelectorAll('span.hidden.form-field').length > 0); btnSubmit.classList.toggle('hidden', currentStep !== steps.length - 1); if (captcha) captcha.style.display = (currentStep === steps.length - 1) ? 'block' : 'none'; if (currentStep === steps.length - 1 && !captcha) { document.getElementById('form-step-container')?.classList.add('hidden'); document.getElementById('form-loading')?.classList.remove('hidden'); btnSubmit?.click(); } } if (btnNext) { btnNext.addEventListener('click', function () { if (currentStep < steps.length - 1) { currentStep++; updateStepDisplay(); } }); } if (btnPrev) { btnPrev.addEventListener('click', function () { if (currentStep > 0) { currentStep--; updateStepDisplay(); } }); } updateStepDisplay(); function getForm() { return document.querySelector('.form-wrap form'); } function shouldIgnoreEnter(target) { if (!target) return false; const tag = target.tagName; if (tag === 'TEXTAREA') return true; if (tag === 'BUTTON') return true; if (tag === 'A') return true; if (target.isContentEditable) return true; if (document.querySelector('.select2-container--open')) return true; return false; } function focusFirstInStepSoon() { requestAnimationFrame(() => { requestAnimationFrame(() => { const el = firstFocusableInVisibleStep(); if (!el) return; el.focus({ preventScroll: true }); if (el.select) el.select(); }); }); } function firstFocusableInVisibleStep() { const visibleStep = Array.from(document.querySelectorAll('.form-step')) .find(s => s.offsetParent !== null); if (!visibleStep) return null; const selector = [ 'input:not([type="hidden"]):not([disabled])', 'textarea:not([disabled])', 'select:not([disabled])', '[tabindex]:not([tabindex="-1"])' ].join(','); const el = visibleStep.querySelector(selector); if (!el) return null; const style = window.getComputedStyle(el); if (style.display === 'none' || style.visibility === 'hidden') return null; return el; } document.addEventListener('keydown', function (e) { if (e.key !== 'Enter') return; if (shouldIgnoreEnter(e.target)) return; e.preventDefault(); e.stopPropagation(); const btnNext = document.getElementById('btn-next'); if (btnNext && btnNext.offsetParent !== null && !btnNext.classList.contains('hidden')) { btnNext.click(); focusFirstInStepSoon(); return; } const btnSubmit = document.getElementById('btn-submit'); if (btnSubmit && btnSubmit.offsetParent !== null && !btnSubmit.classList.contains('hidden')) { btnSubmit.click(); return; } const btn = document.querySelector('.btn-lightblue:not(.hidden):not([disabled])'); if (btn) btn.click(); }, true); })();