From 1a90b3f0d59f8db10f90f8a3c64dde404f0767c4 Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 1 Oct 2026 13:28:23 +0200 Subject: - Screenshots für Modul "Amazon" Doku MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mod_addressvalidation/addressvalidation.js | 413 +++++++++++++++++---- 1 file changed, 341 insertions(+), 72 deletions(-) (limited to 'views/mods/mod_addressvalidation/addressvalidation.js') diff --git a/views/mods/mod_addressvalidation/addressvalidation.js b/views/mods/mod_addressvalidation/addressvalidation.js index b74aa5b..089788b 100644 --- a/views/mods/mod_addressvalidation/addressvalidation.js +++ b/views/mods/mod_addressvalidation/addressvalidation.js @@ -1,82 +1,351 @@ /** - * Globale Funktionen zur Adressvalidation + * Adressvalidierung im Browser + * Fragt wpsg_mod_addressvalidation::ajaxValidate() im Shop an, der API-Key bleibt auf dem Server + * Die Konfiguration (ajaxurl, action, nonce, labelApply, labelProposal) setzt wpsg_mod_addressvalidation::wpsg_enqueue_scripts() */ -function validateAddressBind(data) { - jQuery(data.PLZ).on("input", function () { - validateAddress(data); - }); - jQuery(data.Ort).on("input", function () { - validateAddress(data); - }); - jQuery(data.Strasse).on("input", function () { - validateAddress(data); - }); - jQuery(data.Land).on("input", function () { - validateAddress(data); +/** Verzögerung, damit mehrere geänderte Felder nur eine Anfrage auslösen (ms) */ +var wpsg_mod_addressvalidation_delay = 400; + +/** + * Selektoren der Adressfelder je Adresse + * Klassische Kasse, OnePage, Profil und Registrierung (#strasse …) sowie SmartCheckout (#wpsg_sc_strasse …) + * Die Lieferanschrift (#shipping_…) ist in beiden gleich + */ +var wpsg_mod_addressvalidation_fields = [ + { + type: 'billing', + strasse: '#strasse, #wpsg_sc_strasse', + nr: '#nr, #wpsg_sc_nr', + plz: '#plz, #wpsg_sc_plz', + ort: '#ort, #wpsg_sc_ort', + land: '#wpsg_land, #wpsg_sc_land' + }, + { + type: 'shipping', + strasse: '#shipping_strasse', + nr: '#shipping_nr', + plz: '#shipping_plz', + ort: '#shipping_ort', + land: '#shipping_land' + } +]; + +/** + * Liefert das erste vorhandene Feld zu einem Schlüssel (strasse, nr, plz, ort, land) + * + * @param oFields + * @param strKey + * @return jQuery + */ +function wpsg_mod_addressvalidation_getField(oFields, strKey) { + + return jQuery(oFields[strKey]).first(); + +} // function wpsg_mod_addressvalidation_getField(oFields, strKey) + +/** + * Bindet die Prüfung an die Felder einer Adresse + * Über document, damit auch Felder greifen, die erst später erzeugt werden (SmartCheckout baut sie mit Vue auf) + * + * @param oFields Selektoren der Felder (strasse, nr, plz, ort, land) und type ('billing' oder 'shipping') + */ +function wpsg_mod_addressvalidation_bind(oFields) { + + var oTimer = null; + + jQuery(document).on('change', [oFields.strasse, oFields.nr, oFields.plz, oFields.ort, oFields.land].join(', '), function() { + + window.clearTimeout(oTimer); + + oTimer = window.setTimeout(function() { + + wpsg_mod_addressvalidation_check(oFields); + + }, wpsg_mod_addressvalidation_delay); + }); -} - -// Adress-Validation -function validateAddress(data) { - var - plz, - ort, - strasse, - astr1, - land = 'de', - rw; - plz = jQuery(data.PLZ).val(); - ort = jQuery(data.Ort).val(); - strasse = jQuery(data.Strasse).val(); - nr = jQuery(data.Nr).val(); - if (nr !== undefined) { - strasse = strasse + ' ' + nr; + +} // function wpsg_mod_addressvalidation_bind(oFields) + +/** + * Liefert das Element für die Meldung einer Adresse und legt es bei Bedarf direkt hinter dem Land an + * (ohne Land hinter Ort bzw. PLZ) + * + * @param oFields + * @return jQuery + */ +function wpsg_mod_addressvalidation_getMessage(oFields) { + + var strClass = 'wpsg_mod_addressvalidation_message_' + oFields.type; + var oMessage = jQuery('.' + strClass); + + if (oMessage.length) return oMessage; + + oMessage = jQuery('
').css({ + 'margin': '0 0 1rem 0', + 'padding': '3px 0 3px 8px' + }).hide(); + + var arAnchor = ['land', 'ort', 'plz']; + + for (var i = 0; i < arAnchor.length; i ++) { + + var oField = wpsg_mod_addressvalidation_getField(oFields, arAnchor[i]); + + if (oField.length) { + + // SmartCheckout: Die Felder liegen in einem Grid, die Meldung belegt dort eine eigene Zeile über die volle Breite + var oBlock = oField.closest('.sc_field'); + + if (oBlock.length) { + + oMessage.css({ 'grid-column': '1 / -1', 'margin': '0' }); + + } else { + + oBlock = oField.closest('.wpsg_checkoutblock'); + + } + + ((oBlock.length)?oBlock:oField).after(oMessage); + + break; + + } + } - land = jQuery(data.Land + ' option:selected').val(); - land = jQuery(data.Land + ' option:selected').attr('data-land'); - astr1 = localStorage.getItem(data.StorageKey); - if ((plz.length > 3) && (ort.length > 3) && (strasse.length > 3) && - (astr1 != (strasse + plz + ort + land))) - { + return oMessage; + +} // function wpsg_mod_addressvalidation_getMessage(oFields) + +/** + * Setzt den Wert eines Feldes und meldet die Änderung, damit auch Vue (SmartCheckout) den Wert übernimmt + * + * @param oField + * @param strValue + */ +function wpsg_mod_addressvalidation_setValue(oField, strValue) { + + if (!oField.length) return; + + var el = oField[0]; + + el.value = strValue; + el.dispatchEvent(new Event('input', { bubbles: true })); + el.dispatchEvent(new Event('change', { bubbles: true })); + +} // function wpsg_mod_addressvalidation_setValue(oField, strValue) + +/** + * Übernimmt den Vorschlag des Dienstes in die Felder einer Adresse + * + * @param oFields + * @param oProposal strasse, nr, plz, ort + */ +function wpsg_mod_addressvalidation_apply(oFields, oProposal) { + + var oNr = wpsg_mod_addressvalidation_getField(oFields, 'nr'); + var strStrasse = oProposal.strasse; + + // Ohne eigenes Feld für die Hausnummer gehört sie zur Straße + if (oNr.length) { + + wpsg_mod_addressvalidation_setValue(oNr, oProposal.nr); + + } else if (oProposal.nr !== '') { + + strStrasse = strStrasse + ' ' + oProposal.nr; - astr1 = strasse + plz + ort + land; - localStorage.setItem(data.StorageKey, astr1); - jQuery.ajax({ - url: 'http://api.address-validator.net/api/verify', - type: 'POST', - data: { StreetAddress: strasse, - City: ort, - PostalCode: plz, - //State: State, - CountryCode: land, - //Locale: land, - APIKey: data.Key}, - dataType: 'json', - success: function (json) { - // check API result - if (typeof(json.status) != "undefined") { - status = json.status; - formattedaddress = json.formattedaddress; - if (json.status === 'VALID') { - - - } else if ((json.status === 'INVALID') || (json.status === 'SUSPECT')) { - - alert(data.MsgTeil1 + '-Validation fehlerhaft. Bitte Straße, Hausnummer, PLZ, Ort und Land überprüfen.'); - - } else { - - alert('Adress-Validation Serverproblem: ' + json.status); - - } - } - - } - }); - } -} + wpsg_mod_addressvalidation_setValue(wpsg_mod_addressvalidation_getField(oFields, 'strasse'), strStrasse); + wpsg_mod_addressvalidation_setValue(wpsg_mod_addressvalidation_getField(oFields, 'plz'), oProposal.plz); + wpsg_mod_addressvalidation_setValue(wpsg_mod_addressvalidation_getField(oFields, 'ort'), oProposal.ort); + +} // function wpsg_mod_addressvalidation_apply(oFields, oProposal) + +/** + * Baut die Zeile mit dem Vorschlag des Dienstes, Werte, die von der Eingabe abweichen, sind fett + * + * @param oFields + * @param oData eingegebene Werte (strasse, nr, plz, ort) + * @param oProposal vorgeschlagene Werte (strasse, nr, plz, ort) + * @return jQuery + */ +function wpsg_mod_addressvalidation_renderProposal(oFields, oData, oProposal) { + + var oLine = jQuery('
').css('margin-top', '4px'); + var bNr = (wpsg_mod_addressvalidation_getField(oFields, 'nr').length > 0); + + var normalize = function(strValue) { + + return jQuery.trim(String(strValue || '')).replace(/\s+/g, ' ').toLowerCase(); + + }; + + var addValue = function(strValue, strInput) { + + oLine.append(jQuery((normalize(strValue) !== normalize(strInput))?'':'').text(strValue)); + + }; + + oLine.append(jQuery('').text(wpsg_mod_addressvalidation.labelProposal + ' ')); + + // Ohne eigenes Feld für die Hausnummer steht sie in der Eingabe mit in der Straße + if (bNr) { + + addValue(oProposal.strasse, oData.strasse); + + if (oProposal.nr !== '') { + + oLine.append(' '); + addValue(oProposal.nr, oData.nr); + + } + + } else { + + addValue(jQuery.trim(oProposal.strasse + ' ' + oProposal.nr), oData.strasse); + + } + + oLine.append(', '); + addValue(oProposal.plz, oData.plz); + oLine.append(' '); + addValue(oProposal.ort, oData.ort); + + return oLine; + +} // function wpsg_mod_addressvalidation_renderProposal(oFields, oData, oProposal) + +/** + * Prüft die Adresse über den Shop und zeigt die Meldung an + * + * @param oFields + */ +function wpsg_mod_addressvalidation_check(oFields) { + + var oStrasse = wpsg_mod_addressvalidation_getField(oFields, 'strasse'); + var oPlz = wpsg_mod_addressvalidation_getField(oFields, 'plz'); + var oOrt = wpsg_mod_addressvalidation_getField(oFields, 'ort'); + + if (!oStrasse.length || !oPlz.length || !oOrt.length) return; + + var oMessage = wpsg_mod_addressvalidation_getMessage(oFields); + + var oData = { + action: wpsg_mod_addressvalidation.action, + nonce: wpsg_mod_addressvalidation.nonce, + type: oFields.type, + strasse: jQuery.trim(oStrasse.val() || ''), + nr: jQuery.trim(wpsg_mod_addressvalidation_getField(oFields, 'nr').val() || ''), + plz: jQuery.trim(oPlz.val() || ''), + ort: jQuery.trim(oOrt.val() || ''), + land: wpsg_mod_addressvalidation_getField(oFields, 'land').val() || '' + }; + + // Unvollständige Adressen nicht anfragen + if (oData.strasse.length < 3 || oData.plz.length < 3 || oData.ort.length < 2) { + + oMessage.removeData('address').hide().empty(); + + return; + + } + + var strAddress = JSON.stringify([oData.strasse, oData.nr, oData.plz, oData.ort, oData.land]); + + if (oMessage.data('address') === strAddress) return; + + oMessage.data('address', strAddress); + + jQuery.post(wpsg_mod_addressvalidation.ajaxurl, oData).done(function(response) { + + // Inzwischen wurde die Adresse erneut geändert + if (oMessage.data('address') !== strAddress) return; + + if (!response || !response.success || !response.data.message) { + + oMessage.hide().empty(); + + return; + + } + + oMessage.empty().append(jQuery('').text(response.data.message)); + + if (response.data.proposal) { + + var oProposal = response.data.proposal; + + oMessage.append(wpsg_mod_addressvalidation_renderProposal(oFields, oData, oProposal).append(' ', jQuery('').text(wpsg_mod_addressvalidation.labelApply).on('click', function() { + + wpsg_mod_addressvalidation_apply(oFields, oProposal); + + }))); + + } + + oMessage.css('border-left', '4px solid ' + ((response.data.blocked)?'#DD3D36':'#F0AD4E')).show(); + + }).fail(function() { + + // Ohne Antwort beim nächsten Ändern erneut versuchen, checkCheckout() prüft beim Absenden trotzdem + oMessage.removeData('address').hide().empty(); + + }); + +} // function wpsg_mod_addressvalidation_check(oFields) + +/** + * Prüft eine bereits ausgefüllte Adresse direkt nach dem Laden, z.B. nach einem abgewiesenen Absenden + * Wartet, bis die Felder vorhanden sind (SmartCheckout baut sie erst mit Vue auf) + * + * @param oFields + * @param nTry bisherige Versuche + */ +function wpsg_mod_addressvalidation_checkInitial(oFields, nTry) { + + if (!wpsg_mod_addressvalidation_getField(oFields, 'strasse').length) { + + if (nTry < 20) { + + window.setTimeout(function() { + + wpsg_mod_addressvalidation_checkInitial(oFields, nTry + 1); + + }, 250); + + } + + return; + + } + + wpsg_mod_addressvalidation_check(oFields); + +} // function wpsg_mod_addressvalidation_checkInitial(oFields, nTry) + +/** + * Früherer Aufruf aus checkout.phtml, bleibt für angepasste Templates im Theme erhalten + * Die Felder werden inzwischen automatisch gebunden, der übergebene API-Key wird nicht mehr verwendet + * + * @param data + */ +function validateAddressBind(data) { + +} // function validateAddressBind(data) + +jQuery(document).ready(function() { + + if (typeof(wpsg_mod_addressvalidation) == 'undefined') return; + + for (var i = 0; i < wpsg_mod_addressvalidation_fields.length; i ++) { + + wpsg_mod_addressvalidation_bind(wpsg_mod_addressvalidation_fields[i]); + wpsg_mod_addressvalidation_checkInitial(wpsg_mod_addressvalidation_fields[i], 0); + } +}); -- cgit v1.2.3