summaryrefslogtreecommitdiff
path: root/views/mods/mod_addressvalidation/addressvalidation.js
diff options
context:
space:
mode:
authordaniel <noreply@maennchen1.de>2026-10-01 13:28:23 +0200
committerdaniel <noreply@maennchen1.de>2026-10-01 13:28:23 +0200
commit1a90b3f0d59f8db10f90f8a3c64dde404f0767c4 (patch)
treeb035cd24cc0802a6b3498337e8fdb695385f6f3f /views/mods/mod_addressvalidation/addressvalidation.js
parent9de7219882c5e4298389b260a88d308f26214c70 (diff)
- Screenshots für Modul "Amazon" Doku
Diffstat (limited to 'views/mods/mod_addressvalidation/addressvalidation.js')
-rw-r--r--views/mods/mod_addressvalidation/addressvalidation.js413
1 files changed, 341 insertions, 72 deletions
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('<div class="wpsg_mod_addressvalidation_message ' + strClass + '" role="status"></div>').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('<div class="wpsg_mod_addressvalidation_proposal"></div>').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))?'<strong></strong>':'<span></span>').text(strValue));
+
+ };
+
+ oLine.append(jQuery('<span></span>').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('<span></span>').text(response.data.message));
+
+ if (response.data.proposal) {
+
+ var oProposal = response.data.proposal;
+
+ oMessage.append(wpsg_mod_addressvalidation_renderProposal(oFields, oData, oProposal).append(' ', jQuery('<button type="button" class="button wpsg_mod_addressvalidation_apply"></button>').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);
+ }
+});