PageSourceSearch

https://diocesan.com/wp-content/themes/diocesan2025/assets/js/address-validation.js?ver=7.1.2

js diocesan.com collected 2026-10-01 13:13:28 UTC 11,527 bytes, 309 lines download raw bytes

1jQuery(function ($) {
2
3    // --------------------------------------------------
4    // Helpers
5    // --------------------------------------------------
6
7    function normalize(str) {
8        return (str || '').toString().trim().toUpperCase().replace(/\s+/g, ' ');
9    }
10
11    function setAlert($box, type, html) {
12        var cls = 'mb-2 ';
13
14        switch (type) {
15            case 'validating': cls += 'alert alert-secondary'; break;
16            case 'suggestion': cls += ''; break;
17            case 'success':    cls += 'alert alert-success'; break;
18            case 'error':      cls += 'alert alert-danger'; break;
19            default:           cls += 'alert alert-light border';
20        }
21
22        $box
23            .removeClass()
24            .addClass(cls)
25            .html(html)
26            .stop(true, true)
27            .fadeIn(150);
28    }
29
30    // --------------------------------------------------
31    // Initializer (runs once per form)
32    // --------------------------------------------------
33
34    function initForm($form) {
35
36        if ($form.data('address-validation-ready')) {
37            return;
38        }
39        $form.data('address-validation-ready', true);
40
41        var $address1 = $form.find('[name="address1"]');
42        var $address2 = $form.find('[name="address2"]');
43        var $city     = $form.find('[name="city"]');
44        var $state    = $form.find('[name="stateCode"]');
45        var $zip      = $form.find('[name="zipCode"]');
46
47        if (! $address1.length || ! $city.length || ! $state.length || ! $zip.length) {
48            return;
49        }
50
51        var $inputs = $form.find(
52            '[name="address1"], ' +
53            '[name="address2"], ' +
54            '[name="city"], ' +
55            '[name="stateCode"], ' +
56            '[name="zipCode"]'
57        );
58
59        var $suggestionBox = $form.find('.address-suggestion');
60        if (! $suggestionBox.length) {
61            var $submit = $form.find(':submit').last();
62
63            $suggestionBox = $('<div class="address-suggestion mb-2" style="display:none;"></div>');
64
65            if ($submit.length) {
66                $suggestionBox.insertBefore($submit);
67            } else {
68                $suggestionBox.appendTo($form);
69            }
70        }
71
72        function findApplyButton() {
73
74            // 1. Prefer submit buttons inside the form
75            var $btn = $form.find(':submit').last();
76            if ($btn.length) {
77                return $btn;
78            }
79
80            // 2. Fallback: external submit button using form attribute
81            var formId = $form.attr('id');
82            if (! formId) {
83                return $();
84            }
85
86            return $(':submit[form="' + formId + '"]').last();
87        }
88
89        function setApplyEnabled(enabled) {
90            var $btn = findApplyButton();
91            if (! $btn.length) {
92                return;
93            }
94
95            $btn
96                .prop('disabled', !enabled)
97                .toggleClass('disabled', !enabled);
98        }
99
100        function applyAddress(addr) {
101            if (! addr) {
102                return;
103            }
104
105            $address1.val(addr.address1);
106            $address2.val(addr.address2 || '');
107            $city.val(addr.city);
108            $state.val(addr.state);
109            $zip.val(addr.zip);
110        }
111
112        function collect() {
113            return {
114                address1: $address1.val(),
115                address2: $address2.val(),
116                city:     $city.val(),
117                state:    $state.val(),
118                zip:      $zip.val()
119            };
120        }
121
122        var lastValidated = null;
123        var blurTimer = null;
124        var suppressValidation = false;
125
126        setApplyEnabled(false);
127
128        // --------------------------------------------------
129        // Form submission loading state
130        // --------------------------------------------------
131
132        $form.on('submit', function () {
133
134            var $btn = findApplyButton();
135            if (! $btn.length || $btn.prop('disabled')) {
136                return false;
137            }
138
139            var originalHtml = $btn.html();
140
141            $btn
142                .data('original-html', originalHtml)
143                .prop('disabled', true)
144                .addClass('disabled opacity-50')
145                .html(
146                    '<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>' +
147                    'Saving...'
148                );
149        });
150
151        // --------------------------------------------------
152        // Validation on blur
153        // --------------------------------------------------
154
155        $inputs.on('blur', function () {
156
157            if (suppressValidation) {
158                return;
159            }
160
161            clearTimeout(blurTimer);
162
163            blurTimer = setTimeout(function () {
164
165                var data = collect();
166                if (! data.address1 || ! data.city || ! data.state || ! data.zip) {
167                    return;
168                }
169
170                var normalized = JSON.stringify({
171                    address1: normalize(data.address1),
172                    address2: normalize(data.address2),
173                    city:     normalize(data.city),
174                    state:    normalize(data.state),
175                    zip:      normalize(data.zip)
176                });
177
178                if (normalized === lastValidated) {
179                    return;
180                }
181                lastValidated = normalized;
182
183                setApplyEnabled(false);
184
185                setAlert(
186                    $suggestionBox,
187                    'validating',
188                    '<div class="d-flex align-items-center">' +
189                        '<div class="spinner-border spinner-border-sm me-2"></div>' +
190                        'Validating address...' +
191                    '</div>'
192                );
193
194                $.post('/wp-json/dpi/v1/validate-address', data)
195                    .done(function (response) {
196
197                        if (response && response.suggestion) {
198                            var s = response.suggestion;
199
200                            var differs =
201                                normalize(s.address1) !== normalize(data.address1) ||
202                                normalize(s.address2) !== normalize(data.address2) ||
203                                normalize(s.city)     !== normalize(data.city) ||
204                                normalize(s.state)    !== normalize(data.state) ||
205                                normalize(s.zip)      !== normalize(data.zip);
206
207                            if (differs) {
208
209                                var enteredHtml =
210                                    data.address1 + '<br>' +
211                                    (data.address2 ? data.address2 + '<br>' : '') +
212                                    data.city + ', ' + data.state + ' ' + data.zip;
213
214                                var recommendedHtml =
215                                    s.address1 + '<br>' +
216                                    (s.address2 ? s.address2 + '<br>' : '') +
217                                    s.city + ', ' + s.state + ' ' + s.zip;
218
219                                var html =
220                                    '<div class="fw-semibold w-100 mb-1 small">Confirm Address:</div>' +
221
222                                    '<div class="border border-2 rounded-3 p-2 mb-1">' +
223                                        '<label class="d-flex gap-2 align-items-start">' +
224                                            '<input type="radio" name="address_choice" value="entered">' +
225                                            '<div>' +
226                                                '<div class="fw-semibold fs-xs lh-sm">What you entered</div>' +
227                                                '<div class="small text-muted">' + enteredHtml + '</div>' +
228                                            '</div>' +
229                                        '</label>' +
230                                    '</div>' +
231
232                                    '<div class="border border-2 rounded-3 p-2">' +
233                                        '<label class="d-flex gap-2 align-items-start">' +
234                                            '<input type="radio" name="address_choice" value="recommended">' +
235                                            '<div>' +
236                                                '<div class="fw-semibold fs-xs lh-sm">Recommended</div>' +
237                                                '<div class="small text-muted">' + recommendedHtml + '</div>' +
238                                            '</div>' +
239                                        '</label>' +
240                                    '</div>';
241
242                                $suggestionBox
243                                    .data('entered', data)
244                                    .data('recommended', s);
245
246                                setAlert($suggestionBox, 'suggestion', html);
247                                setApplyEnabled(false);
248                                return;
249                            }
250                        }
251
252                        if (response && response.error) {
253                            setAlert($suggestionBox, 'error', 'This address might be invalid or incomplete.');
254                            setApplyEnabled(false);
255                            return;
256                        }
257
258                        setAlert($suggestionBox, 'success', 'Address validated successfully.');
259                        $suggestionBox.delay(2000).fadeOut(200);
260                        setApplyEnabled(true);
261                    })
262                    .fail(function () {
263                        setAlert($suggestionBox, 'error', 'Unable to validate address at this time.');
264                        setApplyEnabled(false);
265                        $suggestionBox.delay(2500).fadeOut(200);
266                    });
267
268            }, 300);
269        });
270
271        // --------------------------------------------------
272        // Radio selection = enable submit (no revalidation)
273        // --------------------------------------------------
274
275        $form.on('change', 'input[name="address_choice"]', function () {
276
277            var choice = this.value;
278            var addr   = $suggestionBox.data(choice);
279
280            if (choice === 'recommended') {
281                suppressValidation = true;
282                applyAddress(addr);
283
284                setTimeout(function () {
285                    suppressValidation = false;
286                }, 0);
287            }
288
289            setApplyEnabled(true);
290        });
291    }
292
293    // --------------------------------------------------
294    // Lazy auto-init on first interaction
295    // --------------------------------------------------
296
297    $(document).on(
298        'focus blur change',
299        'form.validate-address [name="address1"], ' +
300        'form.validate-address [name="address2"], ' +
301        'form.validate-address [name="city"], ' +
302        'form.validate-address [name="stateCode"], ' +
303        'form.validate-address [name="zipCode"]',
304        function () {
305            initForm($(this).closest('form.validate-address'));
306        }
307    );
308
309});

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.