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.