1(function ($) { 2 'use strict'; 3 4 var currentStep = 1; 5 var totalSteps = 5; 6 7 function showAlert(message) { 8 $('#sas-form-alert').addClass('is-error').text(message || 'Please complete all required fields.'); 9 } 10 11 function hideAlert() { 12 $('#sas-form-alert').removeClass('is-error').text(''); 13 } 14 15 function togglePreviousJobs() { 16 var worked = $('input[name="worked_before"]:checked').val(); 17 var box = $('#sas-previous-jobs'); 18 if (worked === 'yes') { 19 box.addClass('is-visible').attr('aria-hidden', 'false'); 20 } else { 21 box.removeClass('is-visible').attr('aria-hidden', 'true'); 22 } 23 } 24 25 function getStepFromField(field) { 26 var $step = $(field).closest('.sas-form-step'); 27 var step = parseInt($step.data('step'), 10); 28 return step || 1; 29 } 30 31 function updateStep(step) { 32 currentStep = Math.max(1, Math.min(totalSteps, step)); 33 var $active = $('.sas-form-step[data-step="' + currentStep + '"]'); 34 var title = $active.data('title') || ''; 35 var percent = (currentStep / totalSteps) * 100; 36 37 $('.sas-form-step').removeClass('is-active').attr('aria-hidden', 'true'); 38 $active.addClass('is-active').attr('aria-hidden', 'false'); 39 40 $('#sas-current-step').text(currentStep); 41 $('#sas-progress-title').text(title); 42 $('#sas-progress-bar').css('width', percent + '%'); 43 $('.sas-step-dots span').removeClass('is-active is-done').each(function (index) { 44 var dotStep = index + 1; 45 if (dotStep < currentStep) { 46 $(this).addClass('is-done'); 47 } 48 if (dotStep === currentStep) { 49 $(this).addClass('is-active'); 50 } 51 }); 52 53 $('.sas-prev-btn').toggle(currentStep > 1); 54 $('.sas-next-btn').toggle(currentStep < totalSteps); 55 $('.sas-submit-btn').toggle(currentStep === totalSteps); 56 hideAlert(); 57 58 var $shell = $('.sas-form-shell'); 59 if ($shell.length && currentStep > 1) { 60 $('html, body').animate({ scrollTop: Math.max(0, $shell.offset().top - 24) }, 220); 61 } 62 } 63 64 function validateStep(step) { 65 var valid = true; 66 var firstInvalid = null; 67 var $step = $('.sas-form-step[data-step="' + step + '"]'); 68 var checkedRadioNames = {}; 69 70 $step.find('input, select, textarea').each(function () { 71 var el = this; 72 if (el.disabled) { 73 return; 74 } 75 if (el.type === 'radio') { 76 if (checkedRadioNames[el.name]) { 77 return; 78 } 79 checkedRadioNames[el.name] = true; 80 } 81 if (!el.checkValidity()) { 82 valid = false; 83 if (!firstInvalid) { 84 firstInvalid = el; 85 } 86 } 87 }); 88 89 if (!valid && firstInvalid) { 90 firstInvalid.reportValidity(); 91 showAlert('Please complete the required question before continuing.'); 92 } 93 94 return valid; 95 } 96 97 $(document).on('change', 'input[name="worked_before"]', togglePreviousJobs); 98 99 $(document).on('click', '.sas-next-btn', function () { 100 hideAlert(); 101 if (validateStep(currentStep)) { 102 updateStep(currentStep + 1); 103 } 104 }); 105 106 $(document).on('click', '.sas-prev-btn', function () { 107 updateStep(currentStep - 1); 108 }); 109 110 $(document).on('submit', '#sas-application-form', function (e) { 111 e.preventDefault(); 112 hideAlert(); 113 114 var form = this; 115 if (!form.checkValidity()) { 116 var firstInvalid = $(form).find(':invalid').first().get(0); 117 if (firstInvalid) { 118 updateStep(getStepFromField(firstInvalid)); 119 setTimeout(function () { 120 firstInvalid.reportValidity(); 121 showAlert('Please complete all required fields before submitting.'); 122 }, 80); 123 } else { 124 showAlert('Please complete all required fields before submitting.'); 125 } 126 return; 127 } 128 129 var $form = $(form); 130 var $button = $form.find('.sas-submit-btn'); 131 var originalText = $button.text(); 132 $button.prop('disabled', true).text('Submitting...'); 133 134 $.ajax({ 135 url: SASFrontend.ajaxUrl, 136 method: 'POST', 137 data: $form.serialize(), 138 dataType: 'json' 139 }).done(function (response) { 140 if (response && response.success) { 141 form.reset(); 142 togglePreviousJobs(); 143 updateStep(1); 144 $('#sas-thankyou-modal').addClass('is-open').attr('aria-hidden', 'false'); 145 } else { 146 showAlert(response && response.data && response.data.message ? response.data.message : 'Could not submit your application.'); 147 } 148 }).fail(function () { 149 showAlert('Could not submit your application. Please check your connection and try again.'); 150 }).always(function () { 151 $button.prop('disabled', false).text(originalText); 152 }); 153 }); 154 155 $(document).on('click', '.sas-close-modal', function () { 156 $('#sas-thankyou-modal').removeClass('is-open').attr('aria-hidden', 'true'); 157 }); 158 159 $(document).on('click', '#sas-thankyou-modal', function (e) { 160 if (e.target === this) { 161 $(this).removeClass('is-open').attr('aria-hidden', 'true'); 162 } 163 }); 164 165 $(function () { 166 togglePreviousJobs(); 167 updateStep(1); 168 }); 169})(jQuery);
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.