PageSourceSearch

https://public.hiscox.fr/Scripts/runtime-questions.js?v=_URTf8QKWmDgqXH-lFppb-jZ7eiVMsAm9b0llxy5qCQ1

js hiscox.fr collected 2026-09-26 00:34:42 UTC 134,480 bytes, 2,752 lines download raw bytes

1/* Minification failed. Returning unminified contents.
2(1718,18-20): run-time error JS1008: Expected '{': =>
3(1723,1-6): run-time error JS1010: Expected identifier: class
4(1724,11): run-time error JS1004: Expected ';'
5(1725,11): run-time error JS1004: Expected ';'
6(1726,11): run-time error JS1004: Expected ';'
7(1728,22): run-time error JS1004: Expected ';'
8(1734,1-6): run-time error JS1010: Expected identifier: const
9(1734,103-104): run-time error JS1008: Expected '{': ;
10(1734,1): run-time error JS1301: End of file encountered before function is properly closed
11(2737,1): run-time error JS1107: Expecting more source characters
12(2737,1): run-time error JS1009: Expected '}'
13(1726,12-17): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: Radio
14(1725,12-24): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: Autocomplete
15(1724,12-20): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: Dropdown
16 */
17const addressConstants = {
18    addressQuestionContainer: ".instanda-address-question-container",
19    contentType: "application/json",
20    instandaAddressCountry: ".instanda-address-country",
21    displayNone: "display: none;",
22    addressPostcodeLookup: ".instanda-address-postcode-lookup",
23    addressPostcodeLookupResults: ".instanda-address-postcode-lookup-results",
24    singleAddress: ".single-line-address"
25};
26
27document.addEventListener("DOMContentLoaded", () => {
28    let addressQuestions = document.querySelectorAll(addressConstants.addressQuestionContainer);
29    addressQuestions.forEach((addressQuestion) => {
30        let data8option = addressQuestion.querySelector("input[name$='Data8AddressValidation']").value;
31        if (data8option === 'PredictiveAddress') {
32            if (addressQuestion.querySelector(addressConstants.singleAddress) && addressQuestion.querySelector("input[name='HasValidationErrors']").value === 'True') {
33                onAddressDetailEdit(addressQuestion);
34            } else {
35                predictiveAddress(addressQuestion);
36            }
37        }
38    });
39});
40
41function predictiveAddress(container) {
42    let inputToSearch;
43    if (container.querySelector(addressConstants.singleAddress)) {
44        inputToSearch = container.querySelector(addressConstants.singleAddress);
45    } else {
46        inputToSearch = container.querySelector(".instanda-address-line-1").querySelector("input");
47    }
48
49    fetch(container.querySelector('input[name$="PredictiveAddressSettings"]').value, {
50        method: 'GET',
51        headers: {
52            'Content-Type': addressConstants.contentType,
53            'Accept': addressConstants.contentType,
54            'X-Requested-With': 'XMLHttpRequest'
55        }
56    })
57        .then(res => res.json())
58        .then(data => {
59            let options = {
60                ajaxKey: data.ajaxKey,
61                fields: [
62                    { element: getAddressElement(container, 'line-1'), field: 'line1' },
63                    { element: getAddressElement(container, 'line-2'), field: 'line2' },
64                    { element: getAddressElement(container, 'city'), field: 'town' },
65                    { element: getAddressElement(container, 'county'), field: 'county' },
66                    { element: getAddressElement(container, 'state'), field: 'county' }, // county acts like state in us/ca/aus
67                    { element: getAddressElement(container, 'postcode'), field: 'postcode' },
68                    { element: getAddressElement(container, 'country'), field: 'country' }
69                ],
70                customFormatterOptions: {
71                    Formatter: data.formatter,
72                    UseAbbreviations: data.useAbbreviations
73                }
74            };
75
76            if (container.querySelector(addressConstants.instandaAddressCountry) === null) {
77                options.allowedCountries = [container.querySelector(addressConstants.instandaAddressCountry).value];
78            }
79
80            try {
81                new data8.predictiveaddressui(inputToSearch, options);
82            } catch (e) {
83                console.log("INS-11765 Data8 error: from _AddressQuestion.cshtml" + e);
84            }
85        }).catch(err => console.log("Data8 error: from _AddressQuestion.cshtml" + err));
86}
87
88function getAddressElement(container, name) {
89    if (name === 'country' || name === 'state') {
90        if (container.querySelector(`.instanda-address-${name}`) !== null) {
91            return container.querySelector(`.instanda-address-${name}`).querySelector("select");
92        } else {
93            return '';
94        }
95    } else {
96        if (container.querySelector(`.instanda-address-${name}`) !== null) {
97            return container.querySelector(`.instanda-address-${name}`).querySelector("input");
98        } else {
99            return '';
100        }
101    }
102}
103
104function onAddressDetailEdit(el) {
105    let container = el.closest(addressConstants.addressQuestionContainer)
106    let singleLine = container.querySelector(".instanda-address-single-line");
107    let addressDetails = container.querySelectorAll("div.instanda-address-detail");
108    let cancelButton = container.querySelector(".address-search-cancel");
109    singleLine.setAttribute("style", addressConstants.displayNone);
110    addressDetails.forEach(d => d.setAttribute("style", "display: block;"));
111    cancelButton.removeAttribute("style");
112
113    if (container.querySelector(addressConstants.addressPostcodeLookup) !== null) {
114        container.querySelector(addressConstants.addressPostcodeLookup).setAttribute("style", addressConstants.displayNone);
115    }
116}
117
118function onAddressDetailCancel(el) {
119    let container = el.closest(addressConstants.addressQuestionContainer)
120    let singleLine = container.querySelector(".instanda-address-single-line");
121    let addressDetails = container.querySelectorAll("div.instanda-address-detail");
122    let editButton = container.querySelector(".address-search-edit");
123    singleLine.setAttribute("style", "display: block;");
124    addressDetails.forEach(d => d.setAttribute("style", addressConstants.displayNone));
125    editButton.removeAttribute("style");
126
127    if (container.querySelector(addressConstants.addressPostcodeLookup) !== null) {
128        container.querySelector(addressConstants.addressPostcodeLookup).removeAttribute("style")
129    }
130}
131
132function onAddressCountryChange(el, optionLabel) {
133    let container = el.closest(addressConstants.addressQuestionContainer)
134    let state = container.querySelector(".instanda-address-state");
135    let country = container.querySelector(addressConstants.instandaAddressCountry);
136    let stateSelect = state.querySelector("select");
137    let selectedValue = stateSelect.value
138    stateSelect.innerHTML = "";
139    if (el.value === "US") {
140        state.removeAttribute("style");
141        state.querySelector("label").innerHTML = "State";
142        stateSelect.add(new Option(optionLabel, "", false, true));
143        JSON.parse(country.querySelector("#USStates").value).forEach((state) => {
144            stateSelect.add(new Option(state.Text, state.Value, false, state.Selected));
145        })
146        reAssignSelectValue(stateSelect, selectedValue);
147    } else if (el.value === "CA") {
148        state.removeAttribute("style");
149        state.querySelector("label").innerHTML = "Province";
150        stateSelect.add(new Option(optionLabel, "", false, true));
151        JSON.parse(country.querySelector("#CAProvinces").value).forEach((state) => {
152            stateSelect.add(new Option(state.Text, state.Value, false, state.Selected));
153        })
154        reAssignSelectValue(stateSelect, selectedValue);
155    } else if (el.value === "AU") {
156        state.removeAttribute("style");
157        state.querySelector("label").innerHTML = "State";
158        stateSelect.add(new Option(optionLabel, "", false, true));
159        JSON.parse(country.querySelector("#AUSStates").value).forEach((state) => {
160            stateSelect.add(new Option(state.Text, state.Value, false, state.Selected));
161        })
162        reAssignSelectValue(stateSelect, selectedValue);
163    } else {
164        state.setAttribute("style", addressConstants.displayNone);
165    }
166}
167
168function reAssignSelectValue(select, value) {
169    if (select !== null && select.innerHTML.indexOf('value="' + value + '"') > -1) {
170        select.value = value;
171    }
172}
173
174function onFindAddressClicked(el, questionId, postcodeBlankMessage, data8ErrorMessage) {
175    let container = el.closest(addressConstants.addressQuestionContainer);
176    let postcode = container.querySelector("div.instanda-address-postcode-lookup div.instanda-address-postcode input").value;
177    if (postcode === "") {
178        let alertMessage = !postcodeBlankMessage || postcodeBlankMessage.length === 0
179            ? 'Please enter the postcode'
180            : postcodeBlankMessage
181        alert(alertMessage);
182        return;
183    }
184
185    let resultContainer = container.querySelector(addressConstants.addressPostcodeLookupResults);
186    let selectedInput = container.querySelector(".instanda-address-single-line input");
187    selectedInput.style = "display:none;";
188    selectedInput.value = "";
189
190    fetch(`GetAddressListForPostcode?postcode=${postcode}&questionid=${questionId}`, {
191        method: 'GET',
192        headers: {
193            'Content-Type': addressConstants.contentType,
194            'Accept': addressConstants.contentType,
195            'X-Requested-With': 'XMLHttpRequest'
196        }
197    })
198        .then(res => res.json())
199        .then(data => {
200            let addresses = data.Results;
201            if (addresses.length > 0) {
202                resultContainer.innerHTML = "";
203                addresses.forEach((address) => {
204                    resultContainer.innerHTML += `
205                        <div class="address-result">
206                            <button type="button" onclick="onAddressSelected(this)">Select</button>
207                            <span class="address-line">${address.Address.Lines.join(" ")}</span>
208                            <div class="address-result-details" style="display: none;">
209                                <span class="BuildingNumber">${address.RawAddress.BuildingNumber}</span>
210                                <span class="SubBuildingName">${address.RawAddress.SubBuildingName}</span>
211                                <span class="BuildingName">${address.RawAddress.BuildingName}</span>
212                                <span class="ThoroughfareName">${address.RawAddress.ThoroughfareName}</span>
213                                <span class="ThoroughfareDesc">${address.RawAddress.ThoroughfareDesc}</span>
214                                <span class="DependentLocality">${address.RawAddress.DependentLocality}</span>
215                                <span class="AddressLines">${address.Address.Lines.join(",")}</span>
216                            </div>
217                        </div>
218                        `;
219                });
220                resultContainer.innerHTML += `
221                    <div class="address-result">
222                        <button type="button" onclick="discardResult(this)">None of the above</button>
223                    </div>
224                    `;
225            } else {
226                alert(data.Status.ErrorMessage);
227            }
228        }).catch(() => alert(data8ErrorMessage));
229}
230
231function discardResult(el) {
232    let resultContainer = el.closest(addressConstants.addressPostcodeLookupResults);
233    resultContainer.innerHTML = "";
234}
235
236function onAddressSelected(el) {
237    let container = el.closest(addressConstants.addressQuestionContainer);
238    let addressResult = el.closest(".address-result");
239    let addressLines = el.closest(".address-result").querySelector(".AddressLines").innerHTML;
240    let selectedInput = container.querySelector(".instanda-address-single-line input");
241    let addresses = container.querySelector(addressConstants.addressPostcodeLookupResults);
242    selectedInput.removeAttribute("style");
243    selectedInput.setAttribute("disabled", "disabled");
244    selectedInput.setAttribute("readonly", "readonly");
245    selectedInput.value = addressLines.replace(/,{2,}/g, ",").replace(/,/g, ", ");
246    addresses.innerHTML = "";
247
248    let addressData = addressResult.querySelector("div.address-result-details");
249    updateAddressFields(container, addressData);
250}
251
252function updateAddressFields(container, addressData) {
253    let addressLine1 = container.querySelector("div.instanda-address-line-1 input");
254    let addressLine2 = container.querySelector("div.instanda-address-line-2 input");
255    let buildingNumber = container.querySelector("div.instanda-address-building-number input");
256    let buildingName = container.querySelector("div.instanda-address-building-name input");
257    let street = container.querySelector("div.instanda-address-street input");
258    let locality = container.querySelector("div.instanda-address-locality input");
259    let city = container.querySelector("div.instanda-address-city input");
260    let county = container.querySelector("div.instanda-address-county input");
261    let postcode = container.querySelector("div.instanda-address-postcode input");
262    let country = container.querySelector("div.instanda-address-country select");
263
264    if (buildingNumber) {
265        buildingNumber.value = (addressData.querySelector('span.SubBuildingName').innerHTML + " " + addressData.querySelector('span.BuildingNumber').innerHTML).trim();
266    }
267
268    if (buildingName) {
269        buildingName.value = addressData.querySelector('span.BuildingName').innerHTML;
270    }
271
272    if (street) {
273        street.value = (addressData.querySelector('span.ThoroughfareName').innerHTML + " " + addressData.querySelector('span.ThoroughfareDesc').innerHTML).trim()
274    }
275
276    if (locality) {
277        locality.value = addressData.querySelector('span.DependentLocality').innerHTML
278    }
279
280    let addressLines = addressData.querySelector('span.AddressLines').innerHTML.split(",");
281    if (addressLine1) {
282        addressLine1.value = addressLines[0];
283    }
284
285    if (addressLine2) {
286        addressLine2.value = (`${addressLines[1]}, ${addressLines[2]}, ${addressLines[3]}
286`).split(", ").filter(Boolean).join(", ");
287    }
288
289    if (city) {
290        city.value = addressLines[4];
291    }
292
293    if (county) {
294        county.value = addressLines[5];
295    }
296
297    if (postcode) {
298        postcode.value = addressLines[6];
299    }
300
301    if (country) {
302        country.value = "GB"; // only supports UK addresses
303    }
304};
305const toggleElement = (target, duration = 300) => {
306    target.classList.contains('expanded')
307        ? collapseElement(target, duration)
308        : expandElement(target, duration)
309}
310
311const collapseElement = (target, duration = 300) => {
312    if (target.style.display === 'none')
313        return;
314
315    target.classList.remove('expanded');
316
317    target.style.transitionProperty = "height, margin, padding";
318    target.style.transitionDuration = duration + "ms";
319    target.style.boxSizing = "border-box";
320    target.style.height = target.offsetHeight + "px";
321
322    window.requestAnimationFrame(() => {
323        target.style.overflow = "hidden";
324        
325        window.requestAnimationFrame(() => {
326            target.style.height = 0;
327            target.style.paddingTop = 0;
328            target.style.paddingBottom = 0;
329            target.style.marginTop = 0;
330            target.style.marginBottom = 0;
331        })
332    })
333
334    window.setTimeout(() => {
335        target.style.display = "none";
336        target.style.removeProperty("height");
337        target.style.removeProperty("padding-top");
338        target.style.removeProperty("padding-bottom");
339        target.style.removeProperty("margin-top");
340        target.style.removeProperty("margin-bottom");
341        target.style.removeProperty("overflow");
342        target.style.removeProperty("transition-duration");
343        target.style.removeProperty("transition-property");
344    }, duration);
345}
346
347const expandElement = (target, duration = 300) => {
348    if (target.style.display === 'block')
349        return;
350
351    target.classList.add('expanded');
352
353    target.style.removeProperty("display");
354    let display = window.getComputedStyle(target).display;
355
356    window.requestAnimationFrame(() => {
357        if (display === "none") display = "block";
358        
359        target.style.display = display;
360        const height = target.offsetHeight;
361        target.style.overflow = "hidden";
362        target.style.height = 0;
363        target.style.paddingTop = 0;
364        target.style.paddingBottom = 0;
365        target.style.marginTop = 0;
366        target.style.marginBottom = 0;
367
368        window.requestAnimationFrame(() => {
369            target.style.height = height + "px";
370            target.style.removeProperty("padding-top");
371            target.style.removeProperty("padding-bottom");
372            target.style.removeProperty("margin-top");
373            target.style.removeProperty("margin-bottom");
374            target.style.boxSizing = "border-box";
375            target.style.transitionProperty = "height, margin, padding";
376            target.style.transitionDuration = duration + "ms";
377        })
378    })
379
380    window.setTimeout(() => {
381        target.style.removeProperty("height");
382        target.style.removeProperty("overflow");
383        target.style.removeProperty("transition-duration");
384        target.style.removeProperty("transition-property");
385    }, duration);
386};
387let handleRecaptchaCallback = function (token, gCaptchaResponseVariableName) {
388    document.querySelector(`#Variables_${gCaptchaResponseVariableName}__Answer`).value = token;
389};
390const DisplayAsEnum = Object.freeze({
391    AutoComplete: 'AutoComplete',
392    Radio: 'Radio',
393    Dropdown: 'Dropdown',
394    List: 'List'
395})
396
397const carBrandsAndModelsConstants = {
398    classQuestionContainer: 'car-brands-and-models-all',
399    instandaQuestionInnerLabelPrefix: 'instanda-question-inner-label-',
400
401    urlGetBrandsByYear: '/Public/GetCABrands',
402    urlGetModelsByBrand: '/Public/GetCAModels',
403    urlGetPricesByModel: '/Public/GetCAPrices',
404
405    contentType: 'application/json',
406
407    prefixVariables: 'Variables_',
408    suffixAnswer: '__Answer',
409
410    classSelectedBrand: 'selected-brand',
411    classSelectedModel: 'selected-model',
412
413    //wrappers classes
414    classTopWrapper: 'car-brands-and-models-all',
415    classSummaryWrapper: 'car-brands-and-models-summary',
416    classEditWrapper: 'car-brands-and-models-edit',
417
418    //summary classes
419    classSummaryPicture: 'car-summary-picture',
420    classSummaryYear: 'car-summary-year',
421    classSummaryBrand: 'car-summary-brand',
422    classSummaryModel: 'car-summary-model',
423    classSummaryPower: 'car-summary-power',
424    classSummaryPowerType: 'car-summary-power-type',
425    classSummaryBodyType: 'car-summary-body-type',
426    classSummaryGrade1: 'car-summary-grade1',
427    classSummaryGrade2: 'car-summary-grade2',
428    classSummaryGrade3: 'car-summary-grade3',
429    classSummaryGrade4: 'car-summary-grade4',
430    classSummaryGrade5: 'car-summary-grade5',
431    classSummaryPriceId: 'car-summary-price-id',
432    classSummaryPriceCurrency: 'car-summary-price-currency',
433    classSummaryCountry: 'car-summary-country',
434    classSummaryEngineCapacity: 'car-summary-engine-capacity',
435    classSummaryCylinders: 'car-summary-cylinders',
436    classSummaryBodyTypeId: 'car-summary-body-type-id',
437    classSummaryCarNotInList: 'car-summary-car-not-in-list',
438
439    classCarNotInList: 'instanda-question-car-brands-and-models-car-not-in-list-input',
440
441    //edit classes
442    classEditYear: 'instanda-question-car-brands-and-models-input',
443    classEditBrand: 'instanda-question-car-brands-and-models-brand-input',
444    classEditBrandWrapper: 'car-brands-wrapper-',
445    classEditText_Brand: 'text-brand',
446    classEditText_Model: 'text-model',
447    classEditText_BodyType: 'text-body-type',
448
449    classEditBrandLabel: 'instanda-question-car-brands-and-models-brand-label',
450    classEditModelLabel: 'instanda-question-car-brands-and-models-model-label',
451        
452    classEditModel: 'instanda-question-car-brands-and-models-model-input',
453    classEditModelWrapper: 'car-models-wrapper-',
454
455    classEditModelId: 'hidden-model-id',
456    classEditBodyTypeId: 'hidden-body-type-id',
457    classEditPictureUrl: 'hidden-picture-url',
458   
459    classEditPower: 'instanda-question-car-brands-and-models-power-input',
460    classEditPowerType: 'instanda-question-car-brands-and-models-car-power-type-input',
461    classEditBodyType: 'instanda-question-car-brands-and-models-body-type-select',
462    classEditEngineCapacity: 'instanda-question-car-brands-and-models-car-engine-capacity-input',
463    classEditCylinders: 'instanda-question-car-brands-and-models-cylinders-input',
464    classEditPriceId: 'instanda-question-car-brands-and-models-car-priceid-input',
465
466    classEditGrade1: 'instanda-question-car-brands-and-models-grade1-input',
467    classEditGrade2: 'instanda-question-car-brands-and-models-grade2-input',
468    classEditGrade3: 'instanda-question-car-brands-and-models-grade3-input',
469    classEditGrade4: 'instanda-question-car-brands-and-models-grade4-input',
470    classEditGrade5: 'instanda-question-car-brands-and-models-grade5-input',
471
472    classEditPriceCurrency: 'instanda-question-car-brands-and-models-car-price-currency-input',
473    classEditPriceCountry: 'instanda-question-car-brands-and-models-car-price-country-input',
474
475    //wrappers displayAs-brands
476    classBrandsWrapperDropdown: 'car-brands-wrapper-dropdown-',
477    classBrandsWrapperRadio: 'car-brands-wrapper-radio-',
478    classBrandsWrapperList: 'car-brands-wrapper-list-',
479    classBrandsWrapperAutocomplete: 'car-brands-wrapper-autocomplete-',
480
481    //wrappers displayAs-models
482    classModelsWrapperDropdown: 'car-models-wrapper-dropdown-',
483    classModelsWrapperRadio: 'car-models-wrapper-radio-',
484    classModelsWrapperList: 'car-models-wrapper-list-',
485    classModelsWrapperAutocomplete: 'car-models-wrapper-autocomplete-',
486
487    classFieldsetManualInput: 'manual-inputs',
488
489    //buttons
490    classBtnSummary: 'car-brands-and-models-show-summary',
491    classBtnEdit : 'car-brands-and-models-edit-summary',
492
493    //hidden fields used in selectors
494    hiddenBrandVariableNameId : "brandVariableName",
495    hiddenModelVariableNameId : "modelVariableName",
496    hiddenDisplayAsId: "displayAs",
497    isAgentSite: "isAgentSite",
498    questionsAreReadOnly: "questionsAreReadOnly",
499    summaryAlreadyShown: "summaryAlreadyShown",
500
501    classErrorText: 'ui-state-error-text',
502
503    eventChangeInitial: 'change:initial'
504};
505
506document.addEventListener("instanceAdded", addEventListenersToCarBrandsAndModelsQuestion);
507document.addEventListener("DOMContentLoaded", addEventListenersToCarBrandsAndModelsQuestion);
508
509function addEventListenersToCarBrandsAndModelsQuestion(event) {
510    let questionContainers = event.target.querySelectorAll(`.${carBrandsAndModelsConstants.classQuestionContainer}`);
511    questionContainers.forEach((questionContainer) => {
512        QuestionContentLoaded(questionContainer);
513    });
514}
515
516function QuestionContentLoaded(questionContainer) {
517    let displayAsHiddenElement = questionContainer.querySelector(`#${carBrandsAndModelsConstants.hiddenDisplayAsId}`);
518    if (displayAsHiddenElement) {
519        EnableManualInputIfClassicAnalyticsNotAvailable(questionContainer);
520
521        let displayAs = displayAsHiddenElement.value;
522        let brandVariableName = questionContainer.querySelector(`#${carBrandsAndModelsConstants.hiddenBrandVariableNameId}`).value;
523        let modelVariableName = questionContainer.querySelector(`#${carBrandsAndModelsConstants.hiddenModelVariableNameId}`).value;
524        let isAgentSite = questionContainer.querySelector(`#${carBrandsAndModelsConstants.isAgentSite}`).value;
525
526        addEventListeners(questionContainer, brandVariableName, modelVariableName, displayAs, isAgentSite);
527        HideSummaryButton(questionContainer);
528
529        let carNotInListCheckbox = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classCarNotInList} input[type=checkbox]`);
530        let ctrlYear = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditYear} input`);
531        if (ctrlYear.value.length === 4) {
532            if (!carNotInListCheckbox.checked) {
533                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}`));
534                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}`));
535                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperDropdown}`));
536                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperDropdown}`));
537                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperRadio}`));
538                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperRadio}`));
539                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperList}`));
540                ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperList}`));
541            }
542        }
543        else {
544            if (!carNotInListCheckbox.checked) {
545                let innerLabels = questionContainer.querySelectorAll(`div[class*=${carBrandsAndModelsConstants.instandaQuestionInnerLabelPrefix}`);
546                innerLabels.forEach((x) => x.style.display = "none");
547
548                if (displayAs === DisplayAsEnum.AutoComplete) {
549                    HideElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}`));
550                    HideElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}`));
551                }
552            }
553        }
554
555        CarBrandsAndModelsYearChangeJS(ctrlYear, brandVariableName, modelVariableName, displayAs, true);
556        CarBrandsAndModelsBrandChangeJS(null, questionContainer, brandVariableName, modelVariableName, displayAs, true);
557        CarBrandsAndModelsModelChangeJS(null, questionContainer, true);
558
559        let wrapperSummaryElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryWrapper}`);
560        let wrapperEditElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditWrapper}`);
561
562        let wrapperSummaryStyle = window.getComputedStyle(wrapperSummaryElement);
563        let wrapperEditStyle = window.getComputedStyle(wrapperEditElement);
564
565        if (questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_Model}`).value !== '' && !document.getElementsByClassName('input-validation-error').length) {
566            if (wrapperEditStyle.display !== "none" && wrapperEditStyle.visibility !== "hidden") {
567                wrapperEditElement.style.display = "none";
568            }
569        }
570        else if (wrapperSummaryStyle.display !== "none" && wrapperSummaryStyle.visibility !== "hidden") {
571            wrapperSummaryElement.style.display = "none";
572        }
573
574        let questionsAreReadonly = questionContainer.querySelector(`.${carBrandsAndModelsConstants.questionsAreReadOnly}`);
575        let powerTypeIdNotSelected = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPowerType} select option:not(:checked)`);
576        let elementsForManualInput = GetElementsForManualInput(questionContainer);
577        let elementsUsedWithQAInterface = GetElementUsedWithQAInterface(questionContainer);
578        let bodyType = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyType} select`);
579        let bodyTypeText = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`);
580        let pictureElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPictureUrl}`);
581
582        if (!carNotInListCheckbox.checked && questionsAreReadonly !== "true") {
583            elementsForManualInput.forEach((element) => {
584                collapseElement(element);
585            })
586
587            bodyTypeText.style.display = "block";
588            EnableElement(bodyTypeText);
589            SetReadonly(bodyTypeText);
590            DisableElement(bodyType);
591            DisableElement(powerTypeIdNotSelected);
592        }
593        else {
594            elementsUsedWithQAInterface.forEach((element) => {
595                collapseElement(element);
596            })
597
598            elementsForManualInput.forEach((element) => {
599                expandElement(element);
600            })
601
602            DisableElement(bodyTypeText);
603            EnableElement(bodyType);
604
605            EnableElement(powerTypeIdNotSelected);
606
607            let innerLabels = questionContainer.querySelectorAll(`div[class*=${carBrandsAndModelsConstants.instandaQuestionInnerLabelPrefix}`);
608            innerLabels.forEach((x) => x.style.display = "block");
609
610            if (displayAs === DisplayAsEnum.AutoComplete) {
611                questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}`).style.display = "block";
612                questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}`).style.display = "block";
613            }
614
615            let bodyTypeTextElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`);
616            bodyTypeTextElement.value = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyType} select`).value;
617            bodyTypeTextElement.blur();
618        }
619
620        pictureElement.addEventListener('change', function () {
621            let summaryPictureElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPicture} img`);
622            summaryPictureElement.src = pictureElement.value;
623
624            if (pictureElement.value === "") {
625                let style = window.getComputedStyle(summaryPictureElement);
626                if (style.display !== "none" && style.visibility !== "hidden") {
627                    HideElementById(summaryPictureElement.id);
628                }
629            } else {
630                ShowElementById(summaryPictureElement.id);
631            }
632        });
633
634        let summarycarBodyType = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryBodyTypeId} span`);
635        if (summarycarBodyType) {
636            let bodyTypeIdElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyTypeId}`);
637            bodyTypeIdElement.addEventListener('change', function () {
638                summarycarBodyType.innerHTML = bodyTypeIdElement.value;
639            });
640        }
641
642        SetSummaryFields(questionContainer);
643    }
644}
645
646function HideSummaryButton(carBrandsAndModelsQuestion) {
647    let btnSummary = carBrandsAndModelsQuestion.querySelector(`.${carBrandsAndModelsConstants.classBtnSummary}`);
648    if (btnSummary) {
649        btnSummary.style.display = 'none';
650    }
651}
652
653function addEventListeners(questionContainer, brandVariableName, modelVariableName, displayAs, isAgentSite) {
654    //year
655    let ctrlYear = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditYear} input`);
656    ctrlYear.addEventListener("input", (e) => OnYearInput(e.target, brandVariableName, modelVariableName, displayAs));
657
658    //brand
659    let brandElement = questionContainer.querySelector(`#${brandVariableName}`);
660
661   //for displayAs = List, Radio  - events are attached in CarBrandsAndModelsYearChangeJS, CarBrandsAndModelsBrandChangeJS functions
662    if (displayAs === DisplayAsEnum.Dropdown) {
663        brandElement.addEventListener("change", (e) => CarBrandsAndModelsBrandChangeJS(e.target.selectedOptions[0], questionContainer, brandVariableName, modelVariableName, displayAs, false))
664    }
665    else if (displayAs === DisplayAsEnum.AutoComplete) {
666        brandElement.addEventListener("change", (e) => CarBrandsAndModelsBrandChangeJS(e.target, questionContainer, brandVariableName, modelVariableName, displayAs, false))
667    }
668
669    brandElement.addEventListener(carBrandsAndModelsConstants.eventChangeInitial, (e) => CarBrandsAndModelsBrandChangeJS(e.target, questionContainer, brandVariableName, modelVariableName, displayAs, true));
670
671    //model
672    let modelElement = questionContainer.querySelector(`#${modelVariableName}`);
673
674    //for displayAs = List, Radio  - events are attached in CarBrandsAndModelsYearChangeJS, CarBrandsAndModelsBrandChangeJS functions
675
676    if (displayAs === DisplayAsEnum.Dropdown) {
677        modelElement.addEventListener("change", (e) => CarBrandsAndModelsModelChangeJS(e.target.selectedOptions[0], questionContainer,  modelVariableName, false))
678    }
679    else if (displayAs === DisplayAsEnum.AutoComplete) {
680        modelElement.addEventListener("change", (e) => CarBrandsAndModelsModelChangeJS(e.target, questionContainer, modelVariableName, false))
681    }
682
683    modelElement.addEventListener(carBrandsAndModelsConstants.eventChangeInitial, (e) => CarBrandsAndModelsModelChangeJS(e.target, questionContainer, modelVariableName, true));
684
685    //button Edit
686    let btnEdit = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classBtnEdit}`);
687    btnEdit.addEventListener("click", (e) => OnBtnEditClick(e, questionContainer, brandVariableName, modelVariableName, displayAs));
688
689    //button Summary
690    let btnSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classBtnSummary}`);
691    btnSummary.addEventListener("click", (e) => OnBtnSummaryClick(e, questionContainer));
692
693    //car not in list
694    let carNotInListCheckbox = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classCarNotInList} input[type=checkbox]`);
695    carNotInListCheckbox.addEventListener("click", (e) => OnCarNotInListClick(e.target, questionContainer, brandVariableName, modelVariableName, displayAs, isAgentSite));
696}
697
698function OnBtnEditClick(event, questionContainer, brandVariableName, modelVariableName, displayAs) {
699    let wrapperEditElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditWrapper}`);
700    let wrapperSummaryElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryWrapper}`);
701    let summaryBtn = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classBtnSummary}`);
702    let carNotInListCheckbox = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classCarNotInList} input[type=checkbox]`);
703
704    wrapperEditElement.style.display = "block";
705    let style = window.getComputedStyle(wrapperSummaryElement);
706    if (style.display !== "none" && style.visibility !== "hidden") {
707        wrapperSummaryElement.style.display = "none";
708    }
709
710    CarBrandsAndModelsBrandChangeJS(null, questionContainer, brandVariableName, modelVariableName, displayAs, true);
711    summaryBtn.style.display = "block";
712
713    if (!carNotInListCheckbox.checked) {
714        ShowElement(questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBrand}`));
715        ShowElement(questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditModel}`));
716        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}`));
717        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}`));
718        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperDropdown}`));
719        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperDropdown}`));
720        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperRadio}`));
721        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperRadio}`));
722        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperList}`));
723        ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperList}`));
724    }
725}
726
727function OnBtnSummaryClick(event, container) {
728    let wrapperEditElement = container.querySelector(`.${carBrandsAndModelsConstants.classEditWrapper}`);
729    if (wrapperEditElement) {
730        let style = window.getComputedStyle(wrapperEditElement);
731        if (style.display !== "none" && style.visibility !== "hidden") {
732            wrapperEditElement.style.display = "none";
733        }
734    }
735    ShowElement(container.querySelector(`.${carBrandsAndModelsConstants.classSummaryWrapper}`))
736    SetSummaryFields(container)
737}
738
739function SetSummaryFields(questionContainer) {
740
741    let pictureUrl = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPictureUrl}`);
742    let year = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditYear} input`);
743    let brand = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_Brand}`);
744    let model = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_Model}`);
745
746    let power = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPower} input`);
747    let powerType = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPowerType} select`);
748    let bodyTypeText = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`);
749    let bodyTypeId = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyTypeId}`);
750    let engineCapacity = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditEngineCapacity} input`);
751    let cylinders = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditCylinders} input`);
752
753    let priceId = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPriceId} input`);
754    let grade1 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade1} input`);
755    let grade2 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade2} input`);
756    let grade3 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade3} input`);
757    let grade4 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade4} input`);
758    let grade5 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade5} input`);
759    let priceCurrency = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPriceCurrency} input`);
760    let priceCountry = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPriceCountry} input`);
761
762    let carNotInListCheckbox = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classCarNotInList} input[type=checkbox]`);
763
764    let pictureSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPicture} img`);
765    let yearSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryYear} span`);
766    let brandSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryBrand} span`);
767    let modelSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryModel} span`);
768
769    let powerSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPower} span`);
770    let powerTypeSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPowerType} span`);
771    let bodyTypeSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryBodyType} span`);
772    let bodyTypeIdSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryBodyTypeId} span`);
773    let engineCapacitySummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryEngineCapacity} span`);
774    let cylindersSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryCylinders} span`);
775
776    let priceIdSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPriceId} span`);
777    let grade1Summary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryGrade1} span`);
778    let grade2Summary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryGrade2} span`);
779    let grade3Summary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryGrade3} span`);
780    let grade4Summary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryGrade4} span`);
781    let grade5Summary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryGrade5} span`);
782    let priceCurrencySummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPriceCurrency} span`);
783    let priceCountrySummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryCountry} span`);
784    let carNotInListSummary = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryCarNotInList} span`);
785
786    pictureSummary.src = pictureUrl.value;
787    if (pictureUrl.value === "") {
788        let style = window.getComputedStyle(pictureSummary);
789        if (style.display !== "none" && style.visibility !== "hidden") {
790            HideElement(pictureSummary);
791        }
792    } else {
793        ShowElement(pictureSummary);
794    }
795    yearSummary.innerHTML = year.value;
796    brandSummary.innerHTML = brand.value;
797    modelSummary.innerHTML = model.value;
798
799    powerSummary.innerHTML = power.value;
800    powerTypeSummary.innerHTML = powerType.value;
801    bodyTypeSummary.innerHTML = bodyTypeText.value;
802    bodyTypeIdSummary.innerHTML = bodyTypeId.value;
803    engineCapacitySummary.innerHTML = engineCapacity.value;
804    cylindersSummary.innerHTML = cylinders.value;
805
806    priceIdSummary.innerHTML = priceId.value;
807    grade1Summary.innerHTML = grade1.value;
808    grade2Summary.innerHTML = grade2.value;
809    grade3Summary.innerHTML = grade3.value;
810    grade4Summary.innerHTML = grade4.value;
811    grade5Summary.innerHTML = grade5.value;
812    priceCurrencySummary.innerHTML = priceCurrency.value;
813    priceCountrySummary.innerHTML = priceCountry.value;
814
815    carNotInListSummary.innerHTML = carNotInListCheckbox.checked;
816}
817
818function OnCarNotInListClick(carNotInListCheckbox, questionContainer, brandVariableName, modelVariableName, displayAs, isAgentSite) {
819    let elementsUsedWithQAInterface = GetElementUsedWithQAInterface(questionContainer);
820    let elementsForManualInput = GetElementsForManualInput(questionContainer);
821    let elementsEditableOnManualInput = GetElementsEditableOnManualInput(questionContainer, brandVariableName);
822
823    let bodyTypeTextElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`);
824    let bodyTypeElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyType} select`);
825
826    if (carNotInListCheckbox.checked) {
827        elementsUsedWithQAInterface.forEach((element) => {
828            collapseElement(element);
829        })
830         
831        elementsForManualInput.forEach((element) => {
832            expandElement(element);
833        })
834
835        EnableElement(bodyTypeElement);
836        DisableElement(bodyTypeTextElement);
837
838        if (isAgentSite) {
839            elementsEditableOnManualInput.forEach((item) => {
840                item.removeAttribute("readonly");
841            });
842        }
843        else {
844            questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade1}`).value = "";
845            questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade2}`).value = "";
846            questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade3}`).value = "";
847            questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade4}`).value = "";
848            questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade5}`).value = "";
849
850            let brandTextElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_Brand}`);
851            brandTextElement.removeAttribute("readonly");
852            let modelTextElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_Model}`);
853            modelTextElement.removeAttribute("readonly");
854            let powerElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPower} input`);
855            powerElement.removeAttribute("readonly");
856        }
857
858        let pictureElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryPicture} img`);
859        pictureElement.value = '';
860
861        ShowElement(questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBrandLabel}`));
862        ShowElement(questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditModelLabel}`));
863
864        if (displayAs === DisplayAsEnum.AutoComplete) {
865            questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}`).style.display = "block";
866            questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}`).style.display = "block";
867        }
868
869        bodyTypeTextElement.value = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyType} select`).value;
870        questionContainer.querySelector(`.${carBrandsAndModelsConstants.classSummaryBodyType} span`).innerHTML = bodyTypeTextElement.value;
871
872        questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyType} select`).value = '';
873    } else {
874        elementsForManualInput.forEach((element) => {
875            collapseElement(element);
876        })
877
878        elementsUsedWithQAInterface.forEach((element) => {
879            expandElement(element);
880        })
881
882        EnableElement(bodyTypeTextElement);
883        SetReadonly(bodyTypeTextElement);
884        bodyTypeTextElement.value="";
885        DisableElement(bodyTypeElement);
886
887        let powerTypeNotCheckedOptions = questionContainer.querySelectorAll(`.${carBrandsAndModelsConstants.classEditPowerType} select option:not(:checked)`);
888        powerTypeNotCheckedOptions.forEach(x => DisableElement(x))
889
890        let elementsNotResetOnCarNotFound = GetElementsNotResetOnCarNotFound(questionContainer, brandVariableName, modelVariableName);
891        elementsEditableOnManualInput.forEach((item) => {
892            // don't reset brand and model elements
893            if (!elementsNotResetOnCarNotFound.includes(item)) {
894                item.value = "";
895                item.setAttribute("readonly", true);
896            }
897        });
898
899        let yearElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditYear} input`);
900        CarBrandsAndModelsYearChangeJS(
901            yearElement,
902            brandVariableName,
903            modelVariableName,
904            displayAs,
905            true);
906
907        let selectedModelElement = questionContainer.querySelector(`#${modelVariableName} .${carBrandsAndModelsConstants.classSelectedModel}`);
908        if (selectedModelElement) {
909            selectedModelElement.click();
910        }
911    }
912}
913
914function GetElementUsedWithQAInterface(container) {
915    let elementsUsedWithQAInterface = [];
916
917    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperList}`));
918    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperList}`));
919    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperDropdown}`));
920    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperDropdown}`));
921    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperRadio}`));
922    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperRadio}`));
923    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}`));
924    elementsUsedWithQAInterface.push(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}`));
925    elementsUsedWithQAInterface.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`));
926
927    return elementsUsedWithQAInterface.filter(
928        // filter out elements not present on the page
929        function(element){ return element !== null }
930    );
931}
932
933function GetElementsForManualInput(container) {
934    let elementsForManualInput = [];
935
936    elementsForManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_Brand}`));
937    elementsForManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_Model}`));
938    elementsForManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditBodyType} select`));
939
940    return elementsForManualInput;
941}
942
943function GetElementsEditableOnManualInput(container,brandVariableName) {
944    let elementsEditableOnManualInput = [];
945
946    elementsEditableOnManualInput.push(container.querySelector(`#${brandVariableName}`));
947    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_Brand}`));
948    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_Model}`));
949    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditPower} input`));
950    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditPowerType} select`));
951    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditEngineCapacity} input`));
952    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditCylinders} input`));
953    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditPriceId} input`));
954    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditGrade1} input`));
955    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditGrade2} input`));
956    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditGrade3} input`));
957    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditGrade4} input`));
958    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditGrade5} input`));
959    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditPriceCurrency} input`));
960    elementsEditableOnManualInput.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditPriceCountry} input`));
961
962    return elementsEditableOnManualInput;
963}
964
965function GetElementsNotResetOnCarNotFound(container, brandVariableName, modelVariableName) {
966    let elementsNotResetOnCarNotFound = [];
967
968    elementsNotResetOnCarNotFound.push(container.querySelector(`#${brandVariableName}`));
969    elementsNotResetOnCarNotFound.push(container.querySelector(`#${modelVariableName}`));
970    elementsNotResetOnCarNotFound.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_Brand}`));
971    elementsNotResetOnCarNotFound.push(container.querySelector(`.${carBrandsAndModelsConstants.classEditText_Model}`));
972
973    return elementsNotResetOnCarNotFound;
974}
975
976function OnYearInput(yearElement, brandVariableName, modelVariableName, displayAs) {
977    let container = yearElement.closest(`.${carBrandsAndModelsConstants.classQuestionContainer}`);
978    let carNotInListElement = container.querySelector(`.${carBrandsAndModelsConstants.classCarNotInList}`);
979
980    if (yearElement.value.length === 4
981        && !carNotInListElement.checked
982        && !isNaN(yearElement.value)) {
983
984        document.body.style.cursor = "progress";
985
986        if (displayAs === DisplayAsEnum.List) {
987            ShowElement(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperList}]`));
988        }
989        else if (displayAs === DisplayAsEnum.AutoComplete) {
990            ShowElement(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperAutocomplete}]`));
991        }
992        else if (displayAs === DisplayAsEnum.Dropdown) {
993            ShowElement(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperDropdown}]`));
994        }
995        else {
996            ShowElement(container.querySelector(`div[class*=${carBrandsAndModelsConstants.classBrandsWrapperRadio}]`));
997        }
998
999        setTimeout(function () {
1000            CarBrandsAndModelsYearChangeJS(
1001                yearElement,
1002                brandVariableName,
1003                modelVariableName,
1004                displayAs,
1005                false);
1006        }, 0);
1007    }
1008}
1009
1010function CarBrandsAndModelsYearChangeJS(ctrlYearOfManufacture, brandVariableName, modelVariableName, displayAs, isInitialCall) {
1011    let questionContainer = ctrlYearOfManufacture.closest(`.${carBrandsAndModelsConstants.classQuestionContainer}`);
1012
1013    if (ctrlYearOfManufacture.value.length === 4) {
1014
1015        let urlGetBrands = new URL(carBrandsAndModelsConstants.urlGetBrandsByYear, document.location);
1016        urlGetBrands.searchParams.append("year", ctrlYearOfManufacture.value);
1017
1018        document.body.style.cursor = 'wait';
1019
1020        questionContainer.querySelector(`.${carBrandsAndModelsConstants.instandaQuestionInnerLabelPrefix}${brandVariableName}`).style.display = "block";
1021
1022        fetch(urlGetBrands, {
1023            method: 'GET',
1024            headers: {
1025                'Content-Type': carBrandsAndModelsConstants.contentType,
1026                'Accept': carBrandsAndModelsConstants.contentType,
1027                'X-Requested-With': 'XMLHttpRequest'
1028            }
1029        })
1030            .then(res => res.json())
1031            .then(data => {
1032                let brandElement = questionContainer.querySelector(`#${brandVariableName}`);
1033                Empty(brandElement);
1034
1035                let brandsDataList = null;
1036                if (displayAs === DisplayAsEnum.AutoComplete) {
1037                    brandsDataList = document.querySelector(`#Variables_${brandVariableName}__Choices`);
1038                }
1039
1040                data.forEach((item) => {
1041                    let selectedClass = "";
1042                    if (questionContainer.querySelector(`#Text_${brandVariableName}`).value === item.name) {
1043                        selectedClass = carBrandsAndModelsConstants.classSelectedBrand;
1044                    }
1045
1046                    if (displayAs === DisplayAsEnum.List) {
1047                        let liElement = document.createElement('li');
1048                        liElement.classList.add("list-group-item", "list-group-item-action");
1049                        if (selectedClass)
1050                            liElement.classList.add(selectedClass);
1051                        liElement.addEventListener('click', (e) => {
1052                            CarBrandsAndModelsBrandChangeJS(e.target, questionContainer, brandVariableName, modelVariableName, displayAs,false);
1053                        });
1054                        liElement.appendChild(document.createTextNode(item.name));
1055                        brandElement.appendChild(liElement);
1056                        SetBrandAdditionalData(liElement, item);
1057                    }
1058                    else if (displayAs === DisplayAsEnum.Dropdown) {
1059                        let optionElement = document.createElement('option');
1060                        optionElement.value = item.name;
1061                        optionElement.selected = (selectedClass !== "");
1062                        optionElement.text = item.name
1063                        if (selectedClass)
1064                            optionElement.classList.add(selectedClass);
1065                        brandElement.appendChild(optionElement);
1066                        SetBrandAdditionalData(optionElement, item);
1067                    }
1068                    else if (displayAs === DisplayAsEnum.Radio) {
1069                        if (item.name !== '') {
1070                            let radioItemElement = document.createElement("input");
1071                            radioItemElement.type = "radio";
1072                            radioItemElement.id = `${brandVariableName}_radio${item.id}`;
1073                            radioItemElement.name = `${brandVariableName}_radio`;
1074                            radioItemElement.value = item.name;
1075                            radioItemElement.checked = (selectedClass !== "");
1076                            radioItemElement.addEventListener('click', (e) => {
1077                                CarBrandsAndModelsBrandChangeJS(e.target, questionContainer, brandVariableName, modelVariableName, displayAs, false);
1078                            });
1079                            let description = document.createTextNode(` ${item.name}`);
1080                            brandElement.appendChild(radioItemElement);
1081                            brandElement.appendChild(description);
1082                            brandElement.appendChild(document.createElement('br'));
1083                            SetBrandAdditionalData(radioItemElement, item);
1084                        }
1085                    }
1086                    else {
1087                        let dataListItem = document.createElement('option');
1088                        dataListItem.value = item.name;
1089                        brandsDataList.appendChild(dataListItem);
1090
1091                        SetBrandAdditionalData(dataListItem, item);
1092                    }
1093                }); 
1094
1095                if (!isInitialCall) {
1096                    if (displayAs === DisplayAsEnum.List) {
1097                        let liElements = brandElement.getElementsByTagName('li');
1098                        if (liElements.length > 0)
1099                            liElements[0].click();
1100                    }
1101                }
1102                else {
1103                    brandElement.dispatchEvent(new Event(carBrandsAndModelsConstants.eventChangeInitial));
1104                    brandElement.blur();
1105                }
1106
1107                questionContainer.querySelector(`.${carBrandsAndModelsConstants.classErrorText}`).style.display = 'none';
1108                document.body.style.cursor = '';
1109            }).catch((error) => {
1110                console.debug("yearChange error = ", error);
1111                questionContainer.querySelector(`.${carBrandsAndModelsConstants.classErrorText}`).style.display = 'block';
1112                document.body.style.cursor = '';
1113            });
1114    }
1115}
1116
1117function CarBrandsAndModelsBrandChangeJS(
1118    clickedObjectElement,
1119    questionContainer,
1120    brandVariableName,
1121    modelVariableName,
1122    displayAs,
1123    isInitialCall) {
1124
1125    let selectedBrandId = null;
1126    let selectedChildElement = null;
1127    let brandDataListChoices = null;
1128    let brandVariableIdElement = questionContainer.querySelector(`#${brandVariableName}`);
1129    let ctrlYearOfManufacture = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditYear} input`);
1130
1131    if (ctrlYearOfManufacture.value.length !== 4) {
1132        return;
1133    }
1134
1135    if (displayAs === DisplayAsEnum.AutoComplete) {
1136        brandDataListChoices = questionContainer.querySelector(`#Variables_${brandVariableName}__Choices`);
1137        let optionAutoCompleteItems = questionContainer.querySelectorAll(`#Variables_${brandVariableName}__Choices option`);
1138        let selectedName = questionContainer.querySelector(`#${brandVariableName}`).value;
1139        selectedChildElement = Array.from(optionAutoCompleteItems).filter(x => x.value === selectedName);
1140        clickedObjectElement = selectedChildElement[0];
1141        selectedBrandId = dataStorage.get(selectedChildElement[0], "brandId");
1142    }
1143    else {
1144        selectedBrandId = clickedObjectElement != null ? dataStorage.get(clickedObjectElement, "brandId") : null;
1145    }
1146
1147    if (isInitialCall && !brandDataListChoices) {
1148        let selectedBrandItemElement = brandVariableIdElement.querySelector(`.${carBrandsAndModelsConstants.classSelectedBrand}`);
1149        if (selectedBrandItemElement != null) {
1150            selectedBrandItemElement.classList.remove(carBrandsAndModelsConstants.classSelectedBrand);
1151        }
1152        let selectedName = questionContainer.querySelector(`#Text_${brandVariableName}`).value;
1153
1154        if (displayAs === DisplayAsEnum.List) {
1155            let liElements = questionContainer.querySelectorAll(`#${brandVariableName} li`);
1156            selectedChildElement = Array.from(liElements).filter(x => x.innerText === selectedName);
1157            if (selectedChildElement.length > 0) {
1158                selectedChildElement[0].classList.add(carBrandsAndModelsConstants.classSelectedBrand);
1159            }
1160            selectedBrandId = dataStorage.get(selectedChildElement[0], "brandId");
1161        }
1162        else if (displayAs === DisplayAsEnum.Dropdown) {
1163            let optionElements = questionContainer.querySelectorAll(`#${brandVariableName} option`);
1164            selectedChildElement = Array.from(optionElements).filter(x => x.innerText === selectedName);
1165            if (selectedChildElement.length > 0) {
1166                selectedChildElement[0].classList.add(carBrandsAndModelsConstants.classSelectedBrand);
1167            }
1168            selectedBrandId = dataStorage.get(selectedChildElement[0], "brandId");
1169        }
1170        else if (displayAs === DisplayAsEnum.Radio) {
1171            let selectedInputs = questionContainer.querySelectorAll(`#${brandVariableName} input`);
1172            if (selectedInputs != null) {
1173                selectedChildElement = Array.from(selectedInputs).filter(x => x.value === selectedName);
1174                if (selectedChildElement.length > 0) {
1175                    selectedChildElement[0].classList.add(carBrandsAndModelsConstants.classSelectedBrand);
1176                }
1177                selectedBrandId = dataStorage.get(selectedChildElement[0], "brandId");
1178            }
1179        }
1180
1181        if (selectedBrandId === null) {
1182            selectedBrandId = 0;
1183        }
1184    }
1185
1186    if (selectedBrandId) {
1187        if (!isInitialCall) {
1188            let selectedBrandItemElement = brandVariableIdElement.querySelector(`.${carBrandsAndModelsConstants.classSelectedBrand}`);
1189            if (selectedBrandItemElement != null) {
1190                selectedBrandItemElement.classList.remove(carBrandsAndModelsConstants.classSelectedBrand);
1191            }
1192
1193            if (!isTextInput(clickedObjectElement)) {
1194                clickedObjectElement.classList.add(carBrandsAndModelsConstants.classSelectedBrand);
1195            }
1196
1197            let brandVariableElement_TextElement = questionContainer.querySelector(`#Text_${brandVariableName}`);
1198            brandVariableElement_TextElement.value = dataStorage.get(clickedObjectElement, "brandName");
1199        }
1200
1201        let urlGetModels = new URL(carBrandsAndModelsConstants.urlGetModelsByBrand, document.location);
1202        urlGetModels.searchParams.append("brandId", selectedBrandId);
1203        urlGetModels.searchParams.append("year", ctrlYearOfManufacture.value);
1204
1205        document.body.style.cursor = 'progress';
1206
1207        let modelVariableId_Element = questionContainer.querySelector(`#${modelVariableName}`);
1208
1209        questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.instandaQuestionInnerL
1209abelPrefix}${modelVariableName}`).style.display = "block";
1210
1211        if (!isHidden(brandVariableIdElement)) {
1212            ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperDropdown}]`));
1213            ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperAutocomplete}]`));
1214            ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperRadio}]`));
1215            ShowElement(questionContainer.querySelector(`div[class*=${carBrandsAndModelsConstants.classModelsWrapperList}]`));
1216        }
1217
1218        Empty(modelVariableId_Element);
1219
1220        fetch(urlGetModels, {
1221            method: 'GET',
1222            headers: {
1223                'Content-Type': carBrandsAndModelsConstants.contentType,
1224                'Accept': carBrandsAndModelsConstants.contentType,
1225                'X-Requested-With': 'XMLHttpRequest'
1226            }
1227        })
1228            .then(res => res.json())
1229            .then(data => {
1230                let modelDataList = null;
1231                if (displayAs === DisplayAsEnum.AutoComplete) {
1232                    modelDataList = questionContainer.querySelector(`#Variables_${modelVariableName}__Choices`);
1233                    Empty(modelDataList);
1234                    if (!isInitialCall)
1235                        questionContainer.querySelector(`#${modelVariableName}`).value = "";
1236                }
1237
1238                data.forEach((item) => {
1239                    let powerType = "PS";
1240
1241                    if ('power_type' in item) {
1242                        powerType = item.power_type;
1243                    }
1244
1245                    let text = item.name === '' ? '' : `${item.name} ${item.body_type.name} ${item.power} ${powerType}`;
1246
1247                    let selectedClass = "";
1248
1249                    if (isInitialCall) {
1250                        if (questionContainer.querySelector(`#Text_${modelVariableName}`).value === item.name) {
1251                            selectedClass = carBrandsAndModelsConstants.classSelectedModel;
1252                        }
1253                    }
1254                    else {
1255                        let bodyTypeVariableNameElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`);
1256                        if (bodyTypeVariableNameElement != null) {
1257                            bodyTypeVariableNameElement.value = item.body_type.name;
1258                            bodyTypeVariableNameElement.dispatchEvent(new Event('change'));
1259                        }
1260                    }
1261
1262                    if (displayAs === DisplayAsEnum.List) {
1263                        let liElement = document.createElement('li');
1264                        liElement.classList.add("list-group-item", "list-group-item-action");
1265                        if (selectedClass) {
1266                            liElement.classList.add(selectedClass);
1267                        }
1268                        liElement.innerHTML = text;
1269                        liElement.addEventListener('click', (e) => {
1270                            CarBrandsAndModelsModelChangeJS(e.target, questionContainer, modelVariableName, false);
1271                        });
1272
1273                        modelVariableId_Element.appendChild(liElement);
1274
1275                        SetModelAdditionalData(liElement, item)
1276                    }
1277                    else if (displayAs === DisplayAsEnum.Dropdown) {
1278                        let optionElement = document.createElement('option');
1279                        optionElement.value = item.value;
1280                        optionElement.selected = (selectedClass !== "");
1281                        optionElement.text = text;
1282                        if (selectedClass)
1283                            optionElement.classList.add(selectedClass);
1284                        modelVariableId_Element.appendChild(optionElement);
1285
1286                        SetModelAdditionalData(optionElement, item)
1287                    }
1288                    else if (displayAs === DisplayAsEnum.Radio) {
1289                        if (item.name !== '') {
1290                            let radioItemElement = document.createElement("input");
1291                            radioItemElement.type = "radio";
1292                            radioItemElement.id = `${modelVariableName}_radio${item.id}`;
1293                            radioItemElement.name = `${modelVariableName}_radio`;
1294                            radioItemElement.value = item.name;
1295                            radioItemElement.checked = (selectedClass !== "");
1296                            radioItemElement.addEventListener('click', (e) => {
1297                                CarBrandsAndModelsModelChangeJS(e.target, questionContainer, modelVariableName, false);
1298                            });
1299                            let description = document.createTextNode(` ${text}`);
1300                            modelVariableId_Element.appendChild(radioItemElement);
1301                            modelVariableId_Element.appendChild(description);
1302                            modelVariableId_Element.appendChild(document.createElement('br'));
1303                            SetModelAdditionalData(radioItemElement, item);
1304                        }
1305                    }
1306                    else {
1307                        //autocomplete
1308                        let dataListItem = document.createElement('option');
1309                        dataListItem.value = text;
1310                        modelDataList.appendChild(dataListItem);
1311                        SetModelAdditionalData(dataListItem, item);
1312                    }
1313                });
1314
1315                if (!isInitialCall) {
1316                    if (displayAs === DisplayAsEnum.List) {
1317                        let liElements = modelVariableId_Element.getElementsByTagName('li');
1318                        if (liElements.length > 0)
1319                            liElements[0].click();
1320                    }
1321                }
1322                else {
1323                    modelVariableId_Element.dispatchEvent(new Event(carBrandsAndModelsConstants.eventChangeInitial));
1324                }
1325
1326                questionContainer.querySelector(`.${carBrandsAndModelsConstants.classErrorText}`).style.display = 'none';
1327                document.body.style.cursor = '';
1328            }).catch((error) => {
1329                console.debug("brandChange error = ", error);
1330                questionContainer.querySelector(`.${carBrandsAndModelsConstants.classErrorText}`).style.display = 'block';
1331                document.body.style.cursor = '';
1332            });
1333    }
1334}
1335
1336function CarBrandsAndModelsModelChangeJS(
1337    target,
1338    questionContainer,
1339    modelVariableName,
1340    isInitialCall) {
1341    let selectedModelId = null;
1342    let clickedObjectElement = target != null && target.length > 0 ? target[0] : target;
1343
1344    //verify if is Autocomplete 
1345    let modelDataListChoices = questionContainer.querySelector(`#Variables_${modelVariableName}__Choices`);
1346    if (modelDataListChoices) {
1347        let optionAutoCompleteItems = questionContainer.querySelectorAll(`#Variables_${modelVariableName}__Choices option`);
1348        let selectedName = questionContainer.querySelector(`#${modelVariableName}`).value;
1349        let selectedChildElement = Array.from(optionAutoCompleteItems).filter(x => x.value === selectedName);
1350        clickedObjectElement = selectedChildElement[0];
1351        selectedModelId = dataStorage.get(selectedChildElement[0], "modelId");
1352    }
1353    else {
1354        selectedModelId = clickedObjectElement != null ? dataStorage.get(clickedObjectElement, "modelId") : null;
1355    }
1356
1357    let modelElement = questionContainer.querySelector(`#${modelVariableName}`);
1358    let powerTypeElem = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPowerType} select`);
1359    let modelIdVariableElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditModelId}`);
1360
1361    if (!isInitialCall && selectedModelId) {
1362        let selectedItems = modelElement.querySelectorAll(`.${carBrandsAndModelsConstants.classSelectedModel}`);
1363        if (selectedItems.length > 0)
1364            selectedItems.forEach(x => x.classList.remove(carBrandsAndModelsConstants.classSelectedModel));
1365
1366        if (!isTextInput(clickedObjectElement.parentElement)) {
1367            clickedObjectElement.classList.add(carBrandsAndModelsConstants.classSelectedModel)
1368        }
1369
1370        let modelVariableId_TextElement = questionContainer.querySelector("#Text_" + modelVariableName);
1371        modelVariableId_TextElement.value = dataStorage.get(clickedObjectElement, "modelName");
1372        modelIdVariableElement.value = selectedModelId;
1373
1374        let pictureElement = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPictureUrl}`);
1375        let photoUrl = dataStorage.get(clickedObjectElement, "modelPhotoUrl");
1376        pictureElement.value = photoUrl ? photoUrl : "";
1377
1378        UpdateCarBrandsAndModels_ModelDetailsFields(questionContainer, clickedObjectElement)
1379
1380        let urlGetPrices = new URL(carBrandsAndModelsConstants.urlGetPricesByModel, document.location);
1381        urlGetPrices.searchParams.append("modelId", selectedModelId);
1382
1383        document.body.style.cursor = 'progress';
1384
1385        fetch(urlGetPrices, {
1386            method: 'GET',
1387            headers: {
1388                'Content-Type': carBrandsAndModelsConstants.contentType,
1389                'Accept': carBrandsAndModelsConstants.contentType,
1390                'X-Requested-With': 'XMLHttpRequest'
1391            }
1392        })
1393            .then(res => res.json())
1394            .then(data => {
1395
1396                UpdateCarBrandsAndModels_PriceFields(questionContainer, data);
1397
1398                let summaryAlreadyShownElement = questionContainer.querySelector(`#${carBrandsAndModelsConstants.summaryAlreadyShown}`);
1399                if (summaryAlreadyShownElement.value === "false") {
1400                    summaryAlreadyShownElement.value = "true";
1401                    questionContainer.querySelector('.car-brands-and-models-show-summary-' + modelVariableName).click()
1402                }
1403
1404                questionContainer.querySelector(`.${carBrandsAndModelsConstants.classErrorText}`).style.display = 'none';
1405                document.body.style.cursor = '';
1406
1407            }).catch((error) => {
1408                console.debug("modelChange error = ", error);
1409                questionContainer.querySelector(`.${carBrandsAndModelsConstants.classErrorText}`).style.display = 'block';
1410                document.body.style.cursor = '';
1411            });
1412    }
1413    else if (isInitialCall) {
1414        let selectedItems = modelElement.querySelectorAll(`.${carBrandsAndModelsConstants.classSelectedModel}`);
1415        if (selectedItems != null)
1416            selectedItems.forEach(x => x.classList.remove(carBrandsAndModelsConstants.classSelectedModel));
1417        let selected = modelIdVariableElement.value;
1418
1419        if (modelElement.matches("ul")) {
1420            let listItems = modelElement.querySelectorAll(`li`)
1421            listItems.forEach(function (el) {
1422                let modelId = `${dataStorage.get(el, "modelId")}`;
1423                if (selected === modelId) {
1424                    el.classList.add(carBrandsAndModelsConstants.classSelectedModel)
1425                }
1426            });
1427        }
1428    }
1429
1430    let powerTypeNotSelectedOptions = Array.from(powerTypeElem.options).filter(item => !item.selected);
1431    powerTypeNotSelectedOptions.forEach(item => DisableElement(item));
1432
1433    let powerTypeSelectedOptions = Array.from(powerTypeElem.options).filter(item => item.selected);
1434    powerTypeSelectedOptions.forEach(item => EnableElement(item));
1435}
1436
1437function UpdateCarBrandsAndModels_ModelDetailsFields(questionContainer, clickedObjectElement) {
1438    let power = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPower} input`);
1439    let powerType = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPowerType} select`);
1440    let bodyTypeText = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditText_BodyType}`);
1441    let bodyTypeId = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditBodyTypeId}`);
1442    let engineCapacity = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditEngineCapacity} input`);
1443    let cylinders = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditCylinders} input`);
1444
1445    if (power) {
1446        let selectedPower = dataStorage.get(clickedObjectElement, "modelPower");
1447        power.value = selectedPower ? selectedPower : "";
1448    }
1449    if (powerType) {
1450        let selectedPowerType = dataStorage.get(clickedObjectElement, "modelPowerType");
1451        powerType.value = selectedPowerType && selectedPowerType !== "undefined" ? selectedPowerType : "PS";
1452    }
1453    if (bodyTypeText) {
1454        let selectedBodyType = dataStorage.get(clickedObjectElement, "modelBodyTypeName");
1455        bodyTypeText.value = selectedBodyType ? selectedBodyType : "";
1456    }
1457    if (bodyTypeId) {
1458        let selectedBodyTypeId = dataStorage.get(clickedObjectElement, "modelBodyTypeId");
1459        bodyTypeId.value = selectedBodyTypeId ? selectedBodyTypeId : "";
1460    }
1461    if (engineCapacity) {
1462        let selectedCapacity = dataStorage.get(clickedObjectElement, "modelCapacity");
1463        engineCapacity.value = selectedCapacity ? selectedCapacity : "";
1464    }
1465    if (cylinders) {
1466        let selectedCylinders = dataStorage.get(clickedObjectElement, "modelCylinder");
1467        cylinders.value = selectedCylinders ? selectedCylinders : "";
1468    }
1469}
1470
1471function UpdateCarBrandsAndModels_PriceFields(questionContainer, data) {
1472    let priceId = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPriceId} input`);
1473    let grade1 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade1} input`);
1474    let grade2 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade2} input`);
1475    let grade3 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade3} input`);
1476    let grade4 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade4} input`);
1477    let grade5 = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditGrade5} input`);
1478    let priceCurrency = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPriceCurrency} input`);
1479    let priceCountry = questionContainer.querySelector(`.${carBrandsAndModelsConstants.classEditPriceCountry} input`);
1480
1481    if (priceId) {
1482        priceId.value = data.id ;
1483    }
1484    if (grade1) {
1485        grade1.value = data.grade1;
1486    }
1487    if (grade2) {
1488        grade2.value = data.grade2;
1489    }
1490    if (grade3) {
1491        grade3.value = data.grade3;
1492    }
1493    if (grade4) {
1494        grade4.value = data.grade4;
1495    }
1496    if (grade5) {
1497        grade5.value = data.grade5;
1498    }
1499    if (priceCurrency) {
1500        priceCurrency.value = data.currency;
1501    }
1502    if (priceCountry) {
1503        priceCountry.value = data.country;
1504    }
1505}
1506
1507function isTextInput(element) {
1508    return (element.tagName === "INPUT" && element.type === "text");
1509}
1510
1511function SetBrandAdditionalData(element, item) {
1512    dataStorage.put(element, "brandId", item.id);
1513    dataStorage.put(element, "brandName", item.name);
1514}
1515
1516function SetModelAdditionalData(element, item) {
1517    dataStorage.put(element, "modelId", item.id);
1518    dataStorage.put(element, "modelName", item.name);
1519    dataStorage.put(element, "modelPower", item.power);
1520    dataStorage.put(element, "modelPowerType", item.power_type);
1521    dataStorage.put(element, "modelBodyTypeId", item.body_type.id);
1522    dataStorage.put(element, "modelBodyTypeName", item.body_type.name);
1523    dataStorage.put(element, "modelPhotoUrl", item.photo_url);
1524    dataStorage.put(element, "modelCylinder", item.cylinder);
1525    dataStorage.put(element, "modelCapacity", item.capacity);
1526}
1527
1528function Empty(element) {
1529    if (element != null)
1530        while (element.firstChild) element.removeChild(element.firstChild);
1531}
1532
1533function EnableElement(element) {
1534    element.removeAttribute('disabled');
1535}
1536
1537function DisableElement(element) {
1538    element.setAttribute('disabled', '');
1539}
1540
1541function HideElement(element) {
1542    if (element !== null) {
1543        element.style.display = 'none';
1544    }
1545}
1546
1547function ShowElement(element) {
1548    if (element !== null) {
1549        element.style.display = 'block';
1550    }
1551}
1552
1553function HideElementById(elementId) {
1554    if (document.getElementById(elementId) !== null) {
1555        document.getElementById(elementId).style.display = 'none';
1556    }
1557}
1558
1559function ShowElementById(elementId) {
1560    if (document.getElementById(elementId) !== null) {
1561        document.getElementById(elementId).style.display = 'block';
1562    }
1563}
1564
1565function SetReadonly(element) {
1566    element.setAttribute('readonly', true);
1567}
1568
1569function RemoveReadonly(element) {
1570    element.removeAttribute('readonly');
1571}
1572
1573function EnableManualInputIfClassicAnalyticsNotAvailable(container) {
1574    CheckIfClassicAnalyticsInterfaceIsAvailable(function () {
1575        let element = container.querySelector(`.${carBrandsAndModelsConstants.classCarNotInList} input[type=checkbox]`);
1576        if (!element.checked) {
1577            element.click();
1578        }
1579    });
1580}
1581
1582const isHidden = elem => {
1583    return (elem.offsetParent === null)
1584}
1585
1586window.dataStorage = {
1587    _storage: new WeakMap(),
1588    put: function (element, key, obj) {
1589        if (!this._storage.has(element)) {
1590            this._storage.set(element, new Map());
1591        }
1592        this._storage.get(element).set(key, obj);
1593    },
1594    get: function (element, key) {
1595        return (this._storage.has(element) && this._storage.get(element).has(key)) ? this._storage.get(element).get(key) : null;
1596    },
1597    has: function (element, key) {
1598        return this._storage.has(element) && this._storage.get(element).has(key);
1599    },
1600    remove: function (element, key) {
1601        var ret = this._storage.get(element).delete(key);
1602        if (this._storage.get(element).size !== 0) {
1603            this._storage.delete(element);
1604        }
1605        return ret;
1606    }
1607};
1608function lookupCarDetailsJS(isExperianEnabled, questionId, colourVariableName, makeVariableName, modelVariableName, registrationVariableName, yearOfManufactureVariableName, abiGroupVariableName, doorPlanCodeVariableName, wheelPlanCodeVariableName, grossVehicleWeightVariableName, engineCapacityVariableName, transmissionCodeVariableName) {
1609
1610    let carDetailsSelector = 'instanda-car-details-question-input';
1611    let notFoundSelector = 'vehicle-not-found';
1612    let forbiddenSelector = 'vehicle-access-forbidden';
1613    let lookupErrorSelector = 'vehicle-lookup-error';
1614    let regEmptySelector = 'registration-empty';
1615    let registrationNumberLengthErrorSelector = 'registration-length-incorrect';
1616    let systemFailureSelector = "system-failure";
1617
1618    if (questionId) {
1619        carDetailsSelector = `${carDetailsSelector}_${questionId}`;
1620        notFoundSelector = `${notFoundSelector}_${questionId}`;
1621        forbiddenSelector = `${forbiddenSelector}_${questionId}`;
1622        lookupErrorSelector = `${lookupErrorSelector}_${questionId}`;
1623        regEmptySelector = `${regEmptySelector}_${questionId}`;
1624        registrationNumberLengthErrorSelector = `${registrationNumberLengthErrorSelector}_${questionId}`;
1625        systemFailureSelector = `${systemFailureSelector}_${questionId}`;
1626    }
1627
1628    document.getElementById(notFoundSelector).style.display = 'none';
1629    document.getElementById(regEmptySelector).style.display = 'none';
1630    document.getElementById(registrationNumberLengthErrorSelector).style.display = 'none';
1631    document.getElementById(systemFailureSelector).style.display = 'none';
1632
1633    let getElementIdForVariableName = function (variableName) {
1634        return `Variables_${variableName}__Answer`
1635    };
1636
1637    let populateFields = function (data) {
1638        if (data === "VehicleNotFound") {
1639            document.getElementById(notFoundSelector).style.display = 'block';
1640        } else if (data === "AccessForbidden") {
1641            document.getElementById(forbiddenSelector).style.display = 'block';
1642        } else if (data === "InvalidRegistrationNumber") {
1643            document.getElementById(registrationNumberLengthErrorSelector).style.display = 'block';
1644        } else if (data === "SystemFailure") {
1645            document.getElementById(systemFailureSelector).style.display = 'block';
1646        } else {
1647            const {
1648                Colour,
1649                Make,
1650                Model,
1651                YearOfManufacture,
1652                ABIGroup,
1653                DoorPlanCodeVariableName,
1654                WheelPlanCodeVariableName,
1655                GrossVehicleWeightVariableName,
1656                EngineCapacityVariableName,
1657                TransmissionCodeVariableName
1658            } = data;
1659
1660            document.getElementById(getElementIdForVariableName(colourVariableName)).value = Colour;
1661            document.getElementById(getElementIdForVariableName(makeVariableName)).value = Make;
1662            document.getElementById(getElementIdForVariableName(modelVariableName)).value = Model;
1663            document.getElementById(getElementIdForVariableName(yearOfManufactureVariableName)).value = YearOfManufacture;
1664            document.getElementById(getElementIdForVariableName(abiGroupVariableName)).value = ABIGroup;
1665            document.getElementById(getElementIdForVariableName(doorPlanCodeVariableName)).value = DoorPlanCodeVariableName;
1666            document.getElementById(getElementIdForVariableName(wheelPlanCodeVariableName)).value = WheelPlanCodeVariableName;
1667            document.getElementById(getElementIdForVariableName(grossVehicleWeightV
1667ariableName)).value = GrossVehicleWeightVariableName;
1668            document.getElementById(getElementIdForVariableName(engineCapacityVariableName)).value = EngineCapacityVariableName;
1669            document.getElementById(getElementIdForVariableName(transmissionCodeVariableName)).value = TransmissionCodeVariableName;
1670
1671            document.getElementById(carDetailsSelector).style.display = 'block';
1672        }
1673    };
1674
1675    let clear = function () {
1676        let data = {
1677            Color: null,
1678            Make: null,
1679            Model: null,
1680            YearOfManufacture: null,
1681            ABIGroup: null,
1682            DoorPlanCodeVariableName: null,
1683            WheelPlanCodeVariableName: null,
1684            GrossVehicleWeightVariableName: null,
1685            EngineCapacityVariableName: null,
1686            TransmissionCodeVariableName: null
1687        };
1688
1689        populateFields(data);
1690    };
1691
1692    let apiError = function () {
1693        document.getElementById(lookupErrorSelector).style.display = 'block';
1694        clear();
1695    };
1696
1697    let reg = document.getElementById(getElementIdForVariableName(registrationVariableName)).value.trim();
1698
1699    let urlToCall = "LookupCarDetails?registration=" + reg;
1700
1701    if (reg.length < 1) {
1702        document.getElementById(regEmptySelector).style.display = 'block';
1703    } else {
1704        if (isExperianEnabled) {
1705            fetch(urlToCall, {
1706                method: 'GET'
1707            })
1708                .then(res => res.json())
1709                .then(data => {
1710                    populateFields(data)
1711                })
1712                .catch(_ => {
1713                    apiError()
1714                });
1715        }
1716    }
1717};
1718class OptionData {
1719    constructor(variableIndex, text, value, isSelected) {
1720        this.VariableIndex = variableIndex;
1721        this.Text = text;
1722        this.Value = value;
1723        this.IsSelected = isSelected;
1724    }
1725}
1726
1727class QuestionHierarchy {
1728    constructor(id, json, maxDepthLevel) {
1729        this.Id = id;
1730        this.Json = json;
1731        this.MaxDepthLevel = maxDepthLevel;
1732    }
1733
1734    isValid = () => {
1735        return this.Id && this.Json && !isNaN(this.MaxDepthLevel) && this.MaxDepthLevel >= 0;
1736    }
1737}
1738
1739class QuestionHierarchyElementType {
1740    static Dropdown = new QuestionHierarchyElementType('dropdown')
1741    static Autocomplete = new QuestionHierarchyElementType('autocomplete')
1742    static Radio = new QuestionHierarchyElementType('radio')
1743
1744    constructor(type) {
1745        this.type = type;
1746    }
1747}
1748
1749//Query Selectors
1750const hierarchyQuestionParentContainerQuerySelector = '.questionItem.instanda-question-item.container';
1751const hierarchyQuestionNumHierarchyColumnsQuerySelector = 'input[name="NumHierarchyColumns"]';
1752
1753//Element class names
1754const hierarchyQuestionContainerClassName = 'instanda-choice-lookup-hierarchy-question-container';
1755const hierarchyQuestionItemClassName = 'instanda-choice-lookup-question-item';
1756const hierarchyQuestionItemElementGenericInputClassName = 'instanda-question-input';
1757const hierarchyQuestionItemElementSelectClassName = 'instanda-dropdown-input';
1758const hierarchyQuestionItemElementAutocompleteClassName = 'instanda-autocomplete-input';
1759const hierarchyQuestionItemElementRadioClassName = 'instanda-radio-input';
1760
1761//Element Ids
1762const hierarchyQuestionDataDivId = 'advanced-choice-hierarchy-data';
1763const hierarchyQuestionDataTemplateId = `${hierarchyQuestionDataDivId}-template`;
1764
1765//Default strings
1766const selectedText = 'selected';
1767const selectElementText = 'select';
1768const optionElementText = 'option';
1769const clickEventTypeText = 'click';
1770const changeEventTypeText = 'change';
1771const displayPropertyText = 'display';
1772
1773document.addEventListener('DOMContentLoaded', addButtonEvents);
1774
1775function addButtonEvents(event) {
1776    const addButton = document.getElementById('add-new-btn');
1777
1778    if (addButton) {
1779        addButton.addEventListener(clickEventTypeText, checkAndBindHierarchyData);
1780    }
1781}
1782
1783const validateBasicMethodParams = (hierarchyQuestionGenericInput, index, questionHierarchyObject) => {
1784    if (!hierarchyQuestionGenericInput) {
1785        throw new Error('hierarchyQuestionGenericInput not defined');
1786    } else if (isNaN(index) || index < 0) {
1787        throw new Error('Index not defined');
1788    } else if (!questionHierarchyObject) {
1789        throw new Error('Question hierarchy object not defined');
1790    } else if (!questionHierarchyObject.isValid()) {
1791        throw new Error('Question hierarchy is not valid');
1792    }
1793}
1794
1795const getAllHierarchyQuestionItemsFromGenericInput = (hierarchyQuestionGenericInput, questionId) => {
1796    const parentQuestionHierarchyContainer = hierarchyQuestionGenericInput.closest(`#${questionId}`);
1797    return parentQuestionHierarchyContainer.querySelectorAll(`.${hierarchyQuestionItemClassName}`);
1798}
1799
1800const getCurrentQuestionHierarchyBasedOnSelection = (hierarchyQuestionGenericInput, index, questionHierarchyObject) => {
1801    validateBasicMethodParams(hierarchyQuestionGenericInput, index, questionHierarchyObject);
1802
1803    const allHierarchyQuestionItems = getAllHierarchyQuestionItemsFromGenericInput(hierarchyQuestionGenericInput, questionHierarchyObject.Id);
1804
1805    let currentQuestionHierarchy = questionHierarchyObject.Json;
1806
1807    for (let i = 0; i < index; i++) {
1808        const currentHierarchyQuestionGenericInput = allHierarchyQuestionItems[i].querySelector(`.${hierarchyQuestionItemElementGenericInputClassName}`);
1809        const questionHierarchyElementType = getQuestionHierarchyElementType(currentHierarchyQuestionGenericInput);
1810        let searchedValue = '';
1811
1812        switch (questionHierarchyElementType) {
1813            case QuestionHierarchyElementType.Dropdown.type:
1814                const selectElement = currentHierarchyQuestionGenericInput.querySelector(selectElementText);
1815                searchedValue = selectElement.options[selectElement.selectedIndex].value;
1816                break
1817            case QuestionHierarchyElementType.Autocomplete.type:
1818                break
1819            case QuestionHierarchyElementType.Radio.type:
1820                break;
1821        }
1822
1823        currentQuestionHierarchy = currentQuestionHierarchy.find(h => h.value === searchedValue.toString()).subHierarchy;
1824    }
1825
1826    return currentQuestionHierarchy;
1827}
1828
1829const updateOptionsOnDropdownElement = (dropdownElement, index, questionHierarchyObject) => {
1830    const hierarchyJson = getCurrentQuestionHierarchyBasedOnSelection(dropdownElement, index, questionHierarchyObject);
1831
1832    if (!hierarchyJson) {
1833        return;
1834    }
1835
1836    const optionValues = getOptionValues(hierarchyJson);
1837
1838    optionValues.forEach((oValue) => {
1839        const optionElement = createOption(oValue);
1840        dropdownElement.appendChild(optionElement);
1841    });
1842}
1843
1844const getNextElementIfAny = (previousElement) => {
1845    if (!previousElement) {
1846        console.warn('Previous element not defined');
1847    }
1848
1849    return previousElement.closest(`.${hierarchyQuestionItemClassName}`).nextElementSibling.querySelector(`.${hierarchyQuestionItemElementGenericInputClassName}`);
1850}
1851
1852const removeAllNextHierarchyQuestionGenericInputs = (hierarchyQuestionGenericInput, index, questionHierarchyObject) => {
1853    validateBasicMethodParams(hierarchyQuestionGenericInput, index, questionHierarchyObject);
1854
1855    const allHierarchyQuestionItems = getAllHierarchyQuestionItemsFromGenericInput(hierarchyQuestionGenericInput, questionHierarchyObject.Id);
1856
1857    for (let i = index; i < allHierarchyQuestionItems.length; i++) {
1858        const currentHierarchyQuestionGenericInput = allHierarchyQuestionItems[i].querySelector(`.${hierarchyQuestionItemElementGenericInputClassName}`);
1859        const questionHierarchyElementType = getQuestionHierarchyElementType(currentHierarchyQuestionGenericInput);
1860
1861        switch (questionHierarchyElementType) {
1862            case QuestionHierarchyElementType.Dropdown.type:
1863                const selectElement = currentHierarchyQuestionGenericInput.querySelector(selectElementText);
1864
1865                for (const option of selectElement.querySelectorAll('option[value]')) {
1866                    option.remove();
1867                }
1868                break
1869            case QuestionHierarchyElementType.Autocomplete.type:
1870                break
1871            case QuestionHierarchyElementType.Radio.type:
1872                break;
1873        }
1874    }
1875}
1876
1877const dropdownElementOnChange = (event, index, questionHierarchyObject) => {
1878    const dropdownElement = event.target;
1879    const nextIndex = index + 1;
1880
1881    removeAllNextHierarchyQuestionGenericInputs(dropdownElement, nextIndex, questionHierarchyObject);
1882
1883    const nextElement = getNextElementIfAny(dropdownElement);
1884
1885    if (nextElement && dropdownElement.options[dropdownElement.selectedIndex].value) {
1886        if (nextIndex < questionHierarchyObject.MaxDepthLevel) {
1887            expandNextHierarchyQuestionGenericInput(nextElement, nextIndex, questionHierarchyObject);
1888        }
1889        else {
1890            automaticallySelectFollowingHierarchyQuestionGenericInput(nextElement, nextIndex, questionHierarchyObject);
1891        }
1892    }
1893}
1894
1895const radioButtonElementOnChange = (event, index, questionHierarchyObject) => { }
1896
1897const autocompleteElementOnSelect = (event, index, questionHierarchyObject) => { }
1898
1899const checkAndBindHierarchyData = (event) => {
1900    const hierarchyQuestionContainers = document.querySelectorAll(`.${hierarchyQuestionContainerClassName}`);
1901
1902    if (hierarchyQuestionContainers) {
1903        hierarchyQuestionContainers.forEach((container, index) => {
1904            const jsonRawData = container.querySelector(`#${hierarchyQuestionDataTemplateId}`)
1905                .content.cloneNode(true)
1906                .querySelector(`#${hierarchyQuestionDataDivId}`)
1907                .dataset.obj;
1908
1909            if (jsonRawData) {
1910                const json = JSON.parse(jsonRawData);
1911                const questionId = container.closest(hierarchyQuestionParentContainerQuerySelector).id;
1912                const numHierarchyColumnValue = Number(container.querySelector(hierarchyQuestionNumHierarchyColumnsQuerySelector).value != null
1913                    ? container.querySelector(hierarchyQuestionNumHierarchyColumnsQuerySelector).value
1914                    : 0);
1915
1916                const questionHierarchy = new QuestionHierarchy(questionId, json, numHierarchyColumnValue);
1917
1918                const hierarchyQuestionItems = container.querySelectorAll(`.${hierarchyQuestionItemClassName}`);
1919
1920                hierarchyQuestionItems.forEach((questionItem, index) => {
1921                    const hierarchyQuestionGenericInput = questionItem.querySelector(`.${hierarchyQuestionItemElementGenericInputClassName}`);
1922                    const questionHierarchyElementType = getQuestionHierarchyElementType(hierarchyQuestionGenericInput);
1923
1924                    if (index === 0) {
1925                        expandNextHierarchyQuestionGenericInput(hierarchyQuestionGenericInput, index, questionHierarchy);
1926                    }
1927
1928                    switch (questionHierarchyElementType) {
1929                        case QuestionHierarchyElementType.Dropdown.type:
1930                            const selectElement = hierarchyQuestionGenericInput.querySelector(selectElementText);
1931
1932                            selectElement.addEventListener(changeEventTypeText, (event) => dropdownElementOnChange(event, index, questionHierarchy));
1933
1934                            if (selectElement.selectedIndex > 0) {
1935                                selectElement.dispatchEvent(new Event(changeEventTypeText));
1936                            }
1937                            break
1938                        case QuestionHierarchyElementType.Autocomplete.type:
1939                            break
1940                        case QuestionHierarchyElementType.Radio.type:
1941                            break;
1942                    }
1943                });
1944            }
1945        });
1946    }
1947}
1948
1949const expandNextHierarchyQuestionGenericInput = (hierarchyQuestionGenericInput, index, questionHierarchyObject) => {
1950    validateBasicMethodParams(hierarchyQuestionGenericInput, index, questionHierarchyObject);
1951
1952    if (index < questionHierarchyObject.MaxDepthLevel) {
1953
1954        hierarchyQuestionGenericInput.parentElement.style.removeProperty(displayPropertyText);
1955
1956        const questionHierarchyElementType = getQuestionHierarchyElementType(hierarchyQuestionGenericInput);
1957
1958        switch (questionHierarchyElementType) {
1959            case QuestionHierarchyElementType.Dropdown.type:
1960                const selectElement = hierarchyQuestionGenericInput.querySelector(selectElementText);
1961
1962                updateOptionsOnDropdownElement(selectElement, index, questionHierarchyObject);
1963                break
1964            case QuestionHierarchyElementType.Autocomplete.type:
1965                break
1966            case QuestionHierarchyElementType.Radio.type:
1967                break;
1968        }
1969    }
1970}
1971
1972const automaticallySelectFollowingHierarchyQuestionGenericInput = (hierarchyQuestionGenericInput, index, questionHierarchyObject) => {
1973    validateBasicMethodParams(hierarchyQuestionGenericInput, index, questionHierarchyObject);
1974
1975    const questionHierarchyElementType = getQuestionHierarchyElementType(hierarchyQuestionGenericInput);
1976
1977    switch (questionHierarchyElementType) {
1978        case QuestionHierarchyElementType.Dropdown.type:
1979            const selectElement = hierarchyQuestionGenericInput.querySelector(selectElementText);
1980
1981            updateOptionsOnDropdownElement(selectElement, index, questionHierarchyObject);
1982
1983            setOptionAsSelected(
1984                Array.from(selectElement.options)
1985                    .find(op => !isNaN(Number(selectElement.options[0].dataset.optionId)) && Number(op.dataset.optionId) !== -1));
1986            break
1987        case QuestionHierarchyElementType.Autocomplete.type:
1988            break
1989        case QuestionHierarchyElementType.Radio.type:
1990            break;
1991    }
1992
1993    const nextElement = getNextElementIfAny(hierarchyQuestionGenericInput);
1994
1995    if (nextElement) {
1996        const nextIndex = index + 1;
1997        automaticallySelectFollowingHierarchyQuestionGenericInput(nextElement, nextIndex, questionHierarchyObject);
1998    }
1999}
2000
2001const getQuestionHierarchyElementType = (input) => {
2002    const genericInputClasses = input.classList ? input.classList : '';
2003
2004    if (genericInputClasses.contains(hierarchyQuestionItemElementSelectClassName)) {
2005        return QuestionHierarchyElementType.Dropdown.type;
2006    } else if (genericInputClasses.contains(hierarchyQuestionItemElementAutocompleteClassName)) {
2007        return QuestionHierarchyElementType.Autocomplete.type;
2008    } else if (genericInputClasses.contains(hierarchyQuestionItemElementRadioClassName)) {
2009        return QuestionHierarchyElementType.Radio.type;
2010    }
2011
2012    throw new Error('Cannot find element type');
2013}
2014
2015const getOptionValues = (json) => {
2016    let options = [];
2017
2018    json.forEach((item, index) => {
2019        options.push(
2020            new OptionData(
2021                index,
2022                item.text,
2023                item.value,
2024                item.isSelected)
2025        );
2026    });
2027
2028    return options;
2029}
2030
2031const createOption = (optionData) => {
2032    const option = document.createElement(optionElementText);
2033
2034    option.label = optionData.Text;
2035    option.value = optionData.Value;
2036    option.dataset.variableIndex = optionData.VariableIndex;
2037
2038    if (optionData.IsSelected) {
2039        setOptionAsSelected(option);
2040    }
2041
2042    return option;
2043}
2044
2045const setOptionAsSelected = (option) => {
2046    option.setAttribute(selectedText, selectedText);
2047};
2048const choiceLookupConstants = { 
2049    radioInput: "input[type=radio]",
2050};
2051
2052document.addEventListener("DOMContentLoaded", addEventListenersToChoiceLookupQuestion);
2053document.addEventListener("instanceAdded", addEventListenersToChoiceLookupQuestion);
2054
2055function addEventListenersToChoiceLookupQuestion(event) {
2056    let choiceLookupQuestionContainers = event.target.querySelectorAll(".instanda-choice-lookup-question-container");
2057
2058    choiceLookupQuestionContainers.forEach(container => {
2059        let template = container.querySelector("template.instanda-choice-lookup-question-elements");
2060        let templateContent = template.content;
2061        let isHierarchy = parseInt(templateContent.querySelector("input.instanda-choice-lookup-question-num-hierarchy-columns").value) > 0;
2062
2063        container.querySelectorAll(".instanda-choice-lookup-question-item").forEach((item, index) => {
2064            let type = getChoiceType(item);
2065            if (index === 0) {
2066                if (isHierarchy) {
2067                    hideDuplicateOptions(type[0], type[1]);
2068                }
2069                addListener(type, onOptionChanged);
2070            } else {
2071                hideDuplicateOptions(type[0], type[1]);
2072                addListener(type, onOptionChanged);
2073            }
2074        });
2075    });
2076}
2077
2078let hideDuplicateOptions = (container, type) => {
2079    if (type === "radio") {
2080        let radioInputs = container.querySelectorAll(choiceLookupConstants.radioInput);
2081        radioInputs.forEach((radioInput, index) => {
2082            if (index > 0) {
2083                let previousRadioInput = radioInputs[index - 1];
2084                if (previousRadioInput.value === radioInput.value) {
2085                    radioInput.style.display = "none";
2086                }
2087            }
2088        });
2089    } else if (type === "autocomplete") {
2090        let autocompleteInput = container.querySelector("input");
2091        let options = autocompleteInput.querySelectorAll("option");
2092        options.forEach((option, index) => {
2093            if (index > 0) {
2094                let previousOption = options[index - 1];
2095                if (previousOption.value === option.value) {
2096                    option.style.display = "none";
2097                }
2098            }
2099        });
2100    } else if (type === "dropdown") {
2101        let dropdownInput = container.querySelector("select");
2102        let options = dropdownInput.querySelectorAll("option");
2103        options.forEach((option, index) => {
2104            if (index > 0) {
2105                let previousOption = options[index - 1];
2106                if (previousOption.value === option.value) {
2107                    option.style.display = "none";
2108                }
2109            }
2110        });
2111    }
2112}
2113
2114let onOptionChanged = (event) => {
2115    let element = event.target;
2116    let container = element.closest(".instanda-choice-lookup-question-container");
2117    let template = container.querySelector("template.instanda-choice-lookup-question-elements");
2118    let templateContent = template.content;
2119    let options = templateContent.querySelector("input.instanda-choice-lookup-question-options").value;
2120    let optionsArray = JSON.parse(options);
2121
2122    let optionId = "-1";
2123    if (element.type === "radio") {
2124        optionId = element.dataset.optionId;
2125    } else if (element.type === "text") {
2126        [...element.nextElementSibling.options].forEach(option => {
2127            if (option.value === element.value) {
2128                optionId = option.dataset.optionId;
2129            }
2130        });
2131    } else {
2132        optionId = element.options[element.selectedIndex].dataset.optionId;
2133    }
2134    let selectedOptionId = parseInt(optionId);
2135    let selectedOptions = optionsArray[selectedOptionId];
2136    if (optionId !== "-1") {
2137        setLookupOptions(container, selectedOptions, optionId);
2138    }
2139}
2140
2141let setLookupOptions = (container, options, optionId) => {
2142    container.querySelectorAll(".instanda-choice-lookup-question-item").forEach((item, index) => {
2143        let type = getChoiceType(item);
2144        setChoiceInput(type[0], type[1], options[index], optionId)
2145    });
2146}
2147
2148let getChoiceType = (container) => {
2149    let radio = container.querySelector(".instanda-radio-input");
2150    let autocomplete = container.querySelector(".instanda-autocomplete-input");
2151    let dropdown = container.querySelector(".instanda-dropdown-input");
2152
2153    if (radio !== null) {
2154        return [radio, "radio"];
2155    } else if (autocomplete !== null) {
2156        return [autocomplete, "autocomplete"];
2157    } else if (dropdown !== null) {
2158        return [dropdown, "dropdown"];
2159    }
2160    return [null, ""];
2161}
2162
2163let setChoiceInput = (container, type, value, optionId) => {
2164    if (type === "radio") {
2165        let radioInputs = container.querySelectorAll(choiceLookupConstants.radioInput);
2166        radioInputs.forEach(radioInput => {
2167            if (radioInput.dataset.optionId === optionId) {
2168                radioInput.setAttribute("checked", "checked");
2169            } else {
2170                radioInput.removeAttribute("checked");
2171            }
2172        });
2173    } else if (type === "dropdown") {
2174        let dropdownInput = container.querySelector("select");
2175        [...dropdownInput.options].forEach(o => {
2176            if (o.dataset.optionId === optionId) {
2177                o.setAttribute("selected", "selected");
2178            } else {
2179                o.removeAttribute("selected");
2180            }
2181        })
2182        dropdownInput.value = value;
2183    } else if (type === "autocomplete") {
2184        let autocompleteInput = container.querySelector("input");
2185        autocompleteInput.value = value;
2186    }
2187}
2188
2189let addListener = ([container, type], listener) => {
2190    if (type === "radio") {
2191        let radioInputs = container.querySelectorAll(choiceLookupConstants.radioInput);
2192        radioInputs.forEach(radioInput => {
2193            radioInput.addEventListener("change", listener);
2194        });
2195    } else if (type === "autocomplete") {
2196        let autocompleteInput = container.querySelector("input");
2197        autocompleteInput.addEventListener("change", listener);
2198    } else if (type === "dropdown") {
2199        let dropdownInput = container.querySelector("select");
2200        dropdownInput.addEventListener("change", listener);
2201    }
2202}
2203;
2204document.addEventListener("DOMContentLoaded", addEventListenersToChoiceParentQuestion);
2205document.addEventListener("instanceAdded", addEventListenersToChoiceParentQuestion)
2206
2207function addEventListenersToChoiceParentQuestion(event) {
2208    let choiceParentElements = event.target.querySelectorAll(".instanda-choice-parent-question-container");
2209
2210    choiceParentElements.forEach(choiceParentElement => {
2211        let duplicate = choiceParentElement.cloneNode(true);
2212        duplicate.querySelector(".choice-parent-child-question-container").remove();
2213        let dropdown = duplicate.querySelector(".instanda-dropdown-input");
2214        let radio = duplicate.querySelector(".instanda-radio-input");
2215
2216        if (dropdown !== null) {
2217            let dropdownInput = duplicate.querySelector("select");
2218            document.querySelector(`#${dropdownInput.id}`).addEventListener("change", toggleChoiceParentChildQuestions);
2219        } else if (radio !== null) {
2220            let radioInputs = duplicate.querySelectorAll("input[type=radio]");
2221            radioInputs.forEach((radioInput) =>
2222                document.querySelector(`#${radioInput.id}`).addEventListener("click", toggleChoiceParentChildQuestions));
2223        }
2224    });
2225}
2226
2227function toggleChoiceParentChildQuestions(event) {
2228    const _timeoutDuration = 300;
2229    
2230    let option = event.target;
2231    let container = option.closest(".instanda-choice-parent-question-container");
2232    let childQuestionContainer = container.querySelector(".choice-parent-child-question-container");
2233    let _selectedChoiceOptionId = "-1";
2234
2235    if (option.type === "radio") {
2236        _selectedChoiceOptionId = option.dataset.optionId;
2237    } else {
2238        let selectedIndex = option.options.selectedIndex;
2239        _selectedChoiceOptionId = option.options[selectedIndex].dataset.optionId;
2240    }
2241
2242    let childElementsArray = [...childQuestionContainer.querySelectorAll('fieldset')];
2243    let expandedElements = childElementsArray.filter(x => x.classList.contains('expanded') || x.style.display === '' );
2244    let elementsToExpand = childElementsArray.filter(x => x.classList.contains(`child_container__${_selectedChoiceOptionId}`));
2245
2246    if (expandedElements === elementsToExpand)
2247        return;
2248
2249    if (expandedElements === undefined) {
2250        elementsToExpand.forEach((elementToExpand) => {
2251            elementToExpand.removeAttribute("disabled");
2252            expandElement(elementToExpand);
2253        });
2254        return;
2255    }
2256    
2257    expandedElements.forEach((expandedElement) => collapseElement(expandedElement, _timeoutDuration));
2258    
2259    // wait for collapse to finish before expanding the selected element 
2260    window.setTimeout(() => {
2261        expandedElements.forEach((expandedElement) => {expandedElement.disabled = true;});        
2262
2263        if (elementsToExpand !== undefined) 
2264        {
2265            elementsToExpand.forEach((elementToExpand) => {
2266            elementToExpand.removeAttribute("disabled");
2267            expandElement(elementToExpand);
2268            });
2269        }
2270    }, _timeoutDuration);
2271};
2272document.addEventListener("DOMContentLoaded", addEventListenersToChoiceQuestion);
2273document.addEventListener("instanceAdded", addEventListenersToChoiceQuestion);
2274
2275function addEventListenersToChoiceQuestion(event) {
2276    let choiceQuestionContainer = event.target.querySelectorAll(".instanda-choice-question-container");
2277
2278    choiceQuestionContainer.forEach(choiceQuestion => {
2279        let radio = choiceQuestion.querySelector(".instanda-radio-input");
2280        let autocomplete = choiceQuestion.querySelector(".instanda-autocomplete-input");
2281        let dropdown = choiceQuestion.querySelector(".instanda-dropdown-input");
2282
2283        if (radio !== null) {
2284            let radioInputs = radio.querySelectorAll("input[type=radio]");
2285            radioInputs.forEach(radioInput => {
2286                radioInput.addEventListener("change", onChoiceOptionChanged);
2287            });
2288        } else if (autocomplete !== null) {
2289            let autocompleteInput = autocomplete.querySelector("input");
2290            autocompleteInput.addEventListener("change", onChoiceOptionChanged);
2291        } else if (dropdown !== null) {
2292            let dropdownInput = dropdown.querySelector("select");
2293            dropdownInput.addEventListener("change", onChoiceOptionChanged);
2294        }
2295    });
2296}
2297
2298let onChoiceOptionChanged = (event) => {
2299    let element = event.target;
2300    let container = element.closest(".instanda-choice-question-container");
2301    let otherAnswerContainer = container.querySelector(".instanda-choice-question-other-answer-container");
2302
2303    if (otherAnswerContainer !== null) {
2304        let elementName = element.name.split(".");
2305        elementName.splice(-1, 1, "ValueDotNetType");
2306        let typeElementName = elementName.join(".");
2307        let dotNetTypeElement = document.querySelector(`input[name='${typeElementName}']`);
2308        let otherOptionText = otherAnswerContainer.querySelector(".instanda-question-other-option-text").value;
2309        let initialVariableType = otherAnswerContainer.querySelector(".instanda-question-answer-type").value;
2310
2311        if (element.value === otherOptionText) {
2312            if (dotNetTypeElement.value === "Decimal") {
2313                dotNetTypeElement.value = "String"
2314            }
2315            otherAnswerContainer.style.display = "block";
2316            otherAnswerContainer.removeAttribute("disabled");
2317        } else {
2318            dotNetTypeElement.value = initialVariableType;
2319            otherAnswerContainer.style.display = "none";
2320            otherAnswerContainer.setAttribute("disabled", "disabled");
2321        }
2322    }
2323};
2324;
2325document.addEventListener("instanceAdded", addEventListenersToDynamicTotal);
2326document.addEventListener("DOMContentLoaded", addEventListenersToDynamicTotal);
2327
2328function addEventListenersToDynamicTotal(event) {
2329    let dynamicTotalQuestions = event.target.querySelectorAll(".instanda-dynamic-total-question");
2330    dynamicTotalQuestions.forEach((question) => {
2331        addEventListenerToDynamicTotal(question);
2332    });
2333}
2334
2335function addEventListenerToDynamicTotal(question) {
2336    let variableValues = question.querySelector('input[type="hidden"]').value.split(",");
2337
2338    let inputsToSum = [];
2339    variableValues.forEach(function (variableValue) {
2340        if (question.closest(".instanda-instance-container")) {
2341            let multiItemContainer = question.closest(".instanda-instance-container");
2342            inputsToSum.push(multiItemContainer.querySelector(`input[name$="Variables[${variableValue}].Answer`));
2343        } else {
2344            inputsToSum.push(document.querySelector(`input[name$="Variables[${variableValue}].Answer`));
2345        }
2346    });
2347    sumInputs(inputsToSum, question);
2348
2349    inputsToSum.forEach(function (input) {
2350        input.addEventListener("change", function () {
2351            sumInputs(inputsToSum, question);
2352        });
2353    });
2354}
2355
2356function sumInputs(inputsToSum, question) {
2357    let total = 0;
2358    inputsToSum.forEach(function (inputToSum) {
2359        let valueToSum = inputToSum.value.replace(/,/g, '');
2360        if (!isNaN(parseFloat(valueToSum))) {
2361            total += parseFloat(valueToSum);
2362        }
2363    });
2364
2365    question.querySelector('.instanda-dynamic-total-value').innerHTML = total;
2366}
2367;
2368document.addEventListener("DOMContentLoaded", function () {
2369    const fieldValidationError = "field-validation-error";
2370
2371    let observer = new MutationObserver((mutations) => {
2372        mutations.forEach((mutation) => {
2373            if (mutation.type === "attributes" && mutation.target.classList.contains(fieldValidationError)) {
2374                let header = mutation.target.closest(".header-question-container");
2375                let content = header.querySelector('.content');
2376                expandElement(content);
2377                header.open = true;
2378            }
2379        });
2380    });
2381
2382    document.querySelectorAll(".header-question-container").forEach(header => {
2383        let errorSpans = header.querySelectorAll(".instanda-question-validation-message > span");
2384        errorSpans.forEach(span => {
2385            if (span.classList.contains(fieldValidationError)) {
2386                let content = header.querySelector('.content');
2387                toggleElement(content);
2388                header.open = true;
2389            }
2390        });
2391
2392        observer.observe(header, {
2393            attributes: true,
2394            childList: true,
2395            characterData: true,
2396            subtree: true
2397        });
2398        
2399        header.querySelector('summary')
2400            .addEventListener('click', (e) => {
2401            overrideClick(e);
2402        });
2403    });
2404});
2405
2406const overrideClick = (e) => {
2407    e.preventDefault();
2408    let header = e.currentTarget.closest('details');
2409    let content = header.querySelector('.content');
2410    toggleElement(content);
2411    header.open = true;
2412};
2413let OnImageChoiceClicked = (clickedImage) => {
2414    let container = clickedImage.closest('.instanda-image-choice-question-container');
2415    container.querySelectorAll('input[type="radio"]').forEach((radio) => {
2416        radio.removeAttribute('checked');
2417        let image = radio.nextElementSibling;
2418        if (!image.classList.contains("deselectedChoiceImage")) {
2419            image.classList.add("deselectedChoiceImage");
2420        }
2421    });
2422
2423    clickedImage.classList.remove("deselectedChoiceImage");
2424    clickedImage.previousElementSibling.setAttribute('checked', '');
2425};
2426const maskedConstants = {
2427    instandaQuestionInput: "div.instanda-question-input"
2428}
2429
2430document.addEventListener("DOMContentLoaded", function () {
2431    let maskedInputs = document.querySelectorAll("div.masked-hidden-input input[value='masked']");
2432    maskedInputs.forEach((input) => {
2433        let questionContainer = input.closest(maskedConstants.instandaQuestionInput);
2434        let maskedInputValue = questionContainer.querySelector("input").value;
2435        if (maskedInputValue !== null && maskedInputValue !== "") {
2436            onCancelMaskedInput(questionContainer.querySelector("input"), maskedInputValue);
2437        }
2438
2439        let validationEl = questionContainer.nextElementSibling.querySelector("span");
2440        if (validationEl.innerHTML !== "") {
2441            onEditMaskedInput(questionContainer.querySelector("input"), false);
2442        }
2443    });
2444});
2445
2446function onEditMaskedInput(el, removeValue = true) {
2447    let questionContainer = el.closest(maskedConstants.instandaQuestionInput);
2448    let input = questionContainer.querySelector("input");
2449    let maskedInput = questionContainer.querySelector(".masked-hidden-input > input[value='masked']");
2450    if (questionContainer.classList.contains("instanda-date-input")) {
2451        input.type = "date";
2452    }
2453    if (removeValue) {
2454        input.value = "";
2455    }
2456    input.removeAttribute("disabled");
2457    maskedInput.setAttribute("disabled", "disabled");
2458    questionContainer.querySelector("div[name='edit_icon']").style.display = "none";
2459    questionContainer.querySelector("div[name='cancel_icon']").style.display = "block";
2460}
2461
2462function onCancelMaskedInput(el, processedValue) {
2463    let questionContainer = el.closest(maskedConstants.instandaQuestionInput);
2464    let input = questionContainer.querySelector("input");
2465    let maskedInput = questionContainer.querySelector(".masked-hidden-input > input[value='masked']");
2466    if (questionContainer.classList.contains("instanda-date-input")) {
2467        input.type = "text";
2468    }
2469    input.value = processedValue;
2470    maskedInput.removeAttribute("disabled");
2471    input.setAttribute("disabled", "disabled");
2472    questionContainer.querySelector("div[name='edit_icon']").style.display = "block";
2473    questionContainer.querySelector("div[name='cancel_icon']").style.display = "none";
2474};
2475const multiItemConfiguration = {
2476    DefaultAnimationDuration: 500
2477};
2478
2479document.addEventListener('DOMContentLoaded', function () {
2480    let multiItemContainer = document.querySelectorAll('.multi-item-question-container');    
2481    
2482    multiItemContainer.forEach(function (questionContainer) {
2483        let summaryEnabled = questionContainer.querySelector(".instanda-multi-item-instance-summary-header") !== null;
2484        
2485        if (questionContainer.querySelector(".instanda-multi-item-instance-summary-header")) {
2486            questionContainer.querySelectorAll(".instanda-instance-container").forEach(instanceContainer => {
2487                let instanceIndex = instanceContainer.querySelector('input[name$="].InstanceIndex"]').value;
2488                let packageId = instanceContainer.querySelector('input[name$="].PackageId"]').value;
2489                addBlurEventToNewInstanceInputs(document, packageId, instanceIndex, true);
2490                collapseInstanceIfValid(summaryEnabled, instanceContainer);
2491            });
2492        }
2493    });
2494});
2495
2496function addInstance(multiItemQuestionId, maxInstanceLimit, minInstanceLimit, multiItemVariableName, packageId, middleRemoveEnabled, isSummaryEnabled) {
2497    const instanceNodes = document.querySelectorAll(`#question${multiItemQuestionId} .instanda-instance-container`);
2498    const instanceCount = instanceNodes.length;
2499    let countValue = document.getElementsByName(`Variables[${multiItemVariableName}_Count].Answer`)[0];
2500
2501    if (instanceCount === maxInstanceLimit - 1) {
2502        document.getElementById(`${multiItemVariableName}AddButton`).disabled = true;
2503    }
2504
2505    if (instanceCount >= maxInstanceLimit) {
2506        return;
2507    }
2508
2509    let hiddenInstance = document.querySelector(`#question${multiItemQuestionId} .instanda-instance-container-hidden.instance-0`)
2510    let newInstance = hiddenInstance.cloneNode(true);
2511    let lastInstanceIndex = instanceNodes.length > 0 ? instanceNodes[instanceCount - 1].querySelector(`input[name^='Variables[${packageId}]'][name$='.InstanceIndex']`).value : 0;
2512    let newInstanceIndex = parseInt(lastInstanceIndex) + 1;
2513    let innerHtml = newInstance.innerHTML;
2514
2515    let destroyZWS = new RegExp(String.fromCharCode(8203), "g");
2516    innerHtml = innerHtml.replace(destroyZWS, "");
2517    
2518    let regExString = `Variables[${packageId}].Instances[0]`;
2519    let newInnerHtml = innerHtml.replaceAll(regExString, `Variables[${packageId}].Instances[${newInstanceIndex}]`);
2520    
2521    newInnerHtml = newInnerHtml.replace(new RegExp(`Variables_${packageId}__Instances_0_`, 'g'), `Variables_${packageId}__Instances_${newInstanceIndex}_`);
2522    newInstance.innerHTML = newInnerHtml;
2523
2524    newInstance.querySelector(`h3.multi-item-display-name span.display-name-instance-index`).innerText = newInstanceIndex;
2525    let instanceIndexEl = newInstance.querySelector(`input[name$='Variables[${packageId}].Instances[${newInstanceIndex}].InstanceIndex']`);
2526    let positionEl = newInstance.querySelector(`input[name$='Variables[${packageId}].Instances[${newInstanceIndex}].Variables[Position].Answer']`);
2527    instanceIndexEl.value = newInstanceIndex;
2528    positionEl.value = newInstanceIndex;
2529
2530    newInstance.classList.remove('instanda-instance-container-hidden', 'instance-0');
2531    newInstance.classList.add('instanda-instance-container', `instance-${newInstanceIndex}`);
2532
2533    let helpTextLinks = newInstance.querySelectorAll(`.instanda-responsive-help-icon-link`);
2534
2535    helpTextLinks.forEach(htl => {
2536        let previousValue = htl.getAttribute(`data-target`);
2537        newInstance.querySelector(previousValue).id = `${newInstance.querySelector(previousValue).id}_${newInstanceIndex}`;
2538        htl.setAttribute(`data-target`, `${previousValue}_${newInstanceIndex}`);
2539    })
2540
2541    if (isSummaryEnabled) {
2542        addBlurEventToNewInstanceInputs(newInstance, packageId, newInstanceIndex, false);
2543    }
2544
2545    if (middleRemoveEnabled) {
2546        newInstance.querySelectorAll(`#${multiItemVariableName}0RemoveButton`).forEach(rb => {
2547            rb.id = `${multiItemVariableName}${newInstanceIndex}RemoveButton`;
2548            rb.setAttribute('onclick', `removeInstance(${multiItemQuestionId}, ${newInstanceIndex}, ${minInstanceLimit}, '${multiItemVariableName}')`);
2549        });
2550    } else {
2551        document.getElementById(`${multiItemVariableName}RemoveButton`).removeAttribute('disabled');
2552    }
2553
2554    instanceNodes.length > 0 ? instanceNodes[instanceCount - 1].after(newInstance) : hiddenInstance.after(newInstance);
2555
2556    expandElement(newInstance, multiItemConfiguration.DefaultAnimationDuration);
2557    
2558    const newInstanceNodes = document.querySelectorAll(`#question${multiItemQuestionId} .instanda-instance-container`);
2559    newInstanceNodes.forEach(node => node.querySelectorAll(`button[id^='${multiItemVariableName}'][id$='RemoveButton']`)
2560        .forEach(b => b.removeAttribute('disabled')));
2561
2562    countValue.value = parseInt(countValue.value) + 1;
2563    
2564    const event = new Event('instanceAdded');
2565    document.dispatchEvent(event);
2566}
2567
2568function removeLastInstance(multiItemQuestionId, minInstanceLimit, multiItemVariableName) {
2569    const _timeoutDuration = multiItemConfiguration.DefaultAnimationDuration;
2570    const instanceEl = document.querySelectorAll(`#question${multiItemQuestionId} .instanda-instance-container`);
2571    const instanceCount = instanceEl.length;
2572
2573    if (instanceCount === minInstanceLimit + 1) {
2574        document.getElementById(`${multiItemVariableName}RemoveButton`).disabled = true;
2575    }
2576
2577    if (instanceCount <= minInstanceLimit) {
2578        return;
2579    }
2580
2581    collapseElement(instanceEl[instanceCount - 1], _timeoutDuration);
2582    window.setTimeout(() => {
2583        instanceEl[instanceCount - 1].remove();
2584    }, _timeoutDuration);
2585
2586    document.getElementsByName(`Variables[${multiItemVariableName}_Count].Answer`)[0].value = instanceCount - 1;
2587    document.getElementById(`${multiItemVariableName}AddButton`).removeAttribute('disabled');
2588
2589    instanceEl.forEach(node =>
2589 node.querySelectorAll(`button[id^='${multiItemVariableName}'][id$='RemoveButton']`)
2590        .forEach(b => b.setAttribute('disabled', 'disabled')));
2591}
2592
2593function removeInstance(multiItemQuestionId, instanceIndex, minInstanceLimit, multiItemVariableName) {
2594    const _timeoutDuration = multiItemConfiguration.DefaultAnimationDuration;
2595    const instanceEl = document.querySelectorAll(`#question${multiItemQuestionId} .instanda-instance-container.instance-${instanceIndex}`);
2596    let countEl = document.getElementsByName(`Variables[${multiItemVariableName}_Count].Answer`)[0];
2597    let countValue = parseInt(countEl.value);
2598
2599    document.getElementById(`${multiItemVariableName}AddButton`).removeAttribute('disabled');
2600    document.getElementsByName(`Variables[${multiItemVariableName}_Count].Answer`)[0].value = countValue - 1;
2601
2602    if (countValue - 1 <= minInstanceLimit) {
2603        document.querySelectorAll(`#question${multiItemQuestionId} .instanda-instance-container`)
2604            .forEach(node => node.querySelectorAll(`button[id^='${multiItemVariableName}'][id$='RemoveButton']`)
2605                .forEach(b => b.setAttribute('disabled', 'disabled')));
2606    }
2607
2608    collapseElement(instanceEl[0], _timeoutDuration);
2609    window.setTimeout(() => {
2610        instanceEl[0].remove();
2611    }, _timeoutDuration);   
2612}
2613
2614function addBlurEventToNewInstanceInputs(instanceElement, packageId, instanceIndex, initialLoading) {
2615    if (initialLoading === false) {
2616        let summaryElements = instanceElement.querySelectorAll('p.instanda-question-multi-item-summary-answer');
2617        for (let i = 0; i < summaryElements.length; i++) {
2618            summaryElements[i].classList.forEach(c => {
2619                if (c.startsWith('instance-')) {
2620                    summaryElements[i].classList.remove(c);
2621                }
2622            })
2623            summaryElements[i].classList.add('instance-' + instanceIndex);
2624        }
2625    }
2626
2627    let inputs = instanceElement.querySelectorAll(`[name^="Variables[${packageId}].Instances[${instanceIndex}]."][name$="].Answer"]`);
2628    for (let i = 0; i < inputs.length; i++) {
2629        inputs[i].addEventListener('blur', function () {
2630            let variableName = this.name.substring(this.name.lastIndexOf("Variables[") + 10, this.name.lastIndexOf("].Answer"));
2631            let summaryAnswer = instanceElement.querySelector(`.instanda-question-multi-item-summary-answer.instance-${instanceIndex}.${variableName}`);
2632            if (summaryAnswer) {
2633                summaryAnswer.innerText = this.value;
2634            }
2635        });
2636    }
2637}
2638
2639function toggleMultiItemChildQuestionsEditMode(el, editStr, stopEditStr) {
2640    const _timeoutDuration = multiItemConfiguration.DefaultAnimationDuration;
2641    let nextDiv = el.closest('.instanda-multi-item-instance-summary').nextElementSibling;
2642
2643    if (nextDiv.style.display === "none") {
2644        expandElement(nextDiv, _timeoutDuration);
2645        window.setTimeout(() => {
2646            el.innerText = stopEditStr;
2647        }, _timeoutDuration);
2648    } else {
2649        collapseElement(nextDiv, _timeoutDuration);
2650        window.setTimeout(() => {
2651            el.innerText = editStr;
2652        }, _timeoutDuration);
2653    }
2654}
2655
2656function collapseInstanceIfValid(summaryEnabled, instanceContainer) {
2657    if (summaryEnabled) {
2658        let hasError = false;
2659        let errorSpans = instanceContainer.querySelectorAll(".instanda-question-validation-message > span");
2660        errorSpans.forEach(es => {
2661             if (es.classList.contains('field-validation-error')) {
2662                 hasError = true;
2663             }
2664        });
2665        
2666        let allInputs = instanceContainer.querySelectorAll('input, select, textarea');
2667        let visibleInputs = Array.from(allInputs)
2668            .filter(input => input.offsetParent !== null)
2669            .filter(input => !input.disabled)
2670            .filter(input => !input.readOnly);
2671        let hasEmptyQuestion = visibleInputs.some(input => input.value === "");
2672        
2673        if (!hasEmptyQuestion && !hasError) {
2674            // collapse instance
2675            instanceContainer.querySelector('div.action-buttons > button').click();
2676        }
2677    }
2678};
2679document.addEventListener("DOMContentLoaded", function () {
2680    let sliders = document.querySelectorAll(".slider.instanda-number-slider");
2681    sliders.forEach(function (slider) {
2682        let input = slider.querySelector("input[type=range]");
2683        let event = new Event('input');
2684        input.dispatchEvent(event);
2685    });
2686});
2687
2688function onSliderValueChanged(idPrefix, variableName) {
2689    const range = document.querySelector(`#${idPrefix}${variableName}_slider`);
2690    const value = document.querySelector(`#${idPrefix}${variableName}_output`);
2691
2692    let newValue = Number((range.value - range.min) * 100 / (range.max - range.min));
2693    let newPosition = 9 - (newValue * 0.2);
2694
2695    value.parentElement.style.left = `calc(${newValue}% + (${newPosition}px))`;
2696    value.parentElement.style.top = (range.offsetHeight + 3) + 'px';
2697    value.innerHTML = `<span>${range.value}</span>`;
2698
2699    newValue = Number((range.value - range.min) * 100 / (range.max - range.min));
2700    newPosition = 9 - (newValue * 0.2);
2701
2702    value.parentElement.style.left = `calc(${newValue}% + (${newPosition}px))`;
2703    value.innerHTML = `<span>${range.value}</span>`;
2704
2705    document.querySelector(`#${idPrefix}Variables_${variableName}__Answer`).value = range.value;
2706};
2707document.addEventListener("DOMContentLoaded", function () {
2708    
2709    let textEditorContainers = document.querySelectorAll(".instanda-rich-text-input");
2710
2711    textEditorContainers.forEach(function (textEditorContainer) {
2712
2713        let input = textEditorContainer.getElementsByTagName('textarea')[0];
2714        let inputName = input.name;
2715
2716        CKEDITOR.config.extraPlugins = 'confighelper';
2717        let licenseKeyObject = $("#CkEditorLicenseKey")
2718        let licenseKey = licenseKeyObject.val();
2719        licenseKeyObject.remove()
2720
2721        CKEDITOR.config.extraPlugins = 'confighelper';
2722        CKEDITOR.replace(inputName, {
2723            toolbar: [
2724                ['-', 'Cut', 'Copy', 'Paste', '-', 'Undo', 'Redo', 'RemoveFormat'],
2725                ['Table', 'HorizontalRule', 'PageBreak'],
2726                ['Link', 'Unlink'],
2727                ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'],
2728                ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
2729                ['Format', 'Styles', 'Font', 'FontSize'],
2730                ['Bold', 'Italic', 'Underline', 'Superscript', 'Subscript', '-', 'TextColor', "BGColor"]
2731            ],
2732            licenseKey: licenseKey
2733        });        
2734    });
2735});;
2736function toggleYesNoParentChildQuestions(childrenElementName, option, showWhenYes) {
2737    const _timeoutDuration = 300;
2738    
2739    let childQuestionContainer = document.querySelector(`#${childrenElementName}_childQuestionContainer`);
2740
2741    let shouldShow = (option.value === "Yes" && showWhenYes) || (option.value === "No" && !showWhenYes);
2742
2743    if (shouldShow) {
2744        childQuestionContainer.removeAttribute("disabled");
2745        expandElement(childQuestionContainer);
2746    } else {
2747        collapseElement(childQuestionContainer, _timeoutDuration);
2748        window.setTimeout(() => {
2749            childQuestionContainer.disabled = true;
2750        }, _timeoutDuration);
2751    }
2752};

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.