mivaecommerce / readytheme-shadows

Shadows is the development framework and methodology used for creating our ReadyThemes as well as custom websites.
https://shadows.mivareadythemes.com/
MIT License
4 stars 3 forks source link

CADA/CADE: Address Validation Issue #99

Closed influxweb closed 3 years ago

influxweb commented 3 years ago

Current Behavior

When validating an address on CADA or CADE, an error is thrown since there are no billing fields.

Correcting the Issue

To make the update, without applying the latest release, you will need to update the code in User Interface -> Theme Components -> Content Sections -> address_validation:

<mvt:if expr="NOT ISNULL l.settings:customer:validated_ship_addresses OR NOT ISNULL l.settings:customer:validated_bill_addresses OR NOT ISNULL l.settings:addressfields:validated_addresses">
    <div class="c-dialog" data-dialog="address-validation" aria-hidden="true">
        <div class="c-dialog__overlay" tabindex="-1">
            <div class="c-dialog__container" aria-labelledby="address-validation-title" aria-describedby="address-validation-description" aria-modal="true" role="alertdialog">
                <header class="c-dialog__header">
                    <h2 id="address-validation-title" class="c-dialog__title c-heading-delta u-text-uppercase">
                        Address Verification<br><br>
                        <span id="address-validation-description" class="c-heading--subheading u-text-revert">
                            <strong class="u-font-large">Shipping Address</strong><br>
                            The shipping address you entered appears to be incorrect or incomplete. Please verify your address to ensure a timely delivery.
                        </span>
                    </h2>
                    <button class="c-dialog__close" aria-label="Close Dialog" data-dialog-close></button>
                </header>
                <div class="c-dialog__content">
                    <div class="o-layout u-grids-1 u-grids-2--s">
                        <mvt:if expr="l.settings:page:code EQ 'CADA' OR l.settings:page:code EQ 'CADE'">
                            <mvt:assign name="l.settings:addressArray" value="l.settings:addressfields:validated_addresses"/>
                        <mvt:else>
                            <mvt:assign name="l.settings:addressArray" value="l.settings:customer:validated_ship_addresses"/>
                        </mvt:if>
                        <div class="o-layout__item">
                            <mvt:foreach array="addressArray" iterator="address">
                                <mvt:if expr="NOT l.settings:address:validated">
                                    <label class="c-form-checkbox">
                                        <input class="c-form-checkbox__input" type="radio" name="ShipValidatedSelector" data-mm_address_addr1="&mvte:address:addr1;" data-mm_address_addr2="&mvte:address:addr2;" data-mm_address_city="&mvte:address:city;" data-mm_address_comp="&mvte:address:comp;" data-mm_address_country="&mvte:address:country;" data-mm_address_resdntl="&mvte:address:resdntl;" data-mm_address_state="&mvte:address:state;" data-mm_address_zip="&mvte:address:zip;">
                                        <span class="c-form-checkbox__caption u-text-bold">Use&nbsp;<span class="u-hide-visually">Shipping Address&nbsp;</span>As Entered</span>
                                    </label>
                                    <p class="u-font-small">
                                        <mvt:if expr="NOT ISNULL l.settings:address:comp">
                                            &mvte:address:comp;<br>
                                        </mvt:if>
                                        <mvt:if expr="NOT ISNULL l.settings:address:addr1 OR NOT ISNULL l.settings:address:addr2 OR NOT ISNULL l.settings:address:city OR NOT ISNULL l.settings:address:state OR NOT ISNULL l.settings:address:zip OR NOT ISNULL l.settings:address:cntry OR NOT ISNULL l.settings:address:res">
                                            &mvte:address:addr1;<br>
                                            <mvt:if expr="NOT ISNULL l.settings:address:addr2">
                                                &mvte:address:addr2;<br>
                                            </mvt:if>
                                            <mvt:if expr="(NOT ISNULL l.settings:address:city) AND (NOT ISNULL l.settings:address:state)">
                                                &mvte:address:city;, &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                            <mvt:else>
                                                &mvte:address:city; &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                            </mvt:if>
                                            <mvt:if expr="l.settings:address:resdntl">
                                                <br>Residential Address
                                            </mvt:if>
                                        </mvt:if>
                                    </p>
                                    <hr class="c-keyline c-keyline--small">
                                </mvt:if>
                            </mvt:foreach>
                        </div>
                        <div class="o-layout__item">
                            <mvt:assign name="l.settings:address_count" value="1"/>
                            <mvt:foreach array="addressArray" iterator="address">
                                <mvt:if expr="l.settings:address:validated">
                                    <label class="c-form-checkbox">
                                        <input class="c-form-checkbox__input" type="radio" name="ShipValidatedSelector" data-mm_address_addr1="&mvte:address:addr1;" data-mm_address_addr2="&mvte:address:addr2;" data-mm_address_city="&mvte:address:city;" data-mm_address_comp="&mvte:address:comp;" data-mm_address_country="&mvte:address:country;" data-mm_address_resdntl="&mvte:address:resdntl;" data-mm_address_state="&mvte:address:state;" data-mm_address_zip="&mvte:address:zip;" aria-describedby="address-&mvte:address_count;">
                                        <span class="c-form-checkbox__caption u-text-bold">Verified&nbsp;<span class="u-hide-visually">Shipping&nbsp;</span>Address <span class="u-hide-visually">&mvte:address_count;</span></span>
                                    </label>
                                    <p id="address-&mvte:address_count;" class="u-font-small">
                                        <mvt:if expr="NOT ISNULL l.settings:address:comp">
                                            &mvte:address:comp;<br>
                                        </mvt:if>
                                        <mvt:if expr="NOT ISNULL l.settings:address:addr1 OR NOT ISNULL l.settings:address:addr2 OR NOT ISNULL l.settings:address:city OR NOT ISNULL l.settings:address:state OR NOT ISNULL l.settings:address:zip OR NOT ISNULL l.settings:address:cntry OR NOT ISNULL l.settings:address:res">
                                            &mvte:address:addr1;<br>
                                            <mvt:if expr="NOT ISNULL l.settings:address:addr2">
                                                &mvte:address:addr2;<br>
                                            </mvt:if>
                                            <mvt:if expr="(NOT ISNULL l.settings:address:city) AND (NOT ISNULL l.settings:address:state)">
                                                &mvte:address:city;, &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                            <mvt:else>
                                                &mvte:address:city; &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                            </mvt:if>
                                            <mvt:if expr="l.settings:address:resdntl">
                                                <br>Residential Address
                                            </mvt:if>
                                        </mvt:if>
                                    </p>
                                    <hr class="c-keyline c-keyline--small">
                                    <mvt:assign name="l.settings:address_count" value="l.settings:address_count + 1"/>
                                </mvt:if>
                            </mvt:foreach>
                        </div>
                    </div>

                    <mvt:if expr="l.settings:page:code NE 'CADA' AND l.settings:page:code NE 'CADE'">
                        <mvt:if expr="g.billing_to_show NE 1">
                            <br>
                            <p class="u-font-tiny" data-billing-shown>
                                <strong class="u-font-large">Billing Address</strong><br>
                                We were unable to verify the billing address you provided.
                            </p>
                            <div class="o-layout u-grids-1 u-grids-2--s">
                                <div class="o-layout__item">
                                    <mvt:foreach array="customer:validated_bill_addresses" iterator="address">
                                        <mvt:if expr="NOT l.settings:address:validated">
                                            <label class="c-form-checkbox">
                                                <input class="c-form-checkbox__input" type="radio" name="BillValidatedSelector" data-mm_address_addr1="&mvte:address:addr1;" data-mm_address_addr2="&mvte:address:addr2;" data-mm_address_city="&mvte:address:city;" data-mm_address_comp="&mvte:address:comp;" data-mm_address_country="&mvte:address:country;" data-mm_address_state="&mvte:address:state;" data-mm_address_zip="&mvte:address:zip;">
                                                <span class="c-form-checkbox__caption u-text-bold">Use&nbsp;<span class="u-hide-visually">Billing Address&nbsp;</span>As Entered</span>
                                            </label>
                                            <p class="u-font-small">
                                                <mvt:if expr="NOT ISNULL l.settings:address:comp">
                                                    &mvte:address:comp;<br>
                                                </mvt:if>
                                                <mvt:if expr="NOT ISNULL l.settings:address:addr1 OR NOT ISNULL l.settings:address:addr2 OR NOT ISNULL l.settings:address:city OR NOT ISNULL l.settings:address:state OR NOT ISNULL l.settings:address:zip OR NOT ISNULL l.settings:address:cntry">
                                                    &mvte:address:addr1;<br>
                                                    <mvt:if expr="NOT ISNULL l.settings:address:addr2">
                                                        &mvte:address:addr2;<br>
                                                    </mvt:if>
                                                    <mvt:if expr="(NOT ISNULL l.settings:address:city) AND (NOT ISNULL l.settings:address:state)">
                                                        &mvte:address:city;, &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                                    <mvt:else>
                                                        &mvte:address:city; &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                                    </mvt:if>
                                                </mvt:if>
                                            </p>
                                            <hr class="c-keyline c-keyline--small">
                                        </mvt:if>
                                    </mvt:foreach>
                                </div>
                                <div class="o-layout__item">
                                    <mvt:assign name="l.settings:bill_address_count" value="0"/>
                                    <mvt:foreach array="customer:validated_bill_addresses" iterator="address">
                                        <mvt:if expr="l.settings:address:validated">
                                            <label class="c-form-checkbox">
                                                <input class="c-form-checkbox__input" type="radio" name="BillValidatedSelector" data-mm_address_addr1="&mvte:address:addr1;" data-mm_address_addr2="&mvte:address:addr2;" data-mm_address_city="&mvte:address:city;" data-mm_address_comp="&mvte:address:comp;" data-mm_address_country="&mvte:address:country;" data-mm_address_state="&mvte:address:state;" data-mm_address_zip="&mvte:address:zip;" aria-describedby="bill-address-&mvte:bill_address_count;">
                                                <span class="c-form-checkbox__caption u-text-bold">Verified&nbsp;<span class="u-hide-visually">Billing&nbsp;</span>Address <span class="u-hide-visually">&mvte:address_count;</span></span>
                                            </label>
                                            <p id="bill-address-&mvte:bill_address_count;" class="u-font-small">
                                                <mvt:if expr="NOT ISNULL l.settings:address:comp">
                                                    &mvte:address:comp;<br>
                                                </mvt:if>
                                                <mvt:if expr="NOT ISNULL l.settings:address:addr1 OR NOT ISNULL l.settings:address:addr2 OR NOT ISNULL l.settings:address:city OR NOT ISNULL l.settings:address:state OR NOT ISNULL l.settings:address:zip OR NOT ISNULL l.settings:address:cntry">
                                                    &mvte:address:addr1;<br>
                                                    <mvt:if expr="NOT ISNULL l.settings:address:addr2">
                                                        &mvte:address:addr2;<br>
                                                    </mvt:if>
                                                    <mvt:if expr="(NOT ISNULL l.settings:address:city) AND (NOT ISNULL l.settings:address:state)">
                                                        &mvte:address:city;, &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                                    <mvt:else>
                                                        &mvte:address:city; &mvte:address:state; &mvte:address:zip; &mvte:address:country;
                                                    </mvt:if>
                                                </mvt:if>
                                            </p>
                                            <hr class="c-keyline c-keyline--small">
                                            <mvt:assign name="l.settings:bill_address_count" value="l.settings:bill_address_count + 1"/>
                                        </mvt:if>
                                    </mvt:foreach>
                                </div>
                            </div>
                        </mvt:if>
                    </mvt:if>
                    <br>
                    <div class="c-control-group o-layout--justify-end">
                        <button class="c-button c-button--hollow c-control-group__button u-color-primary" data-edit-address>Cancel</button>
                        <button class="c-button c-control-group__button u-bg-primary" data-update-address>Update Address</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script>
        (function () {
            'use strict';

            const billAddresses = document.querySelectorAll('[name="BillValidatedSelector"]');
            const cancel = document.querySelector('[data-edit-address]');
            const dialogElement = document.querySelector('[data-dialog="address-validation"]');
            const formElement = document.querySelector('[data-validate-address]');
            const shipAddresses = document.querySelectorAll('[name="ShipValidatedSelector"]');
            const showBilling = document.querySelector('[data-billing-shown]');
            const update = document.querySelector('[data-update-address]');
            let billPrefix;
            let shipPrefix;

            if (formElement.elements.hasOwnProperty('Action') && (formElement.elements.Action.value === 'ORDR')) {
                billPrefix = 'Bill';
                shipPrefix = 'Ship';
            }
            else if (formElement.elements.hasOwnProperty('Action') && (formElement.elements.Action.value === 'ICST' || formElement.elements.Action.value === 'UCST')) {
                billPrefix = 'Customer_Bill';
                shipPrefix = 'Customer_Ship';
            }
            else if (formElement.elements.hasOwnProperty('Action') && (formElement.elements.Action.value === 'ICSA' || formElement.elements.Action.value === 'UCSA')) {
                billPrefix = null;
                shipPrefix = 'Address_';
            }

            function findFormInputs(form, prefix) {
                return {
                    billing: {
                        addr1: form.elements[prefix + 'Address1'],
                        addr2: form.elements[prefix + 'Address2'],
                        city: form.elements[prefix + 'City'],
                        state: form.elements[prefix + 'State'],
                        stateSelect: form.elements[prefix + 'StateSelect'],
                        country: form.elements[prefix + 'Country'],
                        zip: form.elements[prefix + 'Zip'],
                        validated: form.elements[prefix + 'Validated']
                    },
                    shipping: {
                        addr1: form.elements[prefix + 'Address1'],
                        addr2: form.elements[prefix + 'Address2'],
                        city: form.elements[prefix + 'City'],
                        state: form.elements[prefix + 'State'],
                        stateSelect: form.elements[prefix + 'StateSelect'],
                        country: form.elements[prefix + 'Country'],
                        zip: form.elements[prefix + 'Zip'],
                        validated: form.elements[prefix + 'Validated']
                    }
                };
            }

            function getSelectedShipAddress() {
                for (let i = 0; i < shipAddresses.length; i++) {
                    if (shipAddresses[i].checked) {
                        return {
                            addr1: typeof shipAddresses[i].getAttribute('data-mm_address_addr1') === 'string' ? shipAddresses[i].getAttribute('data-mm_address_addr1') : '',
                            addr2: typeof shipAddresses[i].getAttribute('data-mm_address_addr2') === 'string' ? shipAddresses[i].getAttribute('data-mm_address_addr2') : '',
                            city: typeof shipAddresses[i].getAttribute('data-mm_address_city') === 'string' ? shipAddresses[i].getAttribute('data-mm_address_city') : '',
                            state: typeof shipAddresses[i].getAttribute('data-mm_address_state') === 'string' ? shipAddresses[i].getAttribute('data-mm_address_state') : '',
                            country: typeof shipAddresses[i].getAttribute('data-mm_address_country') === 'string' ? shipAddresses[i].getAttribute('data-mm_address_country') : '',
                            zip: typeof shipAddresses[i].getAttribute('data-mm_address_zip') === 'string' ? shipAddresses[i].getAttribute('data-mm_address_zip') : ''
                        };
                    }
                }
            }

            function getSelectedBillAddress() {
                for (let i = 0; i < billAddresses.length; i++) {
                    if (billAddresses[i].checked) {
                        return {
                            addr1: typeof billAddresses[i].getAttribute('data-mm_address_addr1') === 'string' ? billAddresses[i].getAttribute('data-mm_address_addr1') : '',
                            addr2: typeof billAddresses[i].getAttribute('data-mm_address_addr2') === 'string' ? billAddresses[i].getAttribute('data-mm_address_addr2') : '',
                            city: typeof billAddresses[i].getAttribute('data-mm_address_city') === 'string' ? billAddresses[i].getAttribute('data-mm_address_city') : '',
                            state: typeof billAddresses[i].getAttribute('data-mm_address_state') === 'string' ? billAddresses[i].getAttribute('data-mm_address_state') : '',
                            country: typeof billAddresses[i].getAttribute('data-mm_address_country') === 'string' ? billAddresses[i].getAttribute('data-mm_address_country') : '',
                            zip: typeof billAddresses[i].getAttribute('data-mm_address_zip') === 'string' ? billAddresses[i].getAttribute('data-mm_address_zip') : ''
                        };
                    }
                }
            }

            function setFirstSuggestion() {
                for (let i = 0; i < shipAddresses.length; i++) {
                    if (shipAddresses.length === 1) {
                        shipAddresses[0].checked = true;
                    }
                    else if (shipAddresses.length > 1) {
                        shipAddresses[1].checked = true;
                    }
                }

                if (showBilling !== null) {
                    for (let i = 0; i < billAddresses.length; i++) {
                        if (billAddresses.length === 1) {
                            billAddresses[0].checked = true;
                        }
                        else if (billAddresses.length > 1) {
                            billAddresses[1].checked = true;
                        }
                    }
                }
            }

            cancel.addEventListener('click', function (clickEvent) {
                clickEvent.preventDefault();
                findFormInputs(formElement, shipPrefix).shipping.validated.value = 0;
                if (showBilling !== null) {
                    findFormInputs(formElement, billPrefix).billing.validated.value = 0;
                }
                window.closeDialog();
            });

            update.addEventListener('click', function (clickEvent) {
                clickEvent.preventDefault();
                findFormInputs(formElement, shipPrefix).shipping.addr1.value = getSelectedShipAddress().addr1;
                findFormInputs(formElement, shipPrefix).shipping.addr2.value = getSelectedShipAddress().addr2;
                findFormInputs(formElement, shipPrefix).shipping.city.value = getSelectedShipAddress().city;
                findFormInputs(formElement, shipPrefix).shipping.state.value = getSelectedShipAddress().state;
                findFormInputs(formElement, shipPrefix).shipping.stateSelect.value = getSelectedShipAddress().state;
                findFormInputs(formElement, shipPrefix).shipping.country.value = getSelectedShipAddress().country;
                findFormInputs(formElement, shipPrefix).shipping.zip.value = getSelectedShipAddress().zip;
                if (billPrefix !== null) {
                    if (showBilling !== null) {
                        findFormInputs(formElement, billPrefix).billing.addr1.value = getSelectedBillAddress().addr1;
                        findFormInputs(formElement, billPrefix).billing.addr2.value = getSelectedBillAddress().addr2;
                        findFormInputs(formElement, billPrefix).billing.city.value = getSelectedBillAddress().city;
                        findFormInputs(formElement, billPrefix).billing.state.value = getSelectedBillAddress().state;
                        findFormInputs(formElement, billPrefix).billing.stateSelect.value = getSelectedBillAddress().state;
                        findFormInputs(formElement, billPrefix).billing.country.value = getSelectedBillAddress().country;
                        findFormInputs(formElement, billPrefix).billing.zip.value = getSelectedBillAddress().zip;
                    }
                    else {
                        findFormInputs(formElement, billPrefix).billing.addr1.value = getSelectedShipAddress().addr1;
                        findFormInputs(formElement, billPrefix).billing.addr2.value = getSelectedShipAddress().addr2;
                        findFormInputs(formElement, billPrefix).billing.city.value = getSelectedShipAddress().city;
                        findFormInputs(formElement, billPrefix).billing.state.value = getSelectedShipAddress().state;
                        findFormInputs(formElement, billPrefix).billing.stateSelect.value = getSelectedShipAddress().state;
                        findFormInputs(formElement, billPrefix).billing.country.value = getSelectedShipAddress().country;
                        findFormInputs(formElement, billPrefix).billing.zip.value = getSelectedShipAddress().zip;
                    }
                }
                window.closeDialog();
                formElement.submit();
            });

            /**
             * When closing the dialog by clicking on the `X`, set the hidden input confirming that
             * the address has been validated to `0`.
             */
            document.querySelector('[data-dialog-close]').addEventListener('click', function (clickEvent) {
                if (dialogElement) {
                    if (dialogElement.getAttribute('aria-hidden') === 'false') {
                        findFormInputs(formElement, shipPrefix).shipping.validated.value = 0;
                        if (showBilling !== null) {
                            findFormInputs(formElement, billPrefix).billing.validated.value = 0;
                        }
                    }
                }
            });

            /**
             * When closing the dialog by clicking on the background, set the hidden input confirming that
             * the address has been validated to `0`.
             */
            document.addEventListener('click', function (clickEvent) {
                let clickEventTarget = clickEvent.target;

                if (dialogElement) {
                    if (clickEventTarget === dialogElement.firstElementChild) {
                        if (dialogElement.getAttribute('aria-hidden') === 'false') {
                            findFormInputs(formElement, shipPrefix).shipping.validated.value = 0;
                            if (showBilling !== null) {
                                findFormInputs(formElement, billPrefix).billing.validated.value = 0;
                            }
                        }
                    }
                }
            });

            /**
             * On page load, open the dialog and set the first suggestion as `checked`.
             */
            window.addEventListener('load', function () {
                if (showBilling !== null) {
                    document.querySelector('#billing_to_show').click();
                }
                window.openDialog('address-validation');
                setFirstSuggestion();
            });
        }());
    </script>
</mvt:if>