1(function ($, Drupal, window, document, undefined) { 2 3 $(document).ready(function () { 4 const rulesMessage = validationMessages; 5 6 // Ajout de méthodes personnalisées de validation 7 $.validator.addMethod("regex", function (value, element, regexp) { 8 const re = new RegExp(regexp); 9 return this.optional(element) || re.test(value); 10 }); 11 12 $.validator.addMethod('validatePhone', function (value, element) { 13 return this.optional(element) || $(element).intlTelInput("isValidNumber"); 14 }, "Numéro non valide"); 15 16 // Ciblage de tous les formulaires webform 17 $(".webform-client-form").each(function () { 18 const form = $(this); 19 const phoneInput = $(".form-tel", form); 20 const copiedField = $('[name="submitted[international_phone]"]', form); 21 22 // intlTelInput config 23 phoneInput.intlTelInput({ 24 allowExtensions: true, 25 autoPlaceholder: "off", 26 initialCountry: "auto", 27 geoIpLookup: function(callback) { 28 $.get('https://ipinfo.io', function() {}, "jsonp").always(function(resp) { 29 const countryCode = (resp && resp.country) ? resp.country : "fr"; 30 callback(countryCode); 31 }); 32 }, 33 utilsScript: "/sites/all/themes/esarc/js/intlTelinput-utils.js" 34 }); 35 36 // Mise à jour du champ masqué à chaque modification du champ téléphone 37 phoneInput.on("keyup blur click", function () { 38 const intlNumber = phoneInput.intlTelInput("getNumber"); 39 copiedField.val(intlNumber); 40 }); 41 42 // Initialisation du validateur 43 const validator = form.validate({ 44 rules: { 45 'submitted[commercial_list][0]': { required: true }, 46 'submitted[commercial_list][1]': { required: true }, 47 'submitted[commercial_list][2]': { required: true }, 48 'submitted[condition]': { required: true }, 49 'submitted[rgpd][1]' : { required: true }, 50 'submitted[first_name]': { required: true, minlength: 2 }, 51 'submitted[last_name]': { required: true, minlength: 2 }, 52 'submitted[phone]': { required: true, validatePhone: true }, 53 'submitted[telephone]': { required: true, validatePhone: true }, 54 'submitted[email]': { 55 required: true, 56 regex: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, 57 minlength: 6 58 } 59 }, 60 messages: { 61 'submitted[commercial_list][0]': { 62 required: rulesMessage.cityRequired 63 }, 64 'submitted[commercial_list][1]': { 65 required: rulesMessage.programRequired 66 }, 67 'submitted[commercial_list][2]': { 68 required: rulesMessage.programRequired 69 }, 70 'submitted[commercial_unit_meeting_uuid]': { 71 required: rulesMessage.eventRequired 72 }, 73 'submitted[condition][1]': { 74 required: rulesMessage.termsRequired 75 }, 76 'submitted[rgpd][1]': { 77 required: rulesMessage.termsRequired 78 }, 79 'submitted[email]': { 80 required: rulesMessage.emailRequired, 81 regex: rulesMessage.emailRegex, 82 email: rulesMessage.emailEmail 83 }, 84 'submitted[last_name]': { 85 required: rulesMessage.lastNameRequired, 86 minlength: rulesMessage.lastNameMinLength 87 }, 88 'submitted[first_name]': { 89 required: rulesMessage.firstNameRequired, 90 minlength: rulesMessage.firstNameMinLength 91 }, 92 'submitted[phone]': { 93 required: rulesMessage.phoneRequired, 94 validatePhone: rulesMessage.phonevalidatePhone 95 }, 96 'submitted[telephone]': { 97 required: rulesMessage.phoneRequired, 98 validatePhone: rulesMessage.phonevalidatePhone 99 }, 100 'submitted[rgpd][Ok]': { 101 required: rulesMessage.rgpdRequired 102 } 103 }, 104 errorPlacement: function (error, element) { 105 error.appendTo(element.parent(".form-item")); 106 error.appendTo(element.parent(".intl-tel-input")); 107 }, 108 errorElement: "span", 109 wrapper: "", 110 }); 111 112 // Fonction pour mettre à jour l'état visuel du bouton 113 function updateSubmitButtonState(form) { 114 const submitButton = $("input[type=submit]", form); 115 if (validator.checkForm()) { 116 submitButton.removeClass('opacity-50'); 117 } else { 118 submitButton.addClass('opacity-50'); 119 } 120 } 121 122 // Vérifie la validité des champs à chaque modification 123 form.find(':input').on('keyup blur change', function () { 124 validator.element(this); // Valide le champ individuellement 125 updateSubmitButtonState(form); // Met à jour le bouton visuellement 126 }); 127 128 // Gestion propre de la soumission 129 form.on('submit', function (e) { 130 if (!validator.form()) { 131 //console.warn("ð« [form-protection] Formulaire incomplet"); 132 e.preventDefault(); 133 return false;
134 } 135 136 // Anti double-soumission 137 if (form.data('submitted')) { 138 //console.warn("ð« [form-protection] Double soumission bloquée"); 139 e.preventDefault(); 140 return false; 141 } 142 //console.log("â ï¸ [form-protection] Première soumission validée, verrouillage du bouton"); 143 form.data('submitted', true); 144 145 // Désactiver le bouton 146 const submitButton = form.find("input[type=submit]"); 147 submitButton.prop('disabled', true).addClass('opacity-50'); 148 149 // Modifier le texte du bouton 150 submitButton.val('Envoi en cours...'); 151 }); 152 }); 153 }); 154 155})(jQuery, Drupal, this, this.document);
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.