PageSourceSearch

https://www.aucklandnz.com/js/scripts/updatableFormHelper.js?v=20260806.1

js aucklandnz.com collected 2026-09-24 18:49:28 UTC 7,404 bytes, 195 lines download raw bytes

1window.kentico = window.kentico || {};
2
3window.kentico.updatableFormHelper = (function () {
4
5    // Duration for which user must not type anything in order for the form to be submitted.
6    var KEY_UP_DEBOUNCE_DURATION = 800;
7
8    /**
9     * Registers event listeners and updates the form upon changes of the form data.
10     * @param {object} config Configuration object.
11     * @param {string} config.formId ID of the form element.
12     * @param {string} config.targetAttributeName Data attribute of element that is used to be replaced by HTML received from the server.
13     * @param {string} config.unobservedAttributeName Data attribute which marks an input as not being observed for changes.
14     */
15    function registerEventListeners(config) {
16        if (!config || !config.formId || !config.targetAttributeName || !config.unobservedAttributeName) {
17            throw new Error("Invalid configuration passed.");
18        }
19
20        var writeableTypes = ["email", "number", "password", "search", "tel", "text", "time"];
21
22        var observedForm = document.getElementById(config.formId);
23        if (!(observedForm && observedForm.getAttribute(config.targetAttributeName))) {
24            return;
25        }
26
27        for (i = 0; i < observedForm.length; i++) {
28            var observedFormElement = observedForm.elements[i];
29            var handleElement = !observedFormElement.hasAttribute(config.unobservedAttributeName) &&
30                observedFormElement.type !== "submit";
31
32            if (handleElement) {
33                var isWriteableElement = (observedFormElement.tagName === "INPUT" && writeableTypes.indexOf(observedFormElement.type) !== -1) || observedFormElement.tagName === "TEXTAREA";
34
35                if (isWriteableElement) {
36                    observedFormElement.previousValue = observedFormElement.value;
37
38                    observedFormElement.addEventListener("keyup", debounce(function (e) {
39                        setTimeout(function () {
40                            if (!observedForm.updating && e.target.previousValue !== e.target.value) {
41                                observedForm.keyupUpdate = true;
42                                updateForm(observedForm, e.target);
43                            }
44                        }, 0);
45                    }, KEY_UP_DEBOUNCE_DURATION));
46
47                    observedFormElement.addEventListener("blur", function (e) {
48                        setTimeout(function () {
49                            if (!observedForm.updating && e.target.previousValue !== e.target.value) {
50                                updateForm(observedForm, e.relatedTarget);
51                            }
52                        }, 0);
53                    });
54                }
55
56                observedFormElement.addEventListener("change", function (e) {
57                    setTimeout(function () {
58                        if (!observedForm.updating) {
59                            updateForm(observedForm);
60                        }
61                    }, 0);
62                });
63            }
64        }
65    }
66
67    /**
68     * Updates the form markup.
69     * @param {HTMLElement} form Element of the form to update.
70     * @param {Element} nextFocusElement Element which shout get focus after update.
71     */
72    function updateForm(form, nextFocusElement) {
73        if (!form) {
74            return;
75        }
76
77        // If form is not updatable then do nothing 
78        var elementIdSelector = form.getAttribute("data-ktc-ajax-update");
79        if (!elementIdSelector) {
80            return;
81        }
82
83        $(form).find("input[type='submit']").attr("onclick", "return false;");
84        form.updating = true;
85
86        var formData = new FormData(form);
87        formData.append("kentico_update_form", "true");
88
89        var focus = nextFocusElement || document.activeElement;
90
91        var onResponse = function (event) {
92            if (!event.target.response.data) {
93                var selectionStart = selectionEnd = null;
94                if (focus && (focus.type === "text" || focus.type === "search" || focus.type === "password" || focus.type === "tel" || focus.type === "url")) {
95                    selectionStart = focus.selectionStart;
96                    selectionEnd = focus.selectionEnd;
97                }
98
99                var currentScrollPosition = $(window).scrollTop();
100                $(elementIdSelector).replaceWith(event.target.responseText);
101                $(window).scrollTop(currentScrollPosition);
102
103                if (focus.id) {
104                    var newInput = document.getElementById(focus.id);
105                    if (newInput) {
106                        newInput.focus();
107                        setCaretPosition(newInput, selectionStart, selectionEnd);
108                    }
109                }
110            }
111        };
112
113        createRequest(form, formData, onResponse);
114    }
115
116    function submitForm(event) {
117        event.preventDefault();
118        var form = event.target;
119        var formData = new FormData(form);
120
121        var onResponse = function(event) {
122            var contentType = event.target.getResponseHeader("Content-Type");
123
124            if (contentType.indexOf("application/json") === -1) {
125                var currentScrollPosition = $(window).scrollTop();
126                var replaceTarget = form.getAttribute("data-ktc-ajax-update");
127
128                $(replaceTarget).replaceWith(event.target.response);
129                $(window).scrollTop(currentScrollPosition);
130            } else {
131                var json = JSON.parse(event.target.response);
132
133                location.href = json.redirectTo;
134            }
135        };
136
137        createRequest(form, formData, onResponse);
138    }
139
140    function createRequest(form, formData, onResponse) {
141        var xhr = new XMLHttpRequest();
142
143        xhr.addEventListener("load", onResponse);
144
145        xhr.open("POST", form.action);
146        xhr.send(formData);
147    }
148
149    /**
150     * Sets the caret position.
151     * @param {HTMLInputElement} input Input element in which the caret position should be set.
152     * @param {number} selectionStart Selection start position.
153     * @param {number} selectionEnd Selection end position.
154     */
155    function setCaretPosition(input, selectionStart, selectionEnd) {
156        if (selectionStart === null && selectionEnd === null) {
157            return;
158        }
159
160        if (input.setSelectionRange) {
161            input.setSelectionRange(selectionStart, selectionEnd);
162        }
163    }
164
165    function debounce(func, wait, immediate) {
166        var timeout;
167
168        return function () {
169            var context = this,
170                args = arguments;
171
172            var later = function () {
173                timeout = null;
174
175                if (!immediate) {
176                    func.apply(context, args);
177                }
178            };
179
180            var callNow = immediate && !timeout;
181            clearTimeout(timeout);
182            timeout = setTimeout(later, wait || 200);
183
184            if (callNow) {
185                func.apply(context, args);
186            }
187        };
188    }
189
190    return {
191        registerEventListeners: registerEventListeners,
192        updateForm: updateForm,
193        submitForm: submitForm
194    };
195}());

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.