1jQuery(document).ready(function ($) { 2 3 $.validator.setDefaults({ 4 ignore: [] 5 }); 6 7 function getLabelTextForElement(element) { 8 var $label = $('label[for="' + element.id + '"]'); 9 var labelText = ''; 10 11 if ($label.length) { 12 labelText = $label.text().trim(); 13 } else { 14 var $fallbackLabel = $(element).closest('.form-group, .efb-item').find('label').first(); 15 if ($fallbackLabel.length) { 16 labelText = $fallbackLabel.text().trim(); 17 } else { 18 labelText = $(element).attr('aria-label') || $(element).attr('name') || 'questo campo'; 19 } 20 } 21 22 return labelText.replace(/\*+$/, '').trim(); 23 } 24 25 function updateRoomHiddenField() { 26 var value = $('.fakeinput').text().trim(); 27 $('#room_data').val(value); 28 } 29 30 // Setup MutationObserver per monitorare modifiche nel contenuto del div 31 var fakeInputDiv = document.querySelector('.fakeinput'); 32 if (fakeInputDiv) { 33 const observer = new MutationObserver(function (mutations) { 34 updateRoomHiddenField(); 35 $('#room_data').valid(); 36 }); 37 38 observer.observe(fakeInputDiv, { 39 childList: true, 40 subtree: true, 41 characterData: true 42 }); 43 } 44 45 // !Validate each form on the page 46 $('.edita-form-builder').each(function () { 47 var $form = $(this); 48 var dynamicRules = {}; 49 var dynamicMessages = {}; 50 51 $form.find('input.required, select.required, textarea.required').each(function () { 52 var name = $(this).attr('name'); 53 if (!name) return; // Skip se manca il name 54 55 $(this).attr('aria-required', 'true'); 56 57 // Recupera dinamicamente il testo della label vicino al campo hidden room_data 58 var roomLabelText = $form.find('#room_data').closest('li').find('label.section-title').contents().filter(function () { 59 return this.nodeType === 3; 60 }).text().trim() || 'Camere e ospiti'; 61 62 // Crea dinamicamente la regola required 63 dynamicRules[name] = { 64 required: true 65 }; 66 67 // Crea dinamicamente il messaggio personalizzato 68 dynamicMessages[name] = { 69 required: (typeof efb_i18n !== 'undefined' ? efb_i18n.requiredFieldPrefix : 'Required field:') + " " + getLabelTextForElement(this) + "." 70 }; 71 72 dynamicRules["room_data"] = { 73 required: true 74 }; 75 76 dynamicMessages["room_data"] = { 77 required: (typeof efb_i18n !== 'undefined' ? efb_i18n.requiredFieldPrefix : 'Required field:') + " " + roomLabelText + "." 78 }; 79 80 var type = $(this).attr('type'); 81 82 // Email 83 if (type === 'email') { 84 dynamicRules[name].email = true; 85 dynamicMessages[name].email = (typeof efb_i18n !== 'undefined' ? efb_i18n.emailInvalid : 'Inserisci un indirizzo email valido.'); 86 } 87 88 // Solo numeri 89 if (type === 'number' || $(this).hasClass('digits-only')) { 90 dynamicRules[name].digits = true; 91 dynamicMessages[name].digits = (typeof efb_i18n !== 'undefined' ? efb_i18n.digitsOnly : "Inserisci solo numeri."); 92 } 93 94 // Maxlength (solo se presente come attributo) 95 var maxLength = $(this).attr('maxlength'); 96 if (maxLength) { 97 dynamicRules[name].maxlength = parseInt(maxLength, 10); 98 dynamicMessages[name].maxlength = (typeof efb_i18n !== 'undefined' 99 ? efb_i18n.maxlength.replace('%s', maxLength) 100 : "Massimo " + maxLength + " caratteri."); 101 } 102 }); 103 104 $(this).validate({ 105 106 // submitHandler: function(form) { 107 // $(form).trigger( "efb_grecaptcha_callback"); 108 // }, 109 // rules: { 110 // required: true, 111 // digits: true, 112 // // date: true, 113 // maxlength:2 114 // }, 115 rules: dynamicRules, 116 messages: dynamicMessages, 117 errorClass: 'efb-error', 118 errorElement: 'div', 119 errorPlacement: function (error, element) { 120 var errorId = element.attr("id") + "-error"; 121 var errorWrapper = element.closest('li'); 122 123 error.attr("id", errorId); 124 error.attr("aria-live", "polite"); 125 126 if (element.is(':radio') || element.is(':checkbox')) { 127 error.appendTo(element.parent()); 128 } else if (element.is(':password')) { 129 error.hide(); 130 } else if (element.hasClass('arrivo')) { 131 $('.title-open-date .fakeinput').addClass('bg-error'); 132 } else if (element.hasClass('partenza')) { 133 $('.title-open-date .fakeinput').addClass('bg-error'); 134 } else { 135 var $existingError = $("#" + errorId); 136 if ($existingError.length) { 137 $existingError.text(error.text()); 138 } else { 139 if (!element.attr("aria-describedby")) { 140 element.attr("aria-describedby", errorId); 141 } 142 // error.insertAfter(element); 143 errorWrapper.append(error); 144 } 145 } 146 }, 147 highlight: function (element) { 148 $(element).attr('aria-invalid', 'true'); 149 $(element).closest('li').find('input, textarea').addClass('efb-error'); 150 }, 151 unhighlight: function (element) { 152 $(element).removeAttr('aria-invalid'); 153 $(element).closest('li').find('input, textarea').removeClass('efb-error'); 154 }, 155 invalidHandler: function (event, validator) { 156 if (validator.errorList.length) { 157 $(validator.errorList[0].element).focus(); 158 } 159 } 160 }); 161
162 // usiamo questo eventListener al posto di "submitHandler" di jqueryValidate 163 // perchè altrimenti l'evento submit non si propaga e non riusciamo a tracciarlo 164 // per poi fare il dataLayer.push su analytics 165 $form.on("submit", function (e) { 166 e.preventDefault(); 167 168 if ($(this).valid()) { 169 $(this).find('button.efb-submit').attr('disabled', 'disabled'); 170 console.log('valid'); 171 172 // evento che fa scattare il recaptcha e la funzione di callback 173 $(this).trigger("efb_grecaptcha_callback"); 174 175 } else { 176 $(this).find('button.efb-submit').removeAttr('disabled'); 177 console.log('not valid'); 178 } 179 }); 180 181 }); 182 183 // per il momento la usiamo solo per recaptcha v3 184 if (typeof (efb_config) != "undefined" && typeof (efb_config.recaptcha_v) != "undefined" && efb_config.recaptcha_v == "v3" && typeof (efb_config.recaptcha_sitekey) != "undefined") { 185 $('form').on("efb_grecaptcha_callback", function (event) { 186 var _thisForm = $(this); 187 188 // console.log('scatta evento: efb_grecaptcha_callback', _thisForm);//debug 189 190 grecaptcha.ready(function () { 191 grecaptcha.execute(efb_config.recaptcha_sitekey, { action: 'efb_recaptcha' }).then(function (token) { 192 193 // ho ricevuto il token dal recaptcha, lo appendo come variabile nascosta al form 194 if (_thisForm.find('[name="g-recaptcha-response"]').length < 1) { 195 _thisForm.append('<input type="hidden" name="g-recaptcha-response" />') 196 } 197 198 _thisForm.find('[name="g-recaptcha-response"]').val(token); 199 200 // INIZIO / mrpreno attribution 201 try { 202 if( window.MrPRENODataAcq != undefined && typeof( window.MrPRENODataAcq.getAttribution ) == "function" ) { 203 204 console.log('mrpreno attribution:', window.MrPRENODataAcq.getAttribution()); //debug 205 206 if( _thisForm.find('[name="attribution"]').length === 0 ) { 207 208 var iAttribution = document.createElement("input"); 209 iAttribution.setAttribute("type", "hidden"); 210 iAttribution.setAttribute("name", "attribution"); 211 iAttribution.setAttribute("value", window.MrPRENODataAcq.getAttribution()); 212 213 _thisForm.append(iAttribution); 214 } 215 } 216 } catch(e) { 217 console.log('[mrpreno attribution]', e); 218 } 219 // FINE / mrpreno attribution 220 221 // con _thisForm[0] ho l'oggetto javascript nativo 222 // necessario per usare HTMLFormElement 223 HTMLFormElement.prototype.submit.call(_thisForm[0]); 224 }); 225 }); 226 }); 227 } 228 229 // Force bullets to hide, but only if list-style-type isn't set 230 $('.edita-form-builder li:not(.efb-item-instructions li, .efb-span li)').filter(function () { 231 return $(this).css('list-style-type') !== 'none'; 232 }).css('list-style', 'none'); 233 234 // !Display jQuery UI date picker 235 $('.efb-date-picker').each(function () { 236 var efb_dateFormat = $(this).attr('data-dp-dateFormat') ? $(this).attr('data-dp-dateFormat') : 'mm/dd/yy'; 237 238 $(this).datepicker({ 239 dateFormat: efb_dateFormat 240 }); 241 }); 242 243 $('.modal').scroll(function () { 244 $(".efb-date-picker").datepicker("hide"); 245 $(".efb-date-picker").blur(); 246 }); 247 248 // !Custom validation method to check multiple emails 249 $.validator.addMethod('phone', function (value, element) { 250 // Strip out all spaces, periods, dashes, parentheses, and plus signs 251 value = value.replace(/[\+\s\(\)\.\-\ ]/g, ''); 252 253 return this.optional(element) || value.length > 9 && 254 value.match(/^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$/); 255 256 }, $.validator.messages.phone 257 ); 258 259 260 var labelID; 261 262 $('label').click(function () { 263 labelID = $(this).attr('for'); 264 265 $('#' + labelID).trigger('click'); 266 }); 267 268}); 269 270 271 272 273 274 275 276
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.