1(function ($) { 2 var $items; 3 4 $.widget("xfaWidget.dxp-dropDownList", $.xfaWidget.listBox, { 5 _widgetName: "dxp-dropDownList", 6 7 getOptionsMap: function () { 8 const parentOptionsMap = 9 $.xfaWidget.listBox.prototype.getOptionsMap.apply(this, arguments); 10 return $.extend({}, parentOptionsMap, { 11 value: (val) => { 12 const that = this; 13 let values = !Array.isArray(this.options.value) 14 ? [this.options.value] 15 : this.options.value, 16 hasItemSelected = false; 17 18 $items = this.$userControl.find("li"); 19 $items.each(function () { 20 const saveVal = $(this).attr("data-save"); 21 22 // Check if this value is present in options value array 23 if ( 24 values && typeof _.contains !== "undefined" 25 ? _.contains(values, saveVal) 26 : _.includes(values, saveVal) 27 ) { 28 that._selectListItem($(this)); 29 hasItemSelected = true; 30 $(this).attr("tabIndex", "-1"); 31 } else { 32 $(this).removeClass("selected").attr("data-selected", false); 33 $(this).attr("tabIndex", "0"); 34 } 35 }); 36 37 if (!hasItemSelected) { 38 $(this.$userControl.find("li").get(0)).attr( 39 "tabIndex", 40 that.options.tabIndex 41 ); 42 !this.options.multiSelect && 43 this.$userControl 44 .find(".cmp-form__dropdown-header-value") 45 .text(that.options.placeholder || ""); 46 } 47 48 this.$userControl.toggleClass( 49 "has-single-item-selected", 50 hasItemSelected && !this.options.multiSelect 51 ); 52 }, 53 items: (val) => { 54 let values = !Array.isArray(val) ? [val] : val; 55 const viewItems = this.$userControl.find("li"); 56 57 //if number of items are not same in model and view then balance it 58 if (viewItems.length > values.length) { 59 for (let i = viewItems.length; i > values.length; i--) { 60 this.deleteItem(i - 1); 61 } 62 } else if (viewItems.length < values.length) { 63 for (let i = values.length; i > viewItems.length; i--) { 64 this.addItem({ 65 sDisplayVal: values[i - 1].display, 66 sSaveVal: values[i - 1].save, 67 }); 68 } 69 } 70 71 values.forEach((element, index) => { 72 const $viewItem = $(viewItems[index]); 73 const $viewItemLabel = $viewItem.find( 74 ".cmp-form__dropdown-item-label" 75 ); 76 if ($viewItemLabel.text() !== element.display) { 77 $viewItemLabel.text(element.display || ""); 78 } 79 80 if ($viewItem.attr("data-save") !== element.save) { 81 $viewItem.attr("data-save", element.save || ""); 82 } 83 }); 84 }, 85 tabIndex: () => { 86 const selectedItems = this.$userControl.find("li.selected"), 87 children = this.$userControl.find("li"); 88 if (selectedItems.length) { 89 selectedItems.eq(0).attr("tabIndex", this.options.tabIndex); 90 } else if (children.length > 0) { 91 children.eq(0).attr("tabIndex", this.options.tabIndex); 92 } 93 }, 94 }); 95 }, 96 97 render: function () { 98 this.element.addClass(this._widgetName); 99 this.element[0].addItem = this.addItem.bind(this); 100 this.element.children().remove(); 101 102 //TODO: add a function for geting textStyle 103 const textStyle = this.getOrElse( 104 this.$data(this.element.get(0), "xfamodel"), 105 "textstyle", 106 "" 107 ), 108 that = this, 109 listElTemplate = 110 '<div class="cmp-form__field cmp-form__dropdown ' + 111 (that.options.multiSelect 112 ? "cmp-form__dropdown--multiselect " 113 : "closed ") + 114 (that.options.disabled ? "disabled" : "") + 115 '" role="button" style="<%=textStyle%>" >' + 116 ' <div class="cmp-form__dropdown-header d-flex align-items-center justify-content-between" tabindex="0">\n' +
117 ' <span class="cmp-form__dropdown-header-value">' + 118 (that.options.multiSelect ? that.options.placeholder : "") + 119 " </span>\n" + 120 (that.options.multiSelect 121 ? "" 122 : '<i class="dxp-icon icon-Chevron_Down-small p-0 align-items-center"></i>\n' + 123 ' <% var testIdDropdown = toCamelCase(placeholder) + "DropDown" %>' + 124 ' <i data-test-id="<% print(testIdDropdown) %>" class="dxp-icon icon-Chevron_Up-small p-0 align-items-center"></i>\n') + 125 " </div>\n" + 126 ' <ul class="cmp-form__dropdown-list" role="combobox">' + 127 " <% _.each(items, function(item){ %>" + 128 ' <% var dropdownItem = item.save ? item.save.replace(/"/g,"""): null; %>' + 129 ' <% var testIdDropdownItem = dropdownItem ? toCamelCase(placeholder) + "Option_" + dropdownItem.replace(/\\./g, "").replace(" ","_").toUpperCase() : null; %>' + 130 ' <li class="cmp-form__dropdown-item d-flex justify-content-between" role="option" data-test-id="<% print(testIdDropdownItem) %>" data-save="<% print(dropdownItem) %>" data-selected="false">' + 131 ' <span class="cmp-form__dropdown-item-label"><% print(item.display) %></span>\n' + 132 (that.options.multiSelect 133 ? '<div class="cmp-form__dropdown-item-checkbox d-flex justify-content-center align-items-center">\n' + 134 '<i class="dxp-icon icon-Check-small"></i>\n' + 135 "</div>" 136 : "") + 137 " </li>" + 138 " <% }) %>" + 139 " </ul>\n" + 140 "</div>", 141 compiledListElTemplate = _.template(listElTemplate); 142 143 const resolvedListEl = compiledListElTemplate({ 144 ...that.options, 145 textStyle: textStyle, 146 items: that.options.items, 147 }); 148 that.element.html( 149 xfalib.ut.XfaUtil.prototype.encodeScriptableTags(resolvedListEl) 150 ); 151 const control = $(that.element.children().get(0)).attr( 152 "name", 153 this.options.name 154 ); 155 this._attachEventHandlers(control); 156 return control; 157 }, 158 159 toCamelCase(str) { 160 return str 161 ? str 162 .toLowerCase() 163 .replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => 164 index === 0 ? match.toLowerCase() : match.toUpperCase() 165 ) 166 .replace(/\s+/g, "") 167 : ""; 168 }, 169 170 focus: function () { 171 if (this.$userControl.find(".selected").length > 0) { 172 this.$userControl.find(".selected")[0].focus(); 173 } else if (this.$userControl.find("li").length > 0) { 174 this.$userControl.find("li")[0].focus(); 175 } 176 }, 177 178 addItem: function (values) { 179 const itemValues = values instanceof Array ? values : [values]; 180 itemValues.forEach((itemvalue) => { 181 $( 182 '<li class="cmp-form__dropdown-item d-flex justify-content-between"></li>' 183 ) 184 .attr("data-save", itemvalue.sSaveVal || "") 185 .html( 186 '<span class="cmp-form__dropdown-item-label">' + 187 itemvalue.sDisplayVal || 188 "" + 189 "</span>m" + 190 (this.options.multiSelect 191 ? '<div class="cmp-form__dropdown-item-checkbox d-flex justify-content-center align-items-center">\n' + 192 '<i class="dxp-icon icon-Check-small"></i>\n' + 193 "</div>" 194 : "") 195 ) 196 .appendTo(this.$userControl.find("ul")) 197 .click($.proxy(this._handleItemClick, this)) 198 .focus($.proxy(this._handleItemFocus, this)) 199 .blur($.proxy(this._handleFocusOut, this)); 200 }); 201 202 // add new item as selected if the value is already present in options 203 if (_.contains(this.options.value, itemValues[0].sSaveVal)) { 204 this._selectListItem( 205 this.$userControl.find("[data-save=" + itemValues.sSaveVal + "]") 206 ); 207 } 208 }, 209 210 clearItems: function () { 211 $(this.$userControl).find("ul").empty(); 212 }, 213 214 deleteItem: function (nIndex) { 215 $(this.$userControl) 216 .find("li") 217 .each(function (index, element) { 218 if (index === nIndex) {
219 $(element).off("click").off("focus").off("blur").remove(); 220 } 221 }); 222 }, 223 224 setFocusCorrectOnToggle: function (event) { 225 let nextSibling = $(event.target).next(); 226 if (nextSibling.length > 0) { 227 let firstChild = nextSibling.children().first(); 228 firstChild.focus(); 229 } 230 }, 231 232 _attachEventHandlers: function ($control) { 233 const that = this; 234 235 if (!that.options.multiSelect) { 236 $control.on("click keydown", function (event) { 237 if ( 238 event.type === "click" || 239 (event.type === "keydown" && event.key === "Enter") 240 ) { 241 if (!$control[0].classList.contains("disabled")) { 242 $control.toggleClass("closed"); 243 that.setFocusCorrectOnToggle(event); 244 } 245 } 246 }); 247 248 $(".guidedropdownlist").on("click", function (event) { 249 if ( 250 !$(event.target).closest($control).length && 251 !$control.hasClass("closed") 252 ) { 253 $control.addClass("closed"); 254 } 255 }); 256 } 257 258 $(document).on("keydown", function (event) { 259 if (event.key === "Escape") { 260 $control.addClass("closed"); 261 } 262 }); 263 264 $control.on("focusout", function (event) { 265 setTimeout(function () { 266 if (!$(document.activeElement).closest($control).length) { 267 $control.addClass("closed"); 268 } 269 }, 10); 270 }); 271 272 273 $control 274 .keydown((e) => this._hotKeys(e)) 275 .find("li") 276 .on("mousedown", function () { 277 if (that.inFocus === true) { 278 that.mouseDown = true; 279 } 280 }) 281 .on( 282 "click keydown", 283 function (e) { 284 if ( 285 e.type === "click" || 286 (e.type === "keydown" && e.key === "Enter") 287 ) { 288 this._handleItemClick(e); 289 } 290 }.bind(this) 291 ) 292 .focus((e) => this._handleItemFocus(e)) 293 .blur((e) => this._handleFocusOut(e)); 294 }, 295 296 _toggleItem: function (item) { 297 const $item = $(item); 298 299 const state = $item.attr("data-selected") !== "true"; 300 $item.attr("data-selected", state); 301 302 if (!this.options.multiSelect) { 303 const $selectedItems = this.$userControl.find("li.selected"); 304 if ($selectedItems.length) { 305 $selectedItems.removeClass("selected").attr("data-selected", false); 306 } 307 } 308 $item.toggleClass("selected", state); 309 310 if (state) { 311 !this.options.multiSelect && 312 this.$userControl 313 .find(".cmp-form__dropdown-header-value") 314 .text($item[0].innerText); 315 } else { 316 !this.options.multiSelect && 317 this.$userControl 318 .find(".cmp-form__dropdown-header-value") 319 .text(this.options.placeholder || ""); 320 } 321 322 this.$userControl.trigger("listboxchange"); 323 324 if (!this.options.multiSelect) { 325 $(this.element.children().get(0)).addClass("closed"); 326 } 327 }, 328 329 getCommitValue: function () { 330 return this.$userControl 331 .find("li") 332 .map((index, element) => { 333 // intentionally using $this.attr("data-save") instead of $this.data("data") 334 return $(element).attr("data-selected") === "true" 335 ? $(element).attr("data-save") 336 : null; 337 }) 338 .get(); 339 }, 340 341 _handleItemClick: function (event) { 342 event.stopPropagation(); 343 if (this.mouseDown === true) { 344 this.mouseDown = false; 345 } 346 if (this.options.access !== "open") { 347 return; 348 } 349 this._toggleItem(event.target); 350 }, 351 352 _hotKeys: function (event) { 353 if (this.options.access !== "open") { 354 return; 355 } 356 if (this.itemInFocus) { 357 switch (event.which) { 358 case 38: //arrow up 359 var prevSibling = $(this.itemInFocus).prev(); 360 if (prevSibling) { 361 this.keyDown = true; 362 prevSibling.focus(); 363 this.keyDown = false; 364 } 365 event.preventDefault(); 366 break; 367 case 40: //arrow down 368 var nextSibling = $(this.itemInFocus).next(); 369 if (nextSibling) { 370 this.keyDown = true; 371 nextSibling.focus(); 372 this.keyDown = false;
373 } 374 event.preventDefault(); 375 break; 376 case 91: //left arrow 377 case 92: //right arrow 378 event.preventDefault(); 379 break; 380 case 32: 381 this._toggleItem(this.itemInFocus); 382 event.preventDefault(); 383 break; 384 default: 385 } 386 } 387 }, 388 389 _handleItemFocus: function (event) { 390 if (this.options.access !== "open") { 391 return; 392 } 393 const item = event.target; 394 this.itemInFocus = item; 395 396 // overriding default widgets handleFocus 397 if (!(this.keyDown || this.mouseDown)) { 398 //we do not need to fire focus event if 399 this.$userControl.trigger("listboxenter"); // clicked on another li element or pressed a key to move the selectio 400 } 401 this.mouseDown = false; 402 this.inFocus = true; 403 }, 404 405 _handleFocusOut: function () { 406 if (!(this.keyDown || this.mouseDown)) { 407 this.$userControl.trigger("listboxexit"); 408 this.inFocus = false; 409 } 410 }, 411 412 _selectListItem: function ($elem) { 413 if ($elem && $elem.length) { 414 $elem 415 .addClass("selected") 416 .attr("tabIndex", this.options.tabIndex) 417 .attr("data-selected", true); 418 !this.options.multiSelect && 419 this.$userControl 420 .find(".cmp-form__dropdown-header-value") 421 .text($elem[0].innerText); 422 this._handlePlaceholder(); 423 } 424 }, 425 426 _handlePlaceholder: function () { 427 if ( 428 !this.options.multiSelect && 429 this.$userControl.attr("placeholder") && 430 !this.$userControl.find("> .cmp-form__dropdown-placeholder-title") 431 .length && 432 !this.$userControl.parent().siblings(".guideFieldLabel").length 433 ) { 434 this.$userControl.prepend( 435 `<label class="cmp-form__dropdown-placeholder-title">${this.$userControl.attr( 436 "placeholder" 437 )}</label>` 438 ); 439 } 440 }, 441 }); 442 443 $(document).ready(function () { 444 const dealerId = getDealerIdFromLocalStorage(); 445 446 $(".submit").on("click", function () { 447 setPreferredDealerForDropDown(dealerId); 448 }); 449 450 setPreferredDealerForDropDown(dealerId); 451 }); 452 453 setPreferredDealerForDropDown = function (dealerId) { 454 const array = $items ? Array.from($items) : []; 455 456 if (dealerId === null) return; 457 458 if (Array.isArray(array) && array.length > 0) { 459 array.forEach((element) => { 460 if (dealerId.toLowerCase() === 461 element.getAttribute("data-save").toLowerCase() && 462 !element.hasAttribute("preferredDealer") 463 ) { 464 $(element).attr("preferredDealer", "true"); 465 $(element).click(); 466 } 467 }); 468 } 469 }; 470 471 getDealerIdFromLocalStorage = function () { 472 const params = new URLSearchParams(window.location.search); 473 const hasRetailer = params.get('retailer'); 474 475 if (hasRetailer) return null; 476 477 const getLocalStorageKey = () => 478 `${window.dxp.settings.brand}_preferred_outlet`; 479 let data = {}; 480 try { 481 const rawData = localStorage.getItem(getLocalStorageKey()); 482 data = rawData ? JSON.parse(rawData) : {}; 483 } catch (error) { 484 console.error("Error parsing localStorage data:", error); 485 } 486 487 return ( 488 (data.preferredOutlet && data.preferredOutlet.uuid) || 489 (data.lastVisitedRetailer && data.lastVisitedRetailer.uuid) || 490 null 491 ); 492 }; 493})($);
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.