1/** 2 * @file 3 * Behaviors of Boostrap Layout Builder local video background. 4 */ 5 6(function ($, _, Drupal, drupalSettings) { 7 "use strict"; 8 9 Drupal.behaviors.scrollEffectsInit = { 10 attach: function (context, settings) { 11 AOS.init(); 12 } 13 } 14 15})(window.jQuery, window._, window.Drupal, window.drupalSettings); 16; 17// /** 18// * @file 19// * Vote Up/Down behavior service 20// */ 21// (function ($, Drupal) { 22 23// window.voteUpDownService = (function() { 24// function voteUpDownService() {} 25// voteUpDownService.vote = function(baseWidget, url, operation) { 26// $.ajax({ 27// type: "GET", 28// url: url, 29// success: function(response) { 30// baseWidget.find('.throbber').remove(); 31// baseWidget.find('.reset').addClass('element-invisible'); 32// baseWidget.find('.up.active').each(function () { 33// $(this).removeClass('active').addClass('inactive'); 34// }); 35// baseWidget.find('.down.active').each(function () { 36// $(this).removeClass('active').addClass('inactive'); 37// }); 38// if(operation !== 'reset') { 39// baseWidget.find('.' + operation).each(function () { 40// $(this).removeClass('inactive').addClass('active'); 41// }); 42// baseWidget.find('.reset').removeClass('element-invisible'); 43// } 44// if (baseWidget.hasClass('vud-widget-upanddown')) { 45// baseWidget.find('.points-up').first().html(response.data.up); 46// baseWidget.find('.points-down').first().html(response.data.down); 47// } else { 48// baseWidget.find('.points-sum').first().html(response.data.sum); 49// } 50// } 51// }); 52// }; 53// return voteUpDownService; 54// })(); 55 56// })(jQuery, Drupal); 57 58 59/** 60 * @file 61 * Vote Up/Down behavior service 62 */ 63(function ($, Drupal) { 64 $(".like-widget .up").attr("aria-label", "Like"); 65 window.voteUpDownService = (function () { 66 function voteUpDownService() {} 67 voteUpDownService.vote = function (baseWidget, url, operation) { 68 $.ajax({ 69 type: "GET", 70 url: url, 71 success: function (response) { 72 baseWidget.find(".throbber").remove(); 73 baseWidget.find(".reset").addClass("element-invisible"); 74 baseWidget.find(".up.active").each(function () { 75 $(this).removeClass("active").addClass("inactive"); 76 $(this).attr("aria-label", "Like"); 77 $('html[lang = "fr"]') 78 .find(".vud-widget a.up") 79 .attr("aria-label", "Aimer"); 80 }); 81 baseWidget.find(".down.active").each(function () { 82 $(this).removeClass("active").addClass("inactive"); 83 $(this).attr("aria-label", "Like"); 84 $('html[lang = "fr"]') 85 .find(".vud-widget a.up") 86 .attr("aria-label", "Aimer"); 87 }); 88 if (operation !== "reset") { 89 baseWidget.find("." + operation).each(function () { 90 $(this).removeClass("inactive").addClass("active"); 91 $(this).attr("aria-label", "Unlike"); 92 $('html[lang = "fr"]') 93 .find(".vud-widget a.up") 94 .attr("aria-label", "Ne plus aimer"); 95 }); 96 baseWidget.find(".reset").removeClass("element-invisible"); 97 } 98 if (baseWidget.hasClass("vud-widget-upanddown")) { 99 baseWidget.find(".points-up").first().html(response.data.up); 100 baseWidget.find(".points-down").first().html(response.data.down); 101 } else { 102 baseWidget.find(".points-sum").first().html(response.data.sum); 103 } 104 }, 105 }); 106 }; 107 return voteUpDownService; 108 })(); 109})(jQuery, Drupal); 110; 111/** 112 * @file 113 * Vote Up/Down behavior. 114 */ 115(function ($, Drupal) { 116 117 Drupal.behaviors.voteUpDown = { 118 attach: function (context, settings) { 119 $('.vud-widget a').click(function (e) { 120 e.preventDefault(); 121 var baseWidget = $(this).parents('.vud-widget'); 122 var routeUrl = $(this).is('a') ? $(this).attr('href') : $(this).parent().attr('href'); 123 var operation; 124 125 // if($(this).is('.inactive')) 126 // baseWidget.append('<img class="throbber" src="' + drupalSettings.path.baseUrl + '/' + settings.basePath + '/img/status-active.gif">'); 127 baseWidget.append('<span class="throbber"><i class="icon icon-reset fa-spin"></i><span class="sr-only">' + Drupal.t('Loading...') + '</span></span>'); 128 129 if($(this).is('a.up.inactive')) 130 operation = 'up'; 131 else if($(this).is('a.down.inactive')) 132 operation = 'down'; 133 else 134 operation = 'reset'; 135 136 voteUpDownService.vote(baseWidget, routeUrl, operation); 137 e.stopImmediatePropagation(); 138 }); 139 } 140 }; 141 142})(jQuery, Drupal); 143; 144/******/ (function(modules) { // webpackBootstrap 145/******/ // The module cache 146/******/ var installedModules = {}; 147/******/ 148/******/ // The require function 149/******/ function __webpack_require__(moduleId) { 150/******/ 151/******/ // Check if module is in cache 152/******/ if(installedModules[moduleId]) { 153/******/ return installedModules[moduleId].exports; 154/******/ } 155/******/ // Create a new module (and put it into the cache) 156/******/ var module = installedModules[moduleId] = { 157/******/ i: moduleId, 158/******/ l: false, 159/******/ exports: {} 160/******/ }; 161/******/ 162/******/ // Execute the module function 163/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 164/******/ 165/******/ // Flag the module as loaded
vendor: 2,824 bytes, lines 166-231
166/******/ module.l = true; 167/******/ 168/******/ // Return the exports of the module 169/******/ return module.exports; 170/******/ } 171/******/ 172/******/ 173/******/ // expose the modules object (__webpack_modules__) 174/******/ __webpack_require__.m = modules; 175/******/ 176/******/ // expose the module cache 177/******/ __webpack_require__.c = installedModules; 178/******/ 179/******/ // define getter function for harmony exports 180/******/ __webpack_require__.d = function(exports, name, getter) { 181/******/ if(!__webpack_require__.o(exports, name)) { 182/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 183/******/ } 184/******/ }; 185/******/ 186/******/ // define __esModule on exports 187/******/ __webpack_require__.r = function(exports) { 188/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 189/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 190/******/ } 191/******/ Object.defineProperty(exports, '__esModule', { value: true }); 192/******/ }; 193/******/ 194/******/ // create a fake namespace object 195/******/ // mode & 1: value is a module id, require it 196/******/ // mode & 2: merge all properties of value into the ns 197/******/ // mode & 4: return value when already ns object 198/******/ // mode & 8|1: behave like require 199/******/ __webpack_require__.t = function(value, mode) { 200/******/ if(mode & 1) value = __webpack_require__(value); 201/******/ if(mode & 8) return value; 202/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 203/******/ var ns = Object.create(null); 204/******/ __webpack_require__.r(ns); 205/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 206/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 207/******/ return ns; 208/******/ }; 209/******/ 210/******/ // getDefaultExport function for compatibility with non-harmony modules 211/******/ __webpack_require__.n = function(module) { 212/******/ var getter = module && module.__esModule ? 213/******/ function getDefault() { return module['default']; } : 214/******/ function getModuleExports() { return module; }; 215/******/ __webpack_require__.d(getter, 'a', getter); 216/******/ return getter; 217/******/ }; 218/******/ 219/******/ // Object.prototype.hasOwnProperty.call 220/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 221/******/ 222/******/ // __webpack_public_path__ 223/******/ __webpack_require__.p = "/"; 224/******/ 225/******/ 226/******/ // Load entry module and return exports 227/******/ return __webpack_require__(__webpack_require__.s = 17); 228/******/ }) 229/************************************************************************/ 230/******/ ({ 231
232/***/ "./src/components/search-rest/search-rest.js": 233/*!***************************************************!*\ 234 !*** ./src/components/search-rest/search-rest.js ***! 235 \***************************************************/ 236/*! no static exports found */ 237/***/ (function(module, exports) { 238 239function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 240 241//current 242(function ($, Drupal) { 243 Drupal.behaviors.searchRest = { 244 attach: function attach(context) { 245 // get from block data-url attr 246 // const SEARCH_URL = 'https://dev-bc-villaggio.millenniumweb.com/rest/products'; 247 var SEARCH_URL = $(".search-rest").attr("data-url"); 248 var pathname = window.location.pathname; // Returns path only (/path/example.html) 249 // let url = window.location.href; // Returns full URL (https://example.com/path/example.html) 250 251 var origin = window.location.origin; // Returns base URL (https://example.com) 252 // let search = window.location.search; 253 // Templates inside JS technique 254 // https://stackoverflow.com/a/39065147 255 256 var Select = function Select(_ref) { 257 var identifier = _ref.identifier, 258 label = _ref.label, 259 multiple = _ref.multiple, 260 options = _ref.options; 261 return "\n <div class=\"select-item select-item-".concat(identifier, "\">\n <label for=\"form-").concat(identifier, "\">").concat(label, "</label>\n <select id=\"form-").concat(identifier, "\" name=\"").concat(identifier, "\" class=\"form-select form-").concat(identifier, " selectpicker\" ").concat(multiple ? "multiple" : "", " data-width=\"auto\" data-dropup-auto=\"false\" data-display=\"static\">\n ").concat(options, "\n </select>\n </div>\n "); 262 }; 263 264 var SelectGroup = function SelectGroup(_ref2) { 265 var identifier = _ref2.identifier, 266 label = _ref2.label, 267 options = _ref2.options; 268 return "\n <optgroup label=\"".concat(label, "\">").concat(options, "</option>\n "); 269 }; 270 271 var SelectOption = function SelectOption(_ref3) { 272 var identifier = _ref3.identifier, 273 label = _ref3.label, 274 parent = _ref3.parent; 275 return "\n <option value=\"".concat(identifier, "\" data-parent=\"").concat(parent, "\">").concat(label, "</option>\n "); 276 }; 277 278 var Pill = function Pill(_ref4) { 279 var name = _ref4.name, 280 value = _ref4.value, 281 label = _ref4.label; 282 return "\n <button class=\"pill badge badge-success\" data-filter=\"".concat(name, "\" data-value=\"").concat(value, "\">").concat(label, " <span class=\"sr-only\">") + Drupal.t("remove filter") + "</span><span aria-hidden=\"true\">×</span></button>\n "; 283 }; // TODO: load filters separately? 284 // function loadFilters(feedUrl) { 285 // } 286 287 288 function loadSearchResults(feedUrl, keep_results) { 289 $.ajax({ 290 method: "GET", 291 url: feedUrl, 292 dataType: "JSON", 293 beforeSend: function beforeSend(xhr) { 294 $(".search-rest").removeClass("is-loaded").addClass("is-loading"); 295 }, 296 error: function error() { 297 $(".search-rest").removeClass("is-loading").addClass("loading-error"); 298 }, 299 success: function success(data) { 300 var $body = $("body"); // console.log('success'); 301 302 $(".search-rest").removeClass("is-loading").addClass("is-loaded").addClass("is-initialized"); 303 304 if (!keep_results) { 305 $(".search-content").html(""); 306 } 307 308 $(".filters-pills").html(""); // hide mobile filters. 309 310 $(".search-filters .filters-wrapper").removeClass("show-filters"); 311 $body.removeClass("modal-open"); // console.log('data', data); 312 // if (!$('.search-content').hasClass('filters-loaded')) { 313 // load filters 314 315 $(".search-filters .filters-placeholder").html(""); 316 $.each(data.options, function (index, element) { 317 if (element.options) { 318 // console.log(element); 319 if (!element.settings.exposed) { 320 return; 321 } 322 323 var options = []; // if is not required AND not multiple, 324 // add - Any - option 325 326 if (!element.settings.expose.required && !element.settings.expose.multiple) { 327 options.push(SelectOption({ 328 identifier: "All", 329 label: "- Any -", 330 parent: 0 331 })); 332 } // check if it's a vocabulary. 333 // console.log('element.options', element.options); 334 335 336 for (var key in element.options) { 337 var newOptions = []; 338 339 if (_typeof(element.options[key]) === "object" && element.options[key] !== null) { 340 // console.log('Variable is an object!'); 341 // console.log(element.options[key]); 342 if (element.options[key]["tid"]) { 343 // console.log('is a term', element.options[key]['tid']); 344 newOptions.push(SelectOption({ 345 identifier: element.options[key]["value"], 346 label: element.options[key]["label"], 347 parent: 0 348 })); 349 } 350 } else { 351 newOptions.push(SelectOption({ 352 identifier: key, 353 label: element.options[key], 354 parent: 0 355 })); 356 } // check if has children 357 358 359 if (element.options[key]["children"]) { 360 // console.log('has children'); 361 for (var childrenKey in element.options[key]["children"]) { 362 // check if it's a vocabulary. 363 if (_typeof(element.options[key]["children"][childrenKey]) === "object" && element.options[key]["children"][childrenKey] !== null) { 364 // console.log('Variable is an object!'); 365 // console.log(element.options[key]['children'][childrenKey]); 366 if (element.options[key]["children"][childrenKey]["tid"]) { 367 // console.log('is a term', element.options[key]['children'][childrenKey]['tid']); 368 newOptions.push(SelectOption({ 369 identifier: element.options[key]["children"][childrenKey]["value"], 370 label: "- " + element.options[key]["children"][childrenKey]["label"], 371 parent: element.options[key]["value"] 372 })); 373 } 374 } else { 375 newOptions.push(SelectOption({ 376 identifier: childrenKey, 377 label: element.options[key]["children"][childrenKey], 378 parent: element.options[key] 379 })); 380 } 381 } // wrap the new options first in an option group, then to the select 382 383 384 options.push(SelectGroup({ 385 identifier: element.options[key]["value"], 386 label: element.options[key]["label"], 387 options: newOptions.join("") 388 })); 389 } else { 390 // push the new options directly to the select 391 //console.log("newOptions"); 392 options.push(newOptions); 393 } 394 } 395 396 $(".search-filters .filters-placeholder").append([{ 397 identifier: element.settings.expose.identifier, 398 label: element.settings.expose.label, 399 options: options.join(""), 400 multiple: element.settings.expose.multiple 401 }].map(Select).join("")); 402 } 403 }); // Sort by (uncomment code below to enable this filter) 404 // identifier: sort_by 405 // label: Sort By 406 // options: 407 // items: data.options.sorting 408 // id: data.options.sorting.[item].id 409 // label: data.options.sorting.[item].expose.label 410 411 var sortByOptions = []; // console.log('data', data.options.sorting[key].expose.label) 412 413 for (var key in data.options.sorting) { 414 if (data.options.sorting[key].exposed) { 415 sortByOptions.push(SelectOption({ 416 identifier: key, 417 label: data.options.sorting[key].expose.label 418 })); 419 } // sortByOptions.push(SelectOption({identifier: key, label: data.options.sorting[key].expose.label})) 420 421 } 422 423 var sortText = Drupal.t("Sort By"); 424 $(".sorting-placeholder", context).html(""); 425 $(".sorting-placeholder", context).append(Select({ 426 identifier: "sort_by", 427 label: Drupal.t("Sort By"), 428 options: sortByOptions.join("") 429 })); 430 $(".sorting-placeholder .form-select", context).on("change", function () { 431 // console.log('sorting change'); 432 $(".search-filters .form-submit", context).trigger("click"); 433 }); // $('.search-filters .filters-placeholder').append( 434 // Select({ 435 // identifier: 'sort_by', 436 // label: 'Sort By', 437 // options: sortByOptions.join(''), 438 // }) 439 // ); 440 // Order (uncomment code below to enable this filter) 441 // identifier: sort_order 442 // label: "Order" 443 // options: 444 // ASC: Asc 445 // DESC: Desc 446 // let sortOrderOptions = [ 447 // { identifier: 'ASC', label: 'Asc' }, 448 // { identifier: 'DESC', label: 'Desc' }, 449 // ].map(SelectOption).join(''); 450 // $('.search-filters .filters-placeholder').append( 451 // Select({ 452 // identifier: 'sort_order', 453 // label: 'Order', 454 // options: sortOrderOptions, 455 // }) 456 // ); 457 // Items per page (uncomment code below to enable this filter) 458 // identifier: items_per_page 459 // boolean: data.paging.options.items_per_page 460 // label: data.paging.options.items_per_page_label 461 // options: data.paging.options.items_per_page_options 462 // boolean: data.paging.options.items_per_page_options_all 463 // all label: data.paging.options.items_per_page_options_all_label 464 // if (data.paging.options.items_per_page) { 465 // let itemsPerPageOptions = data.paging.options.items_per_page_options.split(',').map(item => item.trim()); 466 // $.each(itemsPerPageOptions, function(key, value) { 467 // itemsPerPageOptions.push(SelectOption({identifier: value, label: value})) 468 // }); 469 // if (data.paging.options.items_per_page_options_all) { 470 // itemsPerPageOptions.unshift(SelectOption({identifier: 'All', label: data.paging.options.items_per_page_options_all_label})); 471 // } 472 // $('.search-filters .filters-placeholder').append( 473 // Select({ 474 // identifier: 'items_per_page', 475 // label: data.paging.options.items_per_page_label, 476 // options: itemsPerPageOptions.join(''), 477 // }) 478 // ); 479 // } 480 481 $(".search-content").addClass("filters-loaded"); // } 482 // compare request with filters and highligh selected items 483 484 if (data.request) { 485 // console.log(data.request); 486 $.each(data.request, function (index, element) { 487 // console.log(index, element); 488 var requestOptions = []; 489 490 if (element) { 491 requestOptions = element.split(","); 492 } 493 494 if ($(".search-filters .form-" + index).length > 0) { 495 $(".search-filters .form-" + index + " option").each(function () { 496 var decodedOption = decodeURIComponent($(this).val()).replace(/\+/g, " "); // console.log('decodedOption', decodedOption); 497 // console.log('requestOptions', requestOptions); 498 499 if ($.inArray(decodedOption, requestOptions) !== -1) { 500 $(this).attr("selected", "selected"); 501 } 502 }); 503 } // Sort by. 504 505 506 if (index == "sort_by") { 507 if ($(".sorting-placeholder .form-" + index).length > 0) { 508 $(".sorting-placeholder .form-" + index + " option").each(function () { 509 var decodedOption = decodeURIComponent($(this).val()).replace(/\+/g, " "); // console.log('decodedOption', decodedOption); 510 // console.log('requestOptions', requestOptions); 511 512 if ($.inArray(decodedOption, requestOptions) !== -1) { 513 $(this).attr("selected", "selected"); 514 } 515 }); 516 } 517 } // // place pill (based on request) 518 // let $select = $('.search-filters .form-' + index); 519 // if (index != 'items_per_page' 520 // && index != 'sort_by' 521 // && index != 'sort_order' 522 // && element != 'All' 523 // ) { 524 // // if (Array.isArray(requestOptions)) { 525 // // let text = []; 526 // // $select.find("option:selected").each(function () { 527 // // text.push($(this).text()); 528 // // }); 529 // $.each(requestOptions, function(optionIndex, optionElement) { 530 // $('.filters-pills').append(Pill({ 531 // // TODO: need to find the user friendly name 532 // label: optionElement, 533 // name: index, 534 // value: optionElement, 535 // })); 536 // }); 537 // // } else { 538 // // let text = $select.find("option:selected").text(); 539 // // if (value !== "All") { 540 // // $('.filters-pills').append(Pill({ 541 // // label: text, 542 // // name: index, 543 // // value: element, 544 // // })); 545 // // } 546 // // } 547 // } 548 549 }); 550 } // place pills (getting values from the html) 551 552 553 $(".select-item").each(function () { 554 var $select = $(this).find($("select")); 555 var name = $select.attr("name"); 556 var value = $select.val(); // params.push(name + '=' + value); 557 558 if (name != "items_per_page" && name != "sort_order" && name != "sort_by") { 559 if (Array.isArray(value)) { 560 var text = []; 561 $select.find("option:selected").each(function () { 562 text.push($(this).text()); 563 }); 564 $.each(value, function (index, element) { 565 $(".filters-pills").append(Pill({ 566 label: text[index], 567 name: name, 568 value: element 569 })); 570 }); 571 } else {
571 572 var _text = $select.find("option:selected").text(); 573 574 if (value !== "All") { 575 $(".filters-pills").append(Pill({ 576 label: _text, 577 name: name, 578 value: value 579 })); 580 } 581 } 582 } 583 }); // pills 584 585 $(".pill").on("click", function () { 586 // console.log($(this).attr('data-filter'), $(this).attr('data-value')); 587 var filter = $(this).attr("data-filter"); 588 var value = $(this).attr("data-value"); 589 var params = new URLSearchParams(window.location.search); 590 var currentValue = params.get(filter); 591 var decodedValue = decodeURIComponent(value).replace(/\+/g, " "); // console.log("currentValue", currentValue); 592 // console.log("decodedValue", decodedValue); 593 594 currentValue = currentValue.split(","); 595 var newValue = currentValue.filter(function (elem) { 596 return elem != decodedValue; 597 }); 598 console.log(newValue); 599 600 if (newValue.length > 0) { 601 params.set(filter, newValue); 602 } else { 603 params["delete"](filter); 604 } 605 606 params = params.toString(); 607 params = params.toString().replace(/\%2C/g, ","); 608 console.log("params", params); 609 params = "?" + params; 610 loadSearchResults(SEARCH_URL + params); 611 history.replaceState(params, null, origin + pathname + params); 612 }); // apply bootstrap-select plugin 613 614 if ($("html").attr("lang") == "fr") { 615 $(".search-rest .selectpicker").selectpicker({ 616 lang: "FR" 617 }); 618 } else { 619 $(".search-rest .selectpicker").selectpicker(); 620 } //ADA 2-20-2023 621 // ADA fix for select dropdowns 622 // $('.search-rest .dropdown-toggle', context).off('keyup.activedescendant').on('keyup.activedescendant', function () { 623 // var owns = $(this).attr('aria-owns'); 624 // var dropWrap = $('#'+owns); 625 // var activeItem = dropWrap.find('li.active').find('a'); 626 // var activeId = activeItem.attr('id'); 627 // console.log('active desc:', dropWrap ,activeItem,activeItem.length, activeId); 628 // if(activeItem.length < 1){ 629 // $(this).removeAttr('aria-activedescendant'); 630 // return; 631 // } 632 // $(this).attr('aria-activedescendant', activeId); 633 // }); 634 // bootstrap-select hierarchy (cascade) 635 636 637 $(".search-rest .selectpicker", context).on("changed.bs.select", function (e, clickedIndex, isSelected, previousValue) { 638 //var activeItem = $(this).siblings('.dropdown-menu').find('.active a'); 639 //var activeId = activeItem.attr('id'); 640 // do something... 641 // console.log($(this)); 642 // console.log($(this).val()); 643 // console.log('e', e); 644 // console.log('clickedIndex', clickedIndex); 645 // console.log(e.currentTarget['id']); 646 var $selectId = $("#" + e.currentTarget["id"]); 647 var $optionClicked = $selectId.find("option:eq(" + clickedIndex + ")"); // console.log("data-parent", e.currentTarget[clickedIndex]['attributes']["data-parent"]['value']); 648 // console.log("value", e.currentTarget[clickedIndex]['attributes']["value"]['value']); 649 // console.log('option clicked is ', $optionClicked.attr('value')); 650 // console.log('option parent is ', $optionClicked.attr('data-parent')); 651 // console.log('option clicked is selected: ', $optionClicked.is(':selected')); 652 653 var value = $optionClicked.attr("value"); 654 var parent = $optionClicked.attr("data-parent"); // if level 1 655 656 if (parent == 0) { 657 // console.log('is root'); 658 // if selecting 659 if ($optionClicked.is(":selected")) { 660 $selectId.find('option[data-parent="' + value + '"]').prop("selected", true); 661 $selectId.selectpicker("refresh"); 662 } // if deselecting 663 else { 664 $selectId.find('option[data-parent="' + value + '"]').prop("selected", false); 665 $selectId.selectpicker("refresh"); 666 } 667 } // if level 2 668 else { 669 // console.log('is not root, parent is ', parent); 670 // if selecting 671 if ($optionClicked.is(":selected")) { 672 var allSelected = true; // verify if all are selected and check the parent 673 // console.log($selectId.find('option[data-parent='+parent+']').is(':selected')); 674 // console.log($selectId.find('option[data-parent="'+parent+']"')); 675 676 $selectId.find('option[data-parent="' + parent + '"]').each(function (index, element) { 677 if ($(this).is(":selected") == false) { 678 allSelected = false;
679 } 680 }); // console.log('allSelected', allSelected); 681 682 if (allSelected) { 683 $selectId.find('option[value="' + parent + '"]').prop("selected", true); 684 $selectId.selectpicker("refresh"); 685 } 686 } // if deselecting 687 else { 688 var _allSelected = true; // verify if all are selected and uncheck the parent 689 // console.log($selectId.find('option[data-parent='+parent+']').is(':selected')); 690 // console.log('option[data-parent="'+parent+']'); 691 692 $selectId.find('option[data-parent="' + parent + '"]').each(function (index, element) { 693 if ($(this).is(":selected") == false) { 694 _allSelected = false; 695 } 696 }); // console.log('allSelected', allSelected); 697 698 if (_allSelected == false) { 699 $selectId.find('option[value="' + parent + '"]').prop("selected", false); 700 $selectId.selectpicker("refresh"); 701 } 702 } 703 } // console.log($('#' + selectId).val()); 704 // $('#'+ selectId + ' option').each(function(index, element) { 705 // console.log(index, element); 706 // }); 707 708 }); 709 710 function fixOptionsText(target) { 711 $(target).find(".dropdown-item .text").each(function () { 712 if ($(this).html().indexOf("- ") > -1) { 713 $(this).addClass("d-flex"); 714 $(this).html($(this).html().replace("- ", '<span aria-hidden="true">- </span>')); 715 } 716 }); 717 } 718 719 $(".search-rest .filters-placeholder .selectpicker", context).on("show.bs.select", function (e, clickedIndex, isSelected, previousValue) { 720 $(".search-content-wrapper").addClass("overlay_filter"); 721 $(".search-results-wrapper").addClass("overlay_filter"); 722 fixOptionsText(e.target.offsetParent); 723 }); 724 $(".search-rest .filters-placeholder .selectpicker", context).on("refreshed.bs.select", function (e, clickedIndex, isSelected, previousValue) { 725 fixOptionsText(e.target.offsetParent); 726 }); 727 $(".search-rest .sorting-placeholder .selectpicker", context).on("show.bs.select", function (e, clickedIndex, isSelected, previousValue) { 728 $(".search-content-wrapper").addClass("overlay_filter"); 729 }); 730 $(".search-rest .selectpicker", context).on("hide.bs.select", function (e, clickedIndex, isSelected, previousValue) { 731 $(".search-content-wrapper").removeClass("overlay_filter"); 732 $(".search-results-wrapper").removeClass("overlay_filter"); 733 }); // load content 734 735 if (data.data.length > 0) { 736 $(".search-empty").html(""); 737 $(".results-placeholder").html(data.paging.rows_total + " " + Drupal.t("results")); 738 $.each(data.data, function (index, element) { 739 // console.log('element', element); 740 var rendered_entity = element.rendered_entity; 741 $(".search-content").append( // '<div class="search__col" role="group" aria-label="product">' + 742 // rendered_entity + 743 // "</div>" 744 '<div class="search__col" role="group" aria-label="item">' + rendered_entity + "</div>"); 745 $(".search-rest .search-content .recipe-featured__card img").removeAttr("alt").attr("alt", ""); 746 }); //ADA 2-20-2023 747 //focus the first item of the current page. skip for first page. 748 749 if (data.paging.page_current > 0) { 750 $(".search__col").eq(data.paging.page_current * data.paging.rows_per_page).find("a").focus(); 751 } 752 } else { 753 if (data.empty) { 754 $(".search-empty").html(data.empty.value); 755 $(".results-placeholder").html(""); 756 } 757 } // pagination 758 // console.log('data.paging.page_current', data.paging.page_current); 759 760 761 var nextPage = data.paging.page_current + 1; // console.log('nextPage', nextPage) 762 763 if (nextPage < data.paging.page_total) { 764 // Bind button click function with new url 765 $(".view-more").show(); 766 $(".view-more").html(data.paging.tags.next); 767 $(".view-more").off("click").on("click", function (e) { 768 e.preventDefault(); 769 var params = "?page=" + nextPage; 770 var searchParams = new URLSearchParams(window.location.search); 771 searchParams.set("page", nextPage); 772 searchParams = searchParams.toString(); 773 searchParams = "?" + searchParams; // console.log(searchParams); 774 // if (searchParams) { 775 // params = '?' + searchParams + '&page=' + nextPage; 776 // } 777 778 loadSearchResults(SEARCH_URL + searchParams, true); // history.replaceState(null, null, origin + pathname + searchParams); 779 }); 780 } else { 781 // Hide view more button. 782 $(".view-more").hide(); 783 } 784 } 785 }); 786 } // $('.search-filters .form-select', context).on('change', function() { 787 // console.log('filter change'); 788 // }); 789 790 791 $(".search-filters .form-submit", context).on("click", function () { 792 // console.log('filter submit'); 793 // build search url parameters 794 var params = []; 795 $(".select-item").each(function () { 796 var $select = $(this).find($("select")); 797 var name = $select.attr("name"); 798 var value = $select.val(); 799 params.push(name + "=" + value); // // place pill 800 // if (name != 'items_per_page') { 801 // if (Array.isArray(value)) { 802 // let text = []; 803 // $select.find("option:selected").each(function () { 804 // text.push($(this).text()); 805 // }); 806 // $.each(value, function(index, element) { 807 // $('.filters-pills').append(Pill({ 808 // label: text[index], 809 // name: name, 810 // value: element, 811 // })); 812 // }); 813 // } else { 814 // let text = $select.find("option:selected").text(); 815 // if (value !== "All") { 816 // $('.filters-pills').append(Pill({ 817 // label: text, 818 // name: name, 819 // value: value, 820 // })); 821 // } 822 // } 823 // } 824 }); 825 826 if (params) { 827 params = params.join("&"); 828 params = "?" + params; 829 loadSearchResults(SEARCH_URL + params); 830 history.replaceState(params, null, origin + pathname + params); 831 } else { 832 loadSearchResults(SEARCH_URL); 833 history.replaceState(null, null, origin + pathname); 834 } 835 }); // Reset 836 837 $(".search-filters .form-reset", context).on("click", function () { 838 loadSearchResults(SEARCH_URL); 839 history.replaceState(null, null, origin + pathname); 840 }); // urls 841 // window.addEventListener('popstate', function(e) { 842 843 window.onpopstate = function (e) { 844 console.log("e", e); 845 846 if (e.state) { 847 console.log("e.state", e.state); 848 loadSearchResults(SEARCH_URL + e.state); 849 } else { 850 loadSearchResults(SEARCH_URL); 851 } 852 }; // }); 853 // mobile filters 854 // btn show filters 855 856 857 $(".btn-filters", context).on("click", function () { 858 $(".search-filters .filters-wrapper").addClass("show-filters"); 859 $("body").addClass("modal-open"); 860 }); // close filters 861 862 $(".search-filters .filters-close").on("click", function (e) { 863 $(".search-filters .filters-wrapper").removeClass("show-filters"); 864 $("body").removeClass("modal-open"); 865 }); 866 867 function initSearch() { 868 $(".search-content", context).each(function () { 869 var searchParams = new URLSearchParams(window.location.search); 870 searchParams = searchParams.toString(); 871 872 if (searchParams) { 873 // console.log('has searchParams') 874 searchParams = "?" + searchParams; 875 } 876 877 loadSearchResults(SEARCH_URL + searchParams); 878 }); 879 } 880 881 initSearch(); 882 } 883 }; 884})(jQuery, Drupal); 885 886/***/ }), 887 888/***/ 17: 889/*!*********************************************************!*\ 890 !*** multi ./src/components/search-rest/search-rest.js ***! 891 \*********************************************************/ 892/*! no static exports found */ 893/***/ (function(module, exports, __webpack_require__) { 894 895module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/search-rest/search-rest.js */"./src/components/search-rest/search-rest.js"); 896 897 898/***/ }) 899 900/******/ });; 901(function ($) { 902 903 var $stickyFilter = $(".sticky-filter");
904 var subNavPosition = $stickyFilter.offset().top; 905 906 var $mainNav = $("#navbar"); 907 var initHeaderHeight = $mainNav.outerHeight(); 908 909 var isToolbarFixed = $('body').hasClass('toolbar-fixed'); 910 911 // if ($stickyFilter.is(':visible')){ 912 $stickyFilter.css("top", initHeaderHeight+"px"); 913 // } 914 915 $( window ).resize(function() { 916 subNavPosition = $stickyFilter.offset().top; 917 initHeaderHeight = $mainNav.outerHeight(); 918 $stickyFilter.css("top", initHeaderHeight+"px"); 919 }); 920 921 922 function snapMenus() { 923 var scrollTop = $(document).scrollTop() + initHeaderHeight; 924 var subNavHeight = $stickyFilter.outerHeight(true); 925 926 927 if (scrollTop >= subNavPosition && $stickyFilter.is(':visible') ) { 928 $stickyFilter.addClass("sticky"); 929 $stickyFilter.parent().css("margin-top", subNavHeight+"px"); 930 931 if (scrollTop >= subNavPosition + initHeaderHeight){ 932 $stickyFilter.addClass("pushed-up"); 933 $mainNav.addClass("pushed-up"); 934 } else { 935 $stickyFilter.removeClass("pushed-up"); 936 } 937 938 } else { 939 $mainNav.removeClass("pushed-up"); 940 $stickyFilter.removeClass("sticky"); 941 $stickyFilter.parent().css("margin-top",0); 942 } 943 } 944 945 window.addEventListener('scroll', function(e){ 946 if (!isToolbarFixed) { 947 //run on scroll 948 snapMenus(); 949 } 950 }); 951 952 //run on load 953 if (!isToolbarFixed) { 954 snapMenus(); 955 } 956 957 958})(jQuery);; 959/*! 960 * Bootstrap-select v1.14.0-beta3 (https://developer.snapappointments.com/bootstrap-select) 961 * 962 * Copyright 2012-2023 SnapAppointments, LLC 963 * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) 964 */ 965 966(function (root, factory) { 967 if (root === undefined && window !== undefined) root = window; 968 if (typeof define === 'function' && define.amd) { 969 // AMD. Register as an anonymous module unless amdModuleId is set 970 define(["jquery"], function (a0) { 971 return (factory(a0)); 972 }); 973 } else if (typeof module === 'object' && module.exports) { 974 // Node. Does not work with strict CommonJS, but 975 // only CommonJS-like environments that support module.exports, 976 // like Node. 977 module.exports = factory(require("jquery")); 978 } else { 979 factory(root["jQuery"]); 980 } 981}(this, function (jQuery) { 982 983(function ($) { 984 'use strict'; 985 986 var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; 987 988 var uriAttrs = [ 989 'background', 990 'cite', 991 'href', 992 'itemtype', 993 'longdesc', 994 'poster', 995 'src', 996 'xlink:href' 997 ]; 998 999 var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 1000 1001 var DefaultWhitelist = { 1002 // Global attributes allowed on any supplied element below. 1003 '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN], 1004 a: ['target', 'href', 'title', 'rel'], 1005 area: [], 1006 b: [], 1007 br: [], 1008 col: [], 1009 code: [], 1010 div: [], 1011 em: [], 1012 hr: [], 1013 h1: [], 1014 h2: [], 1015 h3: [], 1016 h4: [], 1017 h5: [], 1018 h6: [], 1019 i: [], 1020 img: ['src', 'alt', 'title', 'width', 'height'], 1021 li: [], 1022 ol: [], 1023 p: [], 1024 pre: [], 1025 s: [], 1026 small: [], 1027 span: [], 1028 sub: [], 1029 sup: [], 1030 strong: [], 1031 u: [], 1032 ul: [] 1033 }; 1034 1035 /** 1036 * A pattern that recognizes a commonly useful subset of URLs that are safe. 1037 * 1038 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts 1039 */ 1040 var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; 1041 1042 /** 1043 * A pattern that matches safe data URLs. Only matches image, video and audio types. 1044 * 1045 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts 1046 */ 1047 var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; 1048 1049 var ParseableAttributes = ['title', 'placeholder']; // attributes to use as settings, can add others in the future 1050 1051 function allowedAttribute (attr, allowedAttributeList) { 1052 var attrName = attr.nodeName.toLowerCase(); 1053 1054 if ($.inArray(attrName, allowedAttributeList) !== -1) { 1055 if ($.inArray(attrName, uriAttrs) !== -1) { 1056 return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); 1057 } 1058 1059 return true; 1060 } 1061 1062 var regExp = $(allowedAttributeList).filter(function (index, value) { 1063 return value instanceof RegExp; 1064 }); 1065 1066 // Check if a regular expression validates the attribute. 1067 for (var i = 0, l = regExp.length; i < l; i++) { 1068 if (attrName.match(regExp[i])) { 1069 return true; 1070 } 1071 } 1072 1073 return false;
1074 } 1075 1076 function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) { 1077 if (sanitizeFn && typeof sanitizeFn === 'function') { 1078 return sanitizeFn(unsafeElements); 1079 } 1080 1081 var whitelistKeys = Object.keys(whiteList); 1082 1083 for (var i = 0, len = unsafeElements.length; i < len; i++) { 1084 var elements = unsafeElements[i].querySelectorAll('*'); 1085 1086 for (var j = 0, len2 = elements.length; j < len2; j++) { 1087 var el = elements[j]; 1088 var elName = el.nodeName.toLowerCase(); 1089 1090 if (whitelistKeys.indexOf(elName) === -1) { 1091 el.parentNode.removeChild(el); 1092 1093 continue; 1094 } 1095 1096 var attributeList = [].slice.call(el.attributes); 1097 var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); 1098 1099 for (var k = 0, len3 = attributeList.length; k < len3; k++) { 1100 var attr = attributeList[k]; 1101 1102 if (!allowedAttribute(attr, whitelistedAttributes)) { 1103 el.removeAttribute(attr.nodeName); 1104 } 1105 } 1106 } 1107 } 1108 } 1109 1110 // function srSpeak(text, priority) { 1111 // var el = document.createElement("div"); 1112 // var id = "speak-" + Date.now(); 1113 // el.setAttribute("id", id); 1114 // el.setAttribute("aria-live", priority || "polite"); 1115 // el.classList.add("visually-hidden"); 1116 // document.body.appendChild(el); 1117 1118 // window.setTimeout(function () { 1119 // document.getElementById(id).innerHTML = text; 1120 // }, 100); 1121 1122 // window.setTimeout(function () { 1123 // document.body.removeChild(document.getElementById(id)); 1124 // }, 1000); 1125 // } 1126 1127 function getAttributesObject ($select) { 1128 var attributesObject = {}, 1129 attrVal; 1130 1131 ParseableAttributes.forEach(function (item) { 1132 attrVal = $select.attr(item); 1133 if (attrVal) attributesObject[item] = attrVal; 1134 }); 1135 1136 // for backwards compatibility 1137 // (using title as placeholder is deprecated - remove in v2.0.0) 1138 if (!attributesObject.placeholder && attributesObject.title) { 1139 attributesObject.placeholder = attributesObject.title; 1140 } 1141 1142 return attributesObject; 1143 } 1144 1145 // Polyfill for browsers with no classList support 1146 // Remove in v2 1147 if (!('classList' in document.createElement('_'))) { 1148 (function (view) { 1149 if (!('Element' in view)) return; 1150 1151 var classListProp = 'classList', 1152 protoProp = 'prototype', 1153 elemCtrProto = view.Element[protoProp], 1154 objCtr = Object, 1155 classListGetter = function () { 1156 var $elem = $(this); 1157 1158 return { 1159 add: function (classes) { 1160 classes = Array.prototype.slice.call(arguments).join(' ');
1161 return $elem.addClass(classes); 1162 }, 1163 remove: function (classes) { 1164 classes = Array.prototype.slice.call(arguments).join(' '); 1165 return $elem.removeClass(classes); 1166 }, 1167 toggle: function (classes, force) { 1168 return $elem.toggleClass(classes, force); 1169 }, 1170 contains: function (classes) { 1171 return $elem.hasClass(classes); 1172 } 1173 }; 1174 }; 1175 1176 if (objCtr.defineProperty) { 1177 var classListPropDesc = { 1178 get: classListGetter, 1179 enumerable: true, 1180 configurable: true 1181 }; 1182 try { 1183 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 1184 } catch (ex) { // IE 8 doesn't support enumerable:true 1185 // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36 1186 // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected 1187 if (ex.number === undefined || ex.number === -0x7FF5EC54) { 1188 classListPropDesc.enumerable = false; 1189 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 1190 } 1191 } 1192 } else if (objCtr[protoProp].__defineGetter__) { 1193 elemCtrProto.__defineGetter__(classListProp, classListGetter); 1194 } 1195 }(window)); 1196 } 1197 1198 var testElement = document.createElement('_'); 1199 1200 testElement.classList.add('c1', 'c2'); 1201 1202 if (!testElement.classList.contains('c2')) { 1203 var _add = DOMTokenList.prototype.add, 1204 _remove = DOMTokenList.prototype.remove; 1205 1206 DOMTokenList.prototype.add = function () { 1207 Array.prototype.forEach.call(arguments, _add.bind(this)); 1208 }; 1209 1210 DOMTokenList.prototype.remove = function () { 1211 Array.prototype.forEach.call(arguments, _remove.bind(this)); 1212 }; 1213 } 1214 1215 testElement.classList.toggle('c3', false); 1216 1217 // Polyfill for IE 10 and Firefox <24, where classList.toggle does not 1218 // support the second argument. 1219 if (testElement.classList.contains('c3')) { 1220 var _toggle = DOMTokenList.prototype.toggle; 1221 1222 DOMTokenList.prototype.toggle = function (token, force) { 1223 if (1 in arguments && !this.contains(token) === !force) { 1224 return force; 1225 } else { 1226 return _toggle.call(this, token); 1227 } 1228 }; 1229 } 1230 1231 testElement = null; 1232 1233 // Polyfill for IE (remove in v2) 1234 Object.values = typeof Object.values === 'function' ? Object.values : function (obj) { 1235 return Object.keys(obj).map(function (key) { 1236 return obj[key]; 1237 }); 1238 }; 1239 1240 // shallow array comparison 1241 function isEqual (array1, array2) { 1242 return array1.length === array2.length && array1.every(function (element, index) { 1243 return element === array2[index]; 1244 }); 1245 }; 1246 1247 // <editor-fold desc="Shims"> 1248 if (!String.prototype.startsWith) { 1249 (function () { 1250 'use strict'; // needed to support `apply`/`call` with `undefined`/`null` 1251 var toString = {}.toString; 1252 var startsWith = function (search) { 1253 if (this == null) { 1254 throw new TypeError(); 1255 } 1256 var string = String(this); 1257 if (search && toString.call(search) == '[object RegExp]') { 1258 throw new TypeError(); 1259 } 1260 var stringLength = string.length; 1261 var searchString = String(search); 1262 var searchLength = searchString.length; 1263 var position = arguments.length > 1 ? arguments[1] : undefined; 1264 // `ToInteger` 1265 var pos = position ? Number(position) : 0; 1266 if (pos != pos) { // better `isNaN` 1267 pos = 0; 1268 } 1269 var start = Math.min(Math.max(pos, 0), stringLength); 1270 // Avoid the `indexOf` call if no match is possible 1271 if (searchLength + start > stringLength) { 1272 return false; 1273 } 1274 var index = -1; 1275 while (++index < searchLength) { 1276 if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) { 1277 return false; 1278 } 1279 } 1280 return true; 1281 }; 1282 if (Object.defineProperty) { 1283 Object.defineProperty(String.prototype, 'startsWith', { 1284 'value': startsWith, 1285 'configurable': true, 1286 'writable': true 1287 }); 1288 } else { 1289 String.prototype.startsWith = startsWith; 1290 } 1291 }()); 1292 } 1293 1294 function toKebabCase (str) { 1295 return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) { 1296 return (ofs ? '-' : '') + $.toLowerCase(); 1297 }); 1298 } 1299 1300 function getSelectedOptions () { 1301 var options = this.selectpicker.main.data; 1302 1303 if (this.options.source.data || this.options.source.search) { 1304 options = Object.values(this.selectpicker.optionValuesDataMap); 1305 } 1306 1307 var selectedOptions = options.filter(function (item) { 1308 if (item.selected) { 1309 if (this.options.hideDisabled && item.disabled) return false;
1310 return true; 1311 } 1312 1313 return false; 1314 }, this); 1315 1316 // ensure only 1 option is selected if multiple are set in the data source 1317 if (this.options.source.data && !this.multiple && selectedOptions.length > 1) { 1318 for (var i = 0; i < selectedOptions.length - 1; i++) { 1319 selectedOptions[i].selected = false; 1320 } 1321 1322 selectedOptions = [ selectedOptions[selectedOptions.length - 1] ]; 1323 } 1324 1325 return selectedOptions; 1326 } 1327 1328 // much faster than $.val() 1329 function getSelectValues (selectedOptions) { 1330 var value = [], 1331 options = selectedOptions || getSelectedOptions.call(this), 1332 opt; 1333 1334 for (var i = 0, len = options.length; i < len; i++) { 1335 opt = options[i]; 1336 1337 if (!opt.disabled) { 1338 value.push(opt.value === undefined ? opt.text : opt.value); 1339 } 1340 } 1341 1342 if (!this.multiple) { 1343 return !value.length ? null : value[0]; 1344 } 1345 1346 return value; 1347 } 1348 1349 // set data-selected on select element if the value has been programmatically selected 1350 // prior to initialization of bootstrap-select 1351 // * consider removing or replacing an alternative method * 1352 var valHooks = { 1353 useDefault: false, 1354 _set: $.valHooks.select.set 1355 }; 1356 1357 $.valHooks.select.set = function (elem, value) { 1358 if (value && !valHooks.useDefault) $(elem).data('selected', true); 1359 1360 return valHooks._set.apply(this, arguments); 1361 }; 1362 1363 var changedArguments = null; 1364 1365 var EventIsSupported = (function () { 1366 try { 1367 new Event('change'); 1368 return true; 1369 } catch (e) { 1370 return false; 1371 } 1372 })(); 1373 1374 $.fn.triggerNative = function (eventName) { 1375 var el = this[0], 1376 event; 1377 1378 if (el.dispatchEvent) { // for modern browsers & IE9+ 1379 if (EventIsSupported) { 1380 // For modern browsers 1381 event = new Event(eventName, { 1382 bubbles: true 1383 }); 1384 } else { 1385 // For IE since it doesn't support Event constructor 1386 event = document.createEvent('Event'); 1387 event.initEvent(eventName, true, false); 1388 } 1389 1390 el.dispatchEvent(event); 1391 } 1392 }; 1393 // </editor-fold> 1394 1395 function stringSearch (li, searchString, method, normalize) { 1396 var stringTypes = [ 1397 'display', 1398 'subtext', 1399 'tokens' 1400 ], 1401 searchSuccess = false; 1402 1403 for (var i = 0; i < stringTypes.length; i++) { 1404 var stringType = stringTypes[i], 1405 string = li[stringType]; 1406 1407 if (string) { 1408 string = string.toString(); 1409 1410 // Strip HTML tags. This isn't perfect, but it's much faster than any other method 1411 if (stringType === 'display') { 1412 string = string.replace(/<[^>]+>/g, ''); 1413 } 1414 1415 if (normalize) string = normalizeToBase(string); 1416 string = string.toUpperCase(); 1417 1418 if (typeof method === 'function') { 1419 searchSuccess = method(string, searchString); 1420 } else if (method === 'contains') { 1421 searchSuccess = string.indexOf(searchString) >= 0; 1422 } else if (method === 'containsAll') { 1423 var searchArray = searchString.split(' '); 1424 var notAllMatched = false; 1425 searchSuccess = false; 1426 1427 for (var searchSubString in searchArray) { 1428 searchSuccess = string.indexOf(searchArray[searchSubString]) >= 0; 1429 if (!searchSuccess) notAllMatched = true; 1430 } 1431 1432 if (notAllMatched) searchSuccess = false; 1433 } else { 1434 searchSuccess = string.startsWith(searchString); 1435 } 1436 1437 if (searchSuccess) break; 1438 } 1439 } 1440 1441 return searchSuccess; 1442 } 1443 1444 function toInteger (value) { 1445 return parseInt(value, 10) || 0; 1446 } 1447 1448 // Borrowed from Lodash (_.deburr) 1449 /** Used to map Latin Unicode letters to basic Latin letters. */ 1450 var deburredLetters = { 1451 // Latin-1 Supplement block. 1452 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', 1453 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', 1454 '\xc7': 'C', '\xe7': 'c', 1455 '\xd0': 'D', '\xf0': 'd', 1456 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', 1457 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', 1458 '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', 1459 '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', 1460 '\xd1': 'N', '\xf1': 'n', 1461 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', 1462 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', 1463 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', 1464 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', 1465 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', 1466 '\xc6': 'Ae', '\xe6': 'ae', 1467 '\xde': 'Th', '\xfe': 'th', 1468 '\xdf': 'ss', 1469 // Latin Extended-A block. 1470 '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', 1471 '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', 1472 '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', 1473 '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', 1474 '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', 1475 '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', 1476 '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', 1477 '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', 1478 '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', 1479 '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', 1480 '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', 1481 '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', 1482 '\u0134': 'J', '\u0135': 'j', 1483 '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', 1484 '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', 1485 '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', 1486 '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', 1487 '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', 1488 '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
1489 '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', 1490 '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', 1491 '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', 1492 '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', 1493 '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', 1494 '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', 1495 '\u0163': 't', '\u0165': 't', '\u0167': 't', 1496 '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', 1497 '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', 1498 '\u0174': 'W', '\u0175': 'w', 1499 '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', 1500 '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', 1501 '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', 1502 '\u0132': 'IJ', '\u0133': 'ij', 1503 '\u0152': 'Oe', '\u0153': 'oe', 1504 '\u0149': "'n", '\u017f': 's' 1505 }; 1506 1507 /** Used to match Latin Unicode letters (excluding mathematical operators). */ 1508 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; 1509 1510 /** Used to compose unicode character classes. */ 1511 var rsComboMarksRange = '\\u0300-\\u036f', 1512 reComboHalfMarksRange = '\\ufe20-\\ufe2f', 1513 rsComboSymbolsRange = '\\u20d0-\\u20ff', 1514 rsComboMarksExtendedRange = '\\u1ab0-\\u1aff', 1515 rsComboMarksSupplementRange = '\\u1dc0-\\u1dff', 1516 rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange; 1517 1518 /** Used to compose unicode capture groups. */ 1519 var rsCombo = '[' + rsComboRange + ']'; 1520 1521 /** 1522 * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and 1523 * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). 1524 */ 1525 var reComboMark = RegExp(rsCombo, 'g'); 1526 1527 function deburrLetter (key) { 1528 return deburredLetters[key]; 1529 }; 1530 1531 function normalizeToBase (string) { 1532 string = string.toString(); 1533 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); 1534 } 1535 1536 // List of HTML entities for escaping. 1537 var escapeMap = { 1538 '&': '&', 1539 '<': '<', 1540 '>': '>', 1541 '"': '"', 1542 "'": ''', 1543 '`': '`' 1544 }; 1545 1546 // Functions for escaping and unescaping strings to/from HTML interpolation. 1547 var createEscaper = function (map) { 1548 var escaper = function (match) { 1549 return map[match]; 1550 }; 1551 // Regexes for identifying a key that needs to be escaped. 1552 var source = '(?:' + Object.keys(map).join('|') + ')'; 1553 var testRegexp = RegExp(source); 1554 var replaceRegexp = RegExp(source, 'g'); 1555 return function (string) { 1556 string = string == null ? '' : '' + string; 1557 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 1558 }; 1559 }; 1560 1561 var htmlEscape = createEscaper(escapeMap); 1562 1563 /** 1564 * ------------------------------------------------------------------------ 1565 * Constants 1566 * ------------------------------------------------------------------------ 1567 */ 1568 1569 var keyCodeMap = { 1570 32: ' ', 1571 48: '0', 1572 49: '1', 1573 50: '2', 1574 51: '3', 1575 52: '4', 1576 53: '5', 1577 54: '6', 1578 55: '7', 1579 56: '8', 1580 57: '9', 1581 59: ';', 1582 65: 'A', 1583 66: 'B', 1584 67: 'C', 1585 68: 'D', 1586 69: 'E', 1587 70: 'F', 1588 71: 'G', 1589 72: 'H', 1590 73: 'I', 1591 74: 'J', 1592 75: 'K', 1593 76: 'L', 1594 77: 'M', 1595 78: 'N', 1596 79: 'O', 1597 80: 'P', 1598 81: 'Q', 1599 82: 'R', 1600 83: 'S', 1601 84: 'T', 1602 85: 'U', 1603 86: 'V', 1604 87: 'W', 1605 88: 'X', 1606 89: 'Y', 1607 90: 'Z', 1608 96: '0', 1609 97: '1', 1610 98: '2', 1611 99: '3', 1612 100: '4', 1613 101: '5', 1614 102: '6', 1615 103: '7', 1616 104: '8', 1617 105: '9' 1618 }; 1619 1620 var keyCodes = { 1621 ESCAPE: 27, // KeyboardEvent.which value for Escape (Esc) key 1622 ENTER: 13, // KeyboardEvent.which value for Enter key 1623 SPACE: 32, // KeyboardEvent.which value for space key 1624 TAB: 9, // KeyboardEvent.which value for tab key 1625 ARROW_UP: 38, // KeyboardEvent.which value for up arrow key 1626 ARROW_DOWN: 40 // KeyboardEvent.which value for down arrow key 1627 }; 1628 1629 var Dropdown = window.Dropdown || window.bootstrap && window.bootstrap.Dropdown; 1630 1631 function getVersion () { 1632 var version; 1633 1634 try { 1635 version = $.fn.dropdown.Constructor.VERSION; 1636 } catch (err) { 1637 version = Dropdown.VERSION; 1638 } 1639 1640 return version; 1641 } 1642 1643 var version = { 1644 success: false, 1645 major: '3' 1646 }; 1647 1648 try { 1649 version.full = (getVersion() || '').split(' ')[0].split('.'); 1650 version.major = version.full[0]; 1651 version.success = true; 1652 } catch (err) { 1653 // do nothing 1654 } 1655 1656 var selectId = 0; 1657 1658 var EVENT_KEY = '.bs.select'; 1659 1660 var classNames = { 1661 DISABLED: 'disabled',
1662 DIVIDER: 'divider', 1663 SHOW: 'open', 1664 DROPUP: 'dropup', 1665 MENU: 'dropdown-menu', 1666 MENURIGHT: 'dropdown-menu-right', 1667 MENULEFT: 'dropdown-menu-left', 1668 // to-do: replace with more advanced template/customization options 1669 BUTTONCLASS: 'btn-default', 1670 POPOVERHEADER: 'popover-title', 1671 ICONBASE: 'glyphicon', 1672 TICKICON: 'glyphicon-ok' 1673 }; 1674 1675 var Selector = { 1676 MENU: '.' + classNames.MENU, 1677 DATA_TOGGLE: 'data-toggle="dropdown"' 1678 }; 1679 1680 var elementTemplates = { 1681 div: document.createElement('div'), 1682 span: document.createElement('span'), 1683 i: document.createElement('i'), 1684 subtext: document.createElement('small'), 1685 // TODO remove <a> 1686 a: document.createElement('span'), 1687 li: document.createElement('li'), 1688 whitespace: document.createTextNode('\u00A0'), 1689 fragment: document.createDocumentFragment(), 1690 option: document.createElement('option'), 1691 group: document.createElement('li'), 1692 listbox: document.createElement('ul'), 1693 groupNotice: document.createElement('span') 1694 }; 1695 1696 var hiddenContent = " group. Selecting this option will toggle all items in this group."; 1697 elementTemplates.groupNotice.className = 'sr-only'; 1698 elementTemplates.groupNotice.innerText = hiddenContent; 1699 1700 1701 1702 elementTemplates.selectedOption = elementTemplates.option.cloneNode(false); 1703 elementTemplates.selectedOption.setAttribute('selected', true); 1704 1705 elementTemplates.noResults = elementTemplates.li.cloneNode(false); 1706 elementTemplates.noResults.className = 'no-results'; 1707 1708 elementTemplates.li.setAttribute('role', 'option'); 1709 // elementTemplates.li.className = 'dropdown-item'; 1710 1711 // TODO remove <a> 1712 // elementTemplates.a.setAttribute('role', 'option'); 1713 elementTemplates.a.className = 'dropdown-item'; 1714 1715 elementTemplates.subtext.className = 'text-muted'; 1716 1717 elementTemplates.text = elementTemplates.span.cloneNode(false); 1718 elementTemplates.text.className = 'text'; 1719 1720 elementTemplates.group.className = 'group'; 1721 elementTemplates.group.setAttribute('role', 'group'); 1722 1723 elementTemplates.listbox.className = 'group-options list-unstyled'; 1724 elementTemplates.listbox.setAttribute('role', 'listbox'); 1725 1726 elementTemplates.checkMark = elementTemplates.span.cloneNode(false); 1727 1728 var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN); 1729 var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE); 1730 1731 var generateOption = { 1732 1733 li: function (content, classes, optgroup) { 1734 var li = elementTemplates.li.cloneNode(false); 1735 if (content) { 1736 if (content.nodeType === 1 || content.nodeType === 11) { 1737 li.appendChild(content); 1738 } else { 1739 li.innerHTML = content; 1740 } 1741 } 1742 1743 if (typeof classes !== 'undefined' && classes !== '') li.className = classes; 1744 if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup); 1745 1746 return li; 1747 }, 1748 1749 a: function (text, classes, inline) { 1750 var a = elementTemplates.a.cloneNode(true); 1751 if (text) { 1752 if (text.nodeType === 11) { 1753 a.appendChild(text); 1754 } else { 1755 a.insertAdjacentHTML('beforeend', text); 1756 } 1757 } 1758 if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/)); 1759 if (inline) a.setAttribute('style', inline); 1760 1761 return a; 1762 }, 1763 1764 text: function (options, useFragment) { 1765 var textElement = elementTemplates.text.cloneNode(false), 1766 subtextElement, 1767 iconElement; 1768 1769 if (options.content) { 1770 textElement.innerHTML = options.content; 1771 } else { 1772 textElement.textContent = options.text; 1773 1774 if (options.icon) { 1775 var whitespace = elementTemplates.whitespace.cloneNode(false); 1776 1777 // need to use <i> for icons in the button to prevent a breaking change 1778 // note: switch to span in next major release 1779 iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false); 1780 iconElement.className = this.options.iconBase + ' ' + options.icon; 1781 1782 elementTemplates.fragment.appendChild(iconElement); 1783 elementTemplates.fragment.appendChild(whitespace); 1784 } 1785 1786 if (options.subtext) { 1787 subtextElement = elementTemplates.subtext.cloneNode(false); 1788 subtextElement.textContent = options.subtext; 1789 textElement.appendChild(subtextElement); 1790 } 1791 } 1792 1793 if (useFragment === true) { 1794 while (textElement.childNodes.length > 0) { 1795 elementTemplates.fragment.appendChild(textElement.childNodes[0]); 1796 } 1797 } else { 1798 elementTemplates.fragment.appendChild(textElement); 1799 } 1800 1801 return elementTemplates.fragment; 1802 }, 1803 1804 label: function (options) { 1805 // generate a option group label 1806 // TODO remove 1807 var textElement = elementTemplates.text.cloneNode(false), 1808 subtextElement, 1809 iconElement; 1810 1811 textElement.innerHTML = options.display; 1812 1813 if (options.icon) { 1814 var whitespace = elementTemplates.whitespace.cloneNode(false); 1815 1816 iconElement = elementTemplates.span.cloneNode(false); 1817 iconElement.className = this.options.iconBase + ' ' + options.icon; 1818 1819 elementTemplates.fragment.appendChild(iconElement); 1820 elementTemplates.fragment.appendChild(whitespace); 1821 } 1822 1823 if (options.subtext) { 1824 subtextElement = elementTemplates.subtext.cloneNode(false); 1825 subtextElement.textContent = options.subtext; 1826 textElement.appendChild(subtextElement); 1827 } 1828 1829 elementTemplates.fragment.appendChild(textElement); 1830 1831 return elementTemplates.fragment; 1832 } 1833 }; 1834 1835 var getOptionData = { 1836 fromOption: function (option, type) { 1837 var value; 1838 1839 switch (type) {
1840 case 'divider': 1841 value = option.getAttribute('data-divider') === 'true'; 1842 break; 1843 1844 case 'text': 1845 value = option.textContent; 1846 break; 1847 1848 case 'label': 1849 value = option.label; 1850 break; 1851 1852 case 'style': 1853 value = option.style.cssText; 1854 break; 1855 1856 case 'title': 1857 value = option.title; 1858 break; 1859 1860 default: 1861 value = option.getAttribute('data-' + toKebabCase(type)); 1862 break; 1863 } 1864 1865 return value; 1866 }, 1867 fromDataSource: function (option, type) { 1868 var value; 1869 1870 switch (type) { 1871 case 'text': 1872 case 'label': 1873 value = option.text || option.value || ''; 1874 break; 1875 1876 default: 1877 value = option[type]; 1878 break; 1879 } 1880 1881 return value; 1882 } 1883 }; 1884 1885 function showNoResults (searchMatch, searchValue) { 1886 if (!searchMatch.length) { 1887 elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"'); 1888 this.$menuInner[0].firstChild.appendChild(elementTemplates.noResults); 1889 } 1890 } 1891 1892 function filterHidden (item) { 1893 return !(item.hidden || this.options.hideDisabled && item.disabled); 1894 } 1895 1896 var Selectpicker = function (element, options) { 1897 var that = this; 1898 1899 // bootstrap-select has been initialized - revert valHooks.select.set back to its original function 1900 if (!valHooks.useDefault) { 1901 $.valHooks.select.set = valHooks._set; 1902 valHooks.useDefault = true; 1903 } 1904 1905 this.$element = $(element); 1906 this.$newElement = null; 1907 this.$button = null; 1908 this.$menu = null; 1909 this.options = options; 1910 this.selectpicker = { 1911 main: { 1912 data: [], 1913 optionQueue: elementTemplates.fragment.cloneNode(false), 1914 hasMore: false 1915 }, 1916 search: { 1917 data: [], 1918 hasMore: false 1919 }, 1920 current: {}, // current is either equal to main or search depending on if a search is in progress 1921 view: {}, 1922 // map of option values and their respective data (only used in conjunction with options.source) 1923 optionValuesDataMap: {}, 1924 isSearching: false, 1925 keydown: { 1926 keyHistory: '', 1927 resetKeyHistory: { 1928 start: function () { 1929 return setTimeout(function () { 1930 that.selectpicker.keydown.keyHistory = ''; 1931 }, 800); 1932 } 1933 } 1934 } 1935 }; 1936 1937 this.sizeInfo = {}; 1938 1939 // Format window padding 1940 var winPad = this.options.windowPadding; 1941 if (typeof winPad === 'number') { 1942 this.options.windowPadding = [winPad, winPad, winPad, winPad]; 1943 } 1944 1945 // Expose public methods 1946 this.val = Selectpicker.prototype.val; 1947 this.render = Selectpicker.prototype.render; 1948 this.refresh = Selectpicker.prototype.refresh; 1949 this.setStyle = Selectpicker.prototype.setStyle; 1950 this.selectAll = Selectpicker.prototype.selectAll; 1951 this.deselectAll = Selectpicker.prototype.deselectAll; 1952 this.destroy = Selectpicker.prototype.destroy; 1953 this.remove = Selectpicker.prototype.remove; 1954 this.show = Selectpicker.prototype.show; 1955 this.hide = Selectpicker.prototype.hide; 1956 1957 this.init(); 1958 }; 1959 1960 Selectpicker.VERSION = '1.14.0-beta3'; 1961 1962 // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both. 1963 Selectpicker.DEFAULTS = { 1964 noneSelectedText: 'Nothing selected', 1965 noneResultsText: 'No results matched {0}', 1966 countSelectedText: function (numSelected, numTotal) { 1967 return (numSelected == 1) ? '{0} item selected' : '{0} items selected'; 1968 }, 1969 maxOptionsText: function (numAll, numGroup) { 1970 return [ 1971 (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', 1972 (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' 1973 ]; 1974 }, 1975 selectAllText: 'Select All', 1976 deselectAllText: 'Deselect All', 1977 source: { 1978 pageSize: 40 1979 }, 1980 chunkSize: 40, 1981 doneButton: false, 1982 doneButtonText: 'Close', 1983 multipleSeparator: ', ', 1984 styleBase: 'btn', 1985 style: classNames.BUTTONCLASS, 1986 size: 'auto', 1987 title: null, 1988 placeholder: null, 1989 titleTip: null, 1990 allowClear: false, 1991 selectedTextFormat: 'values', 1992 width: false, 1993 container: false, 1994 hideDisabled: false, 1995 showSubtext: false, 1996 showIcon: true, 1997 showContent: true, 1998 dropupAuto: true, 1999 header: false, 2000 liveSearch: false, 2001 liveSearchPlaceholder: null, 2002 liveSearchNormalize: false, 2003 liveSearchStyle: 'contains', 2004 actionsBox: false, 2005 iconBase: classNames.ICONBASE, 2006 tickIcon: classNames.TICKICON, 2007 showTick: false, 2008 template: { 2009 caret: '<span class="caret"></span>' 2010 }, 2011 maxOptions: false, 2012 mobile: false, 2013 selectOnTab: false, 2014 dropdownAlignRight: false, 2015 windowPadding: 0, 2016 virtualScroll: 600, 2017 display: false, 2018 sanitize: true, 2019 sanitizeFn: null, 2020 whiteList: DefaultWhitelist 2021 }; 2022 2023 Selectpicker.prototype = { 2024 2025 constructor: Selectpicker, 2026 2027 init: function () { 2028 var that = this, 2029 id = this.$element.attr('id'), 2030 element = this.$element[0], 2031 form = element.form; 2032 2033 selectId++; 2034 this.selectId = 'bs-select-' + selectId; 2035 2036 // add tabindex -1 and aria hidden to hidden <select> element 2037 this.$element.attr('tabindex', '-1').attr('aria-hidden', 'true'); 2038 2039 element.classList.add('bs-select-hidden'); 2040 2041 this.multiple = this.$element.prop('multiple'); 2042 this.autofocus = this.$element.prop('autofocus'); 2043 2044 // if the current select has a label 2045 // change it to be associated to the button bar instead 2046 var label = $('label[for="' + id + '"]').get(0); 2047 var labelID; 2048 if ($(label).attr('id')){ 2049 labelID = $(label).attr('id'); 2050 } else { 2051 labelID = 'bs-label-' + selectId; 2052 $(label).attr('id', labelID); 2053 } 2054 2055 2056 2057 if (element.classList.contains('show-tick')) { 2058 this.options.showTick = true; 2059 } 2060 2061 this.$newElement = this.createDropdown(); 2062 2063 this.$element 2064 .after(this.$newElement) 2065 .prependTo(this.$newElement); 2066 2067 // ensure select is associated with form element if it got unlinked after mov
2067ing it inside newElement 2068 if (form && element.form === null) { 2069 if (!form.id) form.id = 'form-' + this.selectId; 2070 element.setAttribute('form', form.id); 2071 } 2072 2073 2074 2075 this.$button = this.$newElement.children('button'); 2076 2077 if (this.options.allowClear) this.$clearButton = this.$button.children('.bs-select-clear-selected'); 2078 this.$menu = this.$newElement.children(Selector.MENU); 2079 this.$menuInner = this.$menu.children('.inner'); 2080 this.$searchbox = this.$menu.find('input'); 2081 2082 element.classList.remove('bs-select-hidden'); 2083 2084 this.fetchData(function () { 2085 that.render(true); 2086 that.buildList(); 2087 2088 requestAnimationFrame(function () { 2089 that.$element.trigger('loaded' + EVENT_KEY); 2090 }); 2091 }); 2092 2093 if (this.options.dropdownAlignRight === true) this.$menu[0].classList.add(classNames.MENURIGHT); 2094 2095 if (typeof id !== 'undefined') { 2096 this.$button.attr('data-id', id); 2097 } 2098 2099 if (typeof labelID !== 'undefined') { 2100 this.$button.attr('aria-labelledby', labelID); 2101 } 2102 2103 this.$button.attr('aria-live', 'polite'); 2104 this.$button.attr('aria-atomic', 'true'); 2105 2106 this.checkDisabled(); 2107 this.clickListener(); 2108 2109 if (version.major > 4) this.dropdown = new Dropdown(this.$button[0]); 2110 2111 if (this.options.liveSearch) { 2112 this.liveSearchListener(); 2113 this.focusedParent = this.$searchbox[0]; 2114 } else { 2115 this.focusedParent = this.$menuInner[0]; 2116 } 2117 2118 this.setStyle(); 2119 this.setWidth(); 2120 if (this.options.container) { 2121 this.selectPosition(); 2122 } else { 2123 this.$element.on('hide' + EVENT_KEY, function () { 2124 if (that.isVirtual()) { 2125 // empty menu on close 2126 var menuInner = that.$menuInner[0], 2127 emptyMenu = menuInner.firstChild.cloneNode(false); 2128 2129 // replace the existing UL with an empty one - this is faster than $.empty() or innerHTML = '' 2130 menuInner.replaceChild(emptyMenu, menuInner.firstChild); 2131 menuInner.scrollTop = 0; 2132 } 2133 }); 2134 } 2135 this.$menu.data('this', this); 2136 this.$newElement.data('this', this); 2137 if (this.options.mobile) this.mobile(); 2138 2139 this.$newElement.on({ 2140 'hide.bs.dropdown': function (e) { 2141 that.$element.trigger('hide' + EVENT_KEY, e); 2142 }, 2143 'hidden.bs.dropdown': function (e) { 2144 that.$element.trigger('hidden' + EVENT_KEY, e); 2145 }, 2146 'show.bs.dropdown': function (e) { 2147 that.$element.trigger('show' + EVENT_KEY, e); 2148 }, 2149 'shown.bs.dropdown': function (e) { 2150 that.$element.trigger('shown' + EVENT_KEY, e); 2151 } 2152 }); 2153 2154 if (element.hasAttribute('required')) { 2155 this.$element.on('invalid' + EVENT_KEY, function () { 2156 that.$button[0].classList.add('bs-invalid'); 2157 2158 that.$element 2159 .on('shown' + EVENT_KEY + '.invalid', function () { 2160 that.$element 2161 .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened 2162 .off('shown' + EVENT_KEY + '.invalid'); 2163 }) 2164 .on('rendered' + EVENT_KEY, function () { 2165 // if select is no longer invalid, remove the bs-invalid class 2166 if (this.validity.valid) that.$button[0].classList.remove('bs-invalid'); 2167 that.$element.off('rendered' + EVENT_KEY); 2168 }); 2169 2170 that.$button.on('blur' + EVENT_KEY, function () { 2171 that.$element.trigger('focus').trigger('blur'); 2172 that.$button.off('blur' + EVENT_KEY); 2173 }); 2174 }); 2175 } 2176 2177 if (form) { 2178 $(form).on('reset' + EVENT_KEY, function () { 2179 requestAnimationFrame(function () { 2180 that.render(); 2181 }); 2182 }); 2183 } 2184 }, 2185 2186 createDropdown: function () { 2187 // Options 2188 // If we are multiple or showTick option is set, then add the show-tick class 2189 var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '', 2190 // multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', 2191 multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', 2192 inputGroup = '', 2193 autofocus = this.autofocus ? ' autofocus' : ''; 2194 2195 if (version.major < 4 && this.$element.parent().hasClass('input-group')) { 2196 inputGroup = ' input-group-btn'; 2197 } 2198 2199 // Elements 2200 var drop, 2201 header = '', 2202 searchbox = '', 2203 actionsbox = '', 2204 donebutton = '', 2205 clearButton = ''; 2206 2207 if (this.options.header) { 2208 header = 2209 '<div class="' + classNames.POPOVERHEADER + '">' + 2210 '<button type="button" class="close" aria-hidden="true">×</button>' + 2211 this.options.header + 2212 '</div>'; 2213 } 2214 2215 if (this.options.liveSearch) { 2216 searchbox = 2217 '<div class="bs-searchbox">' + 2218 '<input type="search" class="form-control" autocomplete="off"' + 2219 ( 2220 this.options.liveSearchPlaceholder === null ? '' 2221 : 2222 ' placeholder="' + htmlEscape(this.options.liveSearchPlaceholder) + '"' 2223 ) + 2224 ' role="combobox" aria-label="Search" aria-controls="' + this.selectId + '" aria-autocomplete="list">' + 2225 '</div>'; 2226 } 2227 2228 if (this.multiple && this.options.actionsBox) { 2229 actionsbox = 2230 '<div class="bs-actionsbox">' + 2231 '<div class="btn-group btn-group-sm">
2231' + 2232 '<button type="button" class="actions-btn bs-select-all btn ' + classNames.BUTTONCLASS + '">' + 2233 this.options.selectAllText + 2234 '</button>' + 2235 '<button type="button" class="actions-btn bs-deselect-all btn ' + classNames.BUTTONCLASS + '">' + 2236 this.options.deselectAllText + 2237 '</button>' + 2238 '</div>' + 2239 '</div>'; 2240 } 2241 2242 if (this.multiple && this.options.doneButton) { 2243 donebutton = 2244 '<div class="bs-donebutton">' + 2245 '<div class="btn-group">' + 2246 '<button type="button" class="btn btn-sm ' + classNames.BUTTONCLASS + '">' + 2247 this.options.doneButtonText + 2248 '</button>' + 2249 '</div>' + 2250 '</div>'; 2251 } 2252 2253 if (this.options.allowClear) { 2254 clearButton = '<span class="close bs-select-clear-selected" title="' + this.options.deselectAllText + '"><span>×</span>'; 2255 } 2256 2257 drop = 2258 '<div class="dropdown bootstrap-select' + showTick + inputGroup + '">' + 2259 '<button type="button" tabindex="0" class="' + 2260 this.options.styleBase + 2261 ' dropdown-toggle" ' + 2262 (this.options.display === 'static' ? 'data-display="static"' : '') + 2263 Selector.DATA_TOGGLE + 2264 autofocus + 2265 ' role="combobox"' + 2266 ' aria-controls="' + this.selectId + '"' + 2267 ' aria-haspopup="listbox"' + 2268 ' aria-expanded="false">' + 2269 '<div class="filter-option">' + 2270 '<div class="filter-option-inner">' + 2271 '<div class="filter-option-inner-inner"> </div>' + 2272 '</div> ' + 2273 '</div>' + 2274 clearButton + 2275 '</span>' + 2276 ( 2277 version.major >= '4' ? '' 2278 : 2279 '<span class="bs-caret">' + 2280 this.options.template.caret + 2281 '</span>' 2282 ) + 2283 '</button>' + 2284 '<div class="' + classNames.MENU + ' ' + (version.major >= '4' ? '' : classNames.SHOW) + '">' + 2285 header + 2286 searchbox + 2287 actionsbox + 2288 '<div class="inner ' + classNames.SHOW + '" id="' + this.selectId + '" ' + '>' + 2289 '<ul class="' + classNames.MENU + ' inner ' + (version.major >= '4' ? classNames.SHOW : '') + '" role="listbox" ' + multiselectable + '>' + 2290 '</ul>' + 2291 '</div>' + 2292 donebutton + 2293 '</div>' + 2294 '</div>'; 2295 2296 return $(drop); 2297 }, 2298 2299 setPositionData: function () { 2300 this.selectpicker.view.canHighlight = []; 2301 this.selectpicker.view.size = 0; 2302 this.selectpicker.view.firstHighlightIndex = false; 2303 2304 for (var i = 0; i < this.selectpicker.current.data.length; i++) { 2305 var li = this.selectpicker.current.data[i], 2306 canHighlight = true; 2307 2308 if (li.type === 'divider') { 2309 canHighlight = false; 2310 li.height = this.sizeInfo.dividerHeight; 2311 } else if (li.type === 'optgroup-label') { 2312 canHighlight = false; 2313 li.height = this.sizeInfo.dropdownHeaderHeight; 2314 } else { 2315 li.height = this.sizeInfo.liHeight; 2316 } 2317 2318 if (li.disabled) canHighlight = false; 2319 2320 this.selectpicker.view.canHighlight.push(canHighlight); 2321 2322 if (canHighlight) { 2323 this.selectpicker.view.size++; 2324 li.posinset = this.selectpicker.view.size; 2325 if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i; 2326 } 2327 2328 li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height; 2329 console.log(li); 2330 } 2331 }, 2332 2333 isVirtual: function () { 2334 return (this.options.virtualScroll !== false) && (this.selectpicker.main.data.length >= this.options.virtualScroll) || this.options.virtualScroll === true; 2335 }, 2336 2337 createView: function (isSearching, setSize, refresh) { 2338 var that = this, 2339 scrollTop = 0; 2340 2341 this.selectpicker.isSearching = isSearching; 2342 this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main; 2343 2344 this.setPositionData(); 2345 2346 if (setSize) { 2347 if (refresh) { 2348 scrollTop = this.$menuInner[0].scrollTop; 2349 } else if (!that.multiple) { 2350 var element = that.$element[0], 2351 selectedIndex = (element.options[element.selectedIndex] || {}).liIndex; 2352 2353 if (typeof selectedIndex === 'number' && that.options.size !== false) { 2354 var selectedData = that.selectpicker.main.data[selectedIndex], 2355 position = selectedData && selectedData.position; 2356 2357 if (position) { 2358 scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2); 2359 } 2360 } 2361 } 2362 } 2363 2364 scroll(scrollTop, true); 2365 2366 this.$menuInner.off('scroll.createView').on('scroll.createView', function (e, updateV
2366alue) { 2367 if (!that.noScroll) scroll(this.scrollTop, updateValue); 2368 that.noScroll = false; 2369 }); 2370 2371 function scroll (scrollTop, init) { 2372 var size = that.selectpicker.current.data.length, 2373 chunks = [], 2374 chunkSize, 2375 chunkCount, 2376 firstChunk, 2377 lastChunk, 2378 currentChunk, 2379 prevPositions, 2380 positionIsDifferent, 2381 previousElements, 2382 menuIsDifferent = true, 2383 isVirtual = that.isVirtual(); 2384 2385 that.selectpicker.view.scrollTop = scrollTop; 2386 2387 chunkSize = that.options.chunkSize; // number of options in a chunk 2388 chunkCount = Math.ceil(size / chunkSize) || 1; // number of chunks 2389 2390 for (var i = 0; i < chunkCount; i++) { 2391 var endOfChunk = (i + 1) * chunkSize; 2392 2393 if (i === chunkCount - 1) { 2394 endOfChunk = size; 2395 } 2396 2397 chunks[i] = [ 2398 (i) * chunkSize + (!i ? 0 : 1), 2399 endOfChunk 2400 ]; 2401 2402 if (!size) break; 2403 2404 if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) { 2405 currentChunk = i; 2406 } 2407 } 2408 2409 if (currentChunk === undefined) currentChunk = 0; 2410 2411 prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1]; 2412 2413 // always display previous, current, and next chunks 2414 firstChunk = Math.max(0, currentChunk - 1); 2415 lastChunk = Math.min(chunkCount - 1, currentChunk + 1); 2416 2417 that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0); 2418 that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0); 2419 2420 positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1; 2421 2422 if (that.activeElement !== undefined) { 2423 if (init) { 2424 if (that.activeElement !== that.selectedElement) { 2425 that.defocusItem(that.activeElement); 2426 } 2427 that.activeElement = undefined; 2428 } 2429 2430 if (that.activeElement !== that.selectedElement) { 2431 that.defocusItem(that.selectedElement); 2432 } 2433 } 2434 2435 if (that.prevActiveElement !== undefined && that.prevActiveElement !== that.activeElement && that.prevActiveElement !== that.selectedElement) { 2436 that.defocusItem(that.prevActiveElement); 2437 } 2438 2439 if (init || positionIsDifferent || that.selectpicker.current.hasMore) { 2440 previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : []; 2441 2442 if (isVirtual === false) { 2443 that.selectpicker.view.visibleElements = that.selectpicker.current.elements; 2444 } else { 2445 that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1); 2446 } 2447 2448 that.setOptionStatus(); 2449 2450 // if searching, check to make sure the list has actually been updated before updating DOM 2451 // this prevents unnecessary repaints 2452 if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements); 2453 2454 // if virtual scroll is disabled and not searching, 2455 // menu should never need to be updated more than once 2456 if ((init || isVirtual === true) && menuIsDifferent) { 2457 var menuInner = that.$menuInner[0], 2458 menuFragment = document.createDocumentFragment(), 2459 emptyMenu = menuInner.firstChild.cloneNode(false), 2460 marginTop, 2461 marginBottom, 2462 elements = that.selectpicker.view.visibleElements, 2463 toSanitize = []; 2464 2465 // replace the existing UL with an empty one - this is faster than $.empty() 2466 menuInner.replaceChild(emptyMenu, menuInner.firstChild); 2467 var currentOptID; 2468 for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) { 2469 var element = elements[i], 2470 elText, 2471 elementData; 2472 2473 console.log(elementData); 2474 2475 if (that.options.sanitize) { 2476 elText = element.lastChild; 2477 2478 if (elText) { 2479 elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0]; 2480 2481 if (elementData && elementData.content && !elementData.sanitized) { 2482 toSanitize.push(elText); 2483 elementData.sanitized = true; 2484 } 2485 } 2486 } 2487 2488 if (elementData.optID && currentOptID != elementData.optID) { 2489 // its a new option group wrapper 2490 var groupWrapper = elementTemplates.group.cloneNode(false); 2491 var listbox = elementTemplates.listbox.cloneNode(false); 2492 var groupNotice = elementTemplates.groupNotice.cloneNode(true); 2493 listbox.setAttribute('aria-label', elementData.display); 2494 listbox.id = 'optgroup-' + elementData.optID; 2495 2496 element.appendChild(groupNotice); 2497 2498 groupWrapper.appendChild(listbox); 2499 menuFragment.appendChild(groupWrapper); 2500 2501 2502 element.setAttribute('data-index', elementData.index); 2503 menuFragment.getElementById('optgroup-' + elementData.optID).appendChild(element); 2504 2505 currentOptID = elementData.optID; 2506 } else if (elementData.type == 'option' && elementData.optID) { 2507 // its an option within a group 2508 element.setAttribute('data-index', elementData.index); 2509 menuFragment.getElementById('optgroup-' + elementData.optID).appendChild(element); 2510 } else if (!elementData.optID) { 2511 // its an option without a group 2512 element.setAttribute('data-index', elementData.index); 2513 menuFragment.appendChild(element); 2514 } 2515 } 2516 2517 if (that.options.sanitize && toSanitize.length) { 2518 sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn); 2519 } 2520 2521 if (isVirtual === true) { 2522 marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position); 2523 marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position); 2524 2525 menuInner.firstChild.style.marginTop = marginTop + 'px'; 2526 menuInner.firstChild.style.marginBottom = marginBottom + 'px'; 2527 } else { 2528 menuInner.firstChild.style.marginTop = 0; 2529 menuInner.firstChild.style.marginBottom = 0; 2530 } 2531 2532 // write menu to DOM - NL 2533 menuInner.firstChild.appendChild(menuFragment); 2534 2535 // if an option is encountered that is wider than the current menu width, update the menu width accordingly 2536 // switch to ResizeObserver with increased browser support 2537 if (isVirtual === true && that.sizeInfo.hasScrollBar) { 2538 var menuInnerInnerWidth = menuInner.firstChild.offsetWidth; 2539 2540 if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) { 2541 menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; 2542 } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) { 2543 // set to 0 to get actual width of menu 2544 that.$menu[0].style.minWidth = 0; 2545 2546 var actualMenuWidth = menuInner.firstChild.offsetWidth; 2547 2548 if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) { 2549 that.sizeInfo.menuInnerInnerWidth = actualMenuWidth; 2550 menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; 2551 } 2552 2553 // reset to default CSS styling 2554 that.$menu[0].style.minWidth = ''; 2555 } 2556 } 2557 } 2558 2559 if ((!isSearching && that.options.source.data || isSearching && that.options.source.search) && that.selectpicker.current.hasMore && currentChunk === chunkCount - 1) { 2560 // Don't load the next chunk until scrolling has started 2561 // This prevents unnecessary requests while the user is typing if pageSize is <= chunkSize 2562 if (scrollTop > 0) { 2563 // Chunks use 0-based indexing, but pages use 1-based. Add 1 to convert and add 1 again to get next page 2564 var page = Math.floor((currentChunk * that.options.chunkSize) / that.options.source.pageSize) + 2; 2565 2566 that.fetchData(function () { 2567 that.render(); 2568 that.buildList(size, isSearching); 2569 that.setPositionData(); 2570 scroll(scrollTop); 2571 }, isSearching ? 'search' : 'data', page, isSearching ? that.selectpicker.search.previousValue : undefined); 2572 } 2573 } 2574 } 2575 2576 that.prevActiveElement = that.activeElement; 2577 2578 if (!that.options.liveSearch) { 2579 that.$menuInner.trigger('focus'); 2580 } else if (isSearching && init) { 2581 var index = 0, 2582 newActive; 2583 2584 if (!that.selectpicker.view.canHighlight[index]) { 2585 index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true); 2586 } 2587 2588 newActive = that.selectpicker.view.visibleElements[index]; 2589 2590 that.defocusItem(that.selectpicker.view.currentActive); 2591 2592 that.activeElement = (that.selectpicker.current.data[index] || {}).element; 2593 2594 that.focusItem(newActive); 2595 } 2596 } 2597 2598 $(window) 2599 .off('resize' + EVENT_KEY + '.' + this.selectId + '.createView') 2600 .on('resize' + EVENT_KEY + '.' + this.selectId + '.createView', function () { 2601 var isActive = that.$newElement.hasClass(classNames.SHOW); 2602 2603 if (isActive) scroll(that.$menuInner[0].scrollTop); 2604 }); 2605 }, 2606 2607 focusItem: function (li, liData, noStyle) { 2608 if (li) { 2609 liData = liData || this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)]; 2610 var a = li.firstChild; 2611 2612 if (a) { 2613 // NL TODO maybe remove 2614 // a.setAttribute('aria-setsize', this.selectpicker.view.size); 2615 // a.setAttribute('aria-posinset', liData.posinset); 2616 2617 if (noStyle !== true) { 2618 // this.focusedParent.setAttribute('aria-activedescendant', a.id); 2619 // this.$button[0].setAttribute('aria-activedescendant', a.id); 2620 this.$button[0].setAttribute('aria-activedescendant', li.id); 2621 li.classList.add('active'); 2622 a.classList.add('active'); 2623 } 2624 } 2625 } 2626 }, 2627 2628 defocusItem: function (li) { 2629 if (li) { 2630 li.classList.remove('active'); 2631 if (li.firstChild) li.firstChild.classList.remove('active'); 2632 } 2633 }, 2634 2635 setPlaceholder: function () { 2636 var that = this, 2637 updateIndex = false;
2638 2639 if ((this.options.placeholder || this.options.allowClear) && !this.multiple) { 2640 if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option'); 2641 2642 // this option doesn't create a new <li> element, but does add a new option at the start, 2643 // so startIndex should increase to prevent having to check every option for the bs-title-option class 2644 updateIndex = true; 2645 2646 var element = this.$element[0], 2647 selectTitleOption = false, 2648 titleNotAppended = !this.selectpicker.view.titleOption.parentNode, 2649 selectedIndex = element.selectedIndex, 2650 selectedOption = element.options[selectedIndex], 2651 firstSelectable = element.querySelector('select > *:not(:disabled)'), 2652 firstSelectableIndex = firstSelectable ? firstSelectable.index : 0, 2653 navigation = window.performance && window.performance.getEntriesByType('navigation'), 2654 // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation 2655 isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2; 2656 2657 if (titleNotAppended) { 2658 // Use native JS to prepend option (faster) 2659 this.selectpicker.view.titleOption.className = 'bs-title-option'; 2660 this.selectpicker.view.titleOption.value = ''; 2661 2662 // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. 2663 // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs, 2664 // if so, the select will have the data-selected attribute 2665 selectTitleOption = !selectedOption || (selectedIndex === firstSelectableIndex && selectedOption.defaultSelected === false && this.$element.data('selected') === undefined); 2666 } 2667 2668 if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) { 2669 element.insertBefore(this.selectpicker.view.titleOption, element.firstChild); 2670 } 2671 2672 // Set selected *after* appending to select, 2673 // otherwise the option doesn't get selected in IE 2674 // set using selectedIndex, as setting the selected attr to true here doesn't work in IE11 2675 if (selectTitleOption && isNotBackForward) { 2676 element.selectedIndex = 0; 2677 } else if (document.readyState !== 'complete') { 2678 // if navigation type is back_forward, there's a chance the select will have its value set by BFCache 2679 // wait for that value to be set, then run render again 2680 window.addEventListener('pageshow', function () { 2681 if (that.selectpicker.view.displayedValue !== element.value) that.render(); 2682 }); 2683 } 2684 } 2685 2686 return updateIndex; 2687 }, 2688 2689 fetchData: function (callback, type, page, searchValue) { 2690 page = page || 1; 2691 type = type || 'data'; 2692 2693 var that = this, 2694 data = this.options.source[type], 2695 builtData; 2696 2697 if (data) { 2698 this.options.virtualScroll = true; 2699 2700 if (typeof data === 'function') { 2701 data.call( 2702 this, 2703 function (data, more, totalItems) { 2704 var current = that.selectpicker[type === 'search' ? 'search' : 'main']; 2705 current.hasMore = more; 2706 current.totalItems = totalItems; 2707 builtData = that.buildData(data, type); 2708 callback.call(that, builtData); 2709 that.$element.trigger('fetched' + EVENT_KEY); 2710 }, 2711 page, 2712 searchValue 2713 ); 2714 } else if (Array.isArray(data)) { 2715 builtData = that.buildData(data, type); 2716 callback.call(that, builtData); 2717 } 2718 } else { 2719 builtData = this.buildData(false, type); 2720 callback.call(that, builtData); 2721 } 2722 }, 2723 2724 buildData: function (data, type) { 2725 var that = this; 2726 var dataGetter = data === false ? getOptionData.fromOption : getOptionData.fromDataSource; 2727 2728 var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([style*="display: none"])', 2729 mainData = [], 2730 // startLen = this.selectpicker.main.data ? this.selectpicker.main.data.length : 0, 2731 optID = 0, 2732 startIndex = this.setPlaceholder() && !data ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop 2733 2734 // if (type === 'search') { 2735 // startLen = this.selectpicker.search.data.length; 2736 // } 2737 2738 if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; 2739 2740 var selectOptions = data ? data.filter(filterHidden, this) : this.$element[0].querySelectorAll('select > *' + optionSelector); 2741 2742 // function addDivider (config) { 2743 // var previousData = mainData[mainData.length - 1]; 2744 2745 // // ensure optgroup doesn't create back-to-back dividers 2746 // if ( 2747 // previousData && 2748 // previousData.type === 'divider' && 2749 // (previousData.optID || config.optID) 2750 // ) { 2751 // return; 2752 // } 2753 2754 // config = config || {}; 2755 // config.type = 'divider'; 2756 2757 // // mainData.push(config); 2758 // } 2759 2760 function addOption (item, config) { 2761 config = config || {}; 2762
2763 config.divider = dataGetter(item, 'divider'); 2764 2765 if (config.divider === true) { 2766 // addDivider({ 2767 // optID: config.optID 2768 // }); 2769 } else { 2770 // var liIndex = mainData.length + startLen, 2771 var liIndex = mainData.length, 2772 cssText = dataGetter(item, 'style'), 2773 inlineStyle = cssText ? htmlEscape(cssText) : '', 2774 optionClass = (item.className || '') + (config.optgroupClass || ''); 2775 2776 if (config.optID) optionClass = 'opt ' + optionClass; 2777 2778 config.optionClass = optionClass.trim(); 2779 config.inlineStyle = inlineStyle; 2780 2781 config.text = dataGetter(item, 'text'); 2782 config.title = dataGetter(item, 'title'); 2783 config.content = dataGetter(item, 'content'); 2784 config.tokens = dataGetter(item, 'tokens'); 2785 config.subtext = dataGetter(item, 'subtext'); 2786 config.icon = dataGetter(item, 'icon'); 2787 2788 config.display = config.content || config.text; 2789 config.value = item.value === undefined ? item.text : item.value; 2790 config.type = 'option'; 2791 config.index = liIndex; 2792 2793 config.option = !item.option ? item : item.option; // reference option element if it exists 2794 config.option.liIndex = liIndex; 2795 config.selected = !!item.selected; 2796 config.disabled = config.disabled || !!item.disabled; 2797 2798 if (data !== false) { 2799 if (that.selectpicker.optionValuesDataMap[config.value]) { 2800 config = $.extend(that.selectpicker.optionValuesDataMap[config.value], config); 2801 } else { 2802 that.selectpicker.optionValuesDataMap[config.value] = config; 2803 } 2804 } 2805 2806 mainData.push(config); 2807 } 2808 } 2809 2810 function addOptgroup (index, selectOptions) { 2811 // console.log("addOptgroup"); 2812 // console.log(index, selectOptions); 2813 var optgroup = selectOptions[index], 2814 // skip placeholder option 2815 previous = index - 1 < startIndex ? false : selectOptions[index - 1], 2816 // next = selectOptions[index + 1], 2817 options = data ? optgroup.children.filter(filterHidden, this) : optgroup.querySelectorAll('option' + optionSelector); 2818 2819 if (!options.length) return; 2820 2821 var config = { 2822 display: htmlEscape(dataGetter(item, 'label')), 2823 subtext: dataGetter(optgroup, 'subtext'), 2824 icon: dataGetter(optgroup, 'icon'), 2825 type: 'optgroup-label', 2826 optgroupClass: ' ' + (optgroup.className || ''), 2827 optgroup: optgroup 2828 }, 2829 headerIndex, 2830 lastIndex; 2831 2832 optID++; 2833 2834 if (previous) { 2835 // addDivider({ optID: optID }); 2836 } 2837 2838 config.optID = optID; 2839 2840 // push the option group to the main config 2841 // mainData.push(config); 2842 2843 for (var j = 0, len = options.length; j < len; j++) { 2844 var option = options[j]; 2845 2846 if (j === 0) { 2847 headerIndex = mainData.length - 1; 2848 lastIndex = headerIndex + len; 2849 } 2850 2851 addOption(option, { 2852 headerIndex: headerIndex, 2853 lastIndex: lastIndex, 2854 optID: config.optID, 2855 optgroupClass: config.optgroupClass, 2856 disabled: optgroup.disabled, 2857 optGroupLabel: config.display 2858 }); 2859 } 2860 2861 // NL commented out, ends with divider 2862 // if (next) { 2863 // addDivider({ optID: optID }); 2864 // } 2865 } 2866 2867 for (var len = selectOptions.length, i = startIndex; i < len; i++) { 2868 var item = selectOptions[i], 2869 children = item.children; 2870 2871 if (children && children.length) { 2872 addOptgroup.call(this, i, selectOptions); 2873 } else { 2874 addOption.call(this, item, {}); 2875 } 2876 } 2877 2878 switch (type) { 2879 case 'data': { 2880 if (!this.selectpicker.main.data) { 2881 this.selectpicker.main.data = []; 2882 } 2883 // Array.prototype.push.apply(this.selectpicker.main.data, mainData); 2884 // this.selectpicker.current.data = this.selectpicker.main.data; 2885 this.selectpicker.main.data = this.selectpicker.current.data = mainData; 2886 break; 2887 } 2888 case 'search': { 2889 Array.prototype.push.apply(this.selectpicker.search.data, mainData); 2890 break; 2891 } 2892 } 2893 2894 return mainData; 2895 }, 2896 2897 buildList: function (size, searching) { 2898 var that = this, 2899 selectData = searching ? this.selectpicker.search.data : this.selectpicker.main.data, 2900 mainElements = [], 2901 widestOptionLength = 0; 2902 2903 if ((that.options.showTick || that.multiple) && !elementTemplates.checkMark.parentNode) { 2904 elementTemplates.checkMark.className = this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark'; 2905 elementTemplates.a.appendChild(elementTemplates.checkMark); 2906 } 2907 2908 function buildElement (mainElements, item) { 2909 // console.log("buildElement: mainElements, item"); 2910 // console.log(mainElements, item); 2911 var liElement, 2912 combinedLength = 0; 2913 2914 switch (item.type) {
2915 case 'divider': 2916 liElement = generateOption.li( 2917 false, 2918 classNames.DIVIDER, 2919 (item.optID ? item.optID + 'div' : undefined) 2920 ); 2921 2922 break; 2923 2924 case 'option': 2925 liElement = generateOption.li( 2926 generateOption.a( 2927 generateOption.text.call(that, item), 2928 item.optionClass, 2929 item.inlineStyle 2930 ), 2931 '', 2932 item.optID 2933 ); 2934 2935 // if (liElement.firstChild) { 2936 // liElement.firstChild.id = that.selectId + '-' + item.index; 2937 // } 2938 2939 liElement.id = that.selectId + '-' + item.index; 2940 2941 break; 2942 2943 case 'optgroup-label': 2944 liElement = generateOption.li( 2945 generateOption.label.call(that, item), 2946 'dropdown-header' + item.optgroupClass, 2947 item.optID 2948 ); 2949 2950 break; 2951 } 2952 2953 if (!item.element) { 2954 item.element = liElement; 2955 } else { 2956 item.element.innerHTML = liElement.innerHTML; 2957 } 2958 mainElements.push(item.element); 2959 2960 // count the number of characters in the option - not perfect, but should work in most cases 2961 if (item.display) combinedLength += item.display.length; 2962 if (item.subtext) combinedLength += item.subtext.length; 2963 // if there is an icon, ensure this option's width is checked 2964 if (item.icon) combinedLength += 1; 2965 2966 if (combinedLength > widestOptionLength) { 2967 widestOptionLength = combinedLength; 2968 2969 // guess which option is the widest 2970 // use this when calculating menu width 2971 // not perfect, but it's fast, and the width will be updating accordingly when scrolling 2972 that.selectpicker.view.widestOption = mainElements[mainElements.length - 1]; 2973 } 2974 } 2975 2976 var startIndex = size || 0; 2977 2978 for (var len = selectData.length, i = startIndex; i < len; i++) { 2979 var item = selectData[i]; 2980 2981 buildElement(mainElements, item); 2982 } 2983 2984 if (size) { 2985 if (searching) { 2986 Array.prototype.push.apply(this.selectpicker.search.elements, mainElements); 2987 } else { 2988 Array.prototype.push.apply(this.selectpicker.main.elements, mainElements); 2989 this.selectpicker.current.elements = this.selectpicker.main.elements; 2990 } 2991 } else { 2992 if (searching) { 2993 this.selectpicker.search.elements = mainElements; 2994 } else { 2995 this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements; 2996 } 2997 } 2998 }, 2999 3000 findLis: function () { 3001 return this.$menuInner.find('.inner li[role="option"]'); 3002 }, 3003 3004 render: function (init) { 3005 var that = this, 3006 element = this.$element[0], 3007 // ensure titleOption is appended and selected (if necessary) before getting selectedOptions 3008 placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0, 3009 selectedOptions = getSelectedOptions.call(this), 3010 selectedCount = selectedOptions.length, 3011 selectedValues = getSelectValues.call(this, selectedOptions), 3012 button = this.$button[0], 3013 buttonInner = button.querySelector('.filter-option-inner-inner'), 3014 multipleSeparator = document.createTextNode(this.options.multipleSeparator), 3015 titleFragment = elementTemplates.fragment.cloneNode(false), 3016 titleTipFragment = elementTemplates.fragment.cloneNode(false), 3017 showCount, 3018 countMax, 3019 hasContent = false; 3020 3021 // console.log('render start : that.selectpicker.main.data', that.selectpicker.main.data); 3022 3023 function createSelected (item) { 3024 if (item.selected) { 3025 that.createOption(item, true); 3026 } else if (item.children && item.children.length) { 3027 item.children.map(createSelected); 3028 } 3029 } 3030 3031 // create selected option elements to ensure select value is correct 3032 if (this.options.source.data && init) { 3033 selectedOptions.map(createSelected); 3034 element.appendChild(this.selectpicker.main.optionQueue); 3035 3036 if (placeholderSelected) placeholderSelected = element.selectedIndex === 0; 3037 } 3038 3039 button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !selectedValues && selectedValues !== 0); 3040 3041 if (!that.multiple && selectedOptions.length === 1) { 3042 that.selectpicker.view.displayedValue = selectedValues; 3043 } 3044 3045 if (this.options.selectedTextFormat === 'static') { 3046 titleFragment = generateOption.text.call(this, { text: this.options.placeholder }, true); 3047 } else { 3048 showCount = this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 0; 3049 3050 // determine if the number of selected options will be shown (showCount === true) 3051 if (showCount) { 3052 countMax = this.options.selectedTextFormat.split('>'); 3053 showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2); 3054 } 3055 3056 // only loop through all selected options if the count won't be shown 3057 if (showCount === false) { 3058 if (!placeholderSelected) { 3059 for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) { 3060 if (selectedIndex < 50) { 3061 var option = selectedOptions[selectedIndex], 3062 titleOptions = {}; 3063 3064 if (option) { 3065 if (this.multiple && selectedIndex > 0) { 3066 titleFragment.appendChild(multipleSeparator.cloneNode(false)); 3067 } 3068 3069 if (option.title) { 3070 titleOptions.text = option.title; 3071 } else if (option.content && that.options.showContent) { 3072 titleOptions.content = option.content.toString(); 3073 hasContent = true; 3074 } else { 3075 if (that.options.showIcon) { 3076 titleOptions.icon = option.icon; 3077 } 3078 if (that.options.showSubtext && !that.multiple && option.subtext) titleOptions.subtext = ' ' + option.subtext; 3079 titleOptions.text = option.text.trim(); 3080 } 3081 3082 titleFragment.appendChild(generateOption.text.call(this, titleOptions, true)); 3083 } 3084 } else { 3085 break; 3086 } 3087 } 3088 3089 // add ellipsis 3090 if (selectedCount > 49) { 3091 titleFragment.appendChild(document.createTextNode('...')); 3092 } 3093 } 3094 } else { 3095 var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"]):not([style*="display: none"])'; 3096 if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; 3097 3098 // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc. 3099 var totalCount = this.$element[0].querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length, 3100 tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText; 3101 3102 titleFragment = generateOption.text.call(this, { 3103 text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString()) 3104 }, true); 3105 } 3106 } 3107 3108 // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText 3109 if (!titleFragment.childNodes.length) { 3110 titleFragment = generateOption.text.call(this, { 3111 text: this.options.placeholder ? this.options.placeholder : this.options.noneSelectedText 3112 }, true); 3113 } 3114 3115 // if the select has a title, apply it to the button, and if not, apply titleFragment text 3116 // strip all HTML tags and trim the result, then unescape any escaped tags 3117 // removed NL 3118 // button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim(); 3119 3120 if (this.options.sanitize && hasContent) { 3121 sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn); 3122 } 3123 3124 buttonInner.innerHTML = '<span class="sr-only">Selected options: </span>'; 3125 buttonInner.appendChild(titleFragment); 3126 3127 if (this.options.titleTip && !button.querySelector('.title-tip')) { 3128 var titleTip = document.createElement('div'); 3129 titleTip.setAttribute('class', 'title-tip'); 3130 titleTipFragment = generateOption.text.call(this, { 3131 text: this.options.titleTip ? this.options.titleTip : '' 3132 }, true); 3133 titleTip.appendChild(titleTipFragment); 3134 button.querySelector('.filter-option').prepend(titleTip); 3135 } 3136 3137 if (version.major < 4 && this.$newElement[0].classList.contains('bs3-has-addon')) { 3138 var filterExpand = button.querySelector('.filter-expand'), 3139 clone = buttonInner.cloneNode(true); 3140 3141 clone.className = 'filter-expand'; 3142 3143 if (filterExpand) { 3144 button.replaceChild(clone, filterExpand); 3145 } else { 3146 button.appendChild(clone); 3147 } 3148 } 3149 // console.log('render END : that.selectpicker.main.data', that.selectpicker.main.data); 3150 3151 this.$element.trigger('rendered' + EVENT_KEY); 3152 }, 3153 3154 /** 3155 * @param [style] 3156 * @param [status] 3157 */ 3158 setStyle: function (newStyle, status) { 3159 var button = this.$button[0], 3160 newElement = this.$newElement[0], 3161 style = this.options.style.trim(), 3162 buttonClass; 3163 3164 if (this.$element.attr('class')) { 3165 this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '')); 3166 } 3167 3168 if (version.major < 4) { 3169 newElement.classList.add('bs3'); 3170 3171 if (newElement.parentNode.classList && newElement.parentNode.classList.contains('input-group') && 3172 (newElement.previousElementSibling || newElement.nextElementSibling) && 3173 (newElement.previousElementSibling || newElement.nextElementSibling).classList.contains('input-group-addon') 3174 ) { 3175 newElement.classList.add('bs3-has-addon'); 3176 } 3177 } 3178 3179 if (newStyle) { 3180 buttonClass = newStyle.trim(); 3181 } else { 3182 buttonClass = style; 3183 } 3184 3185 if (status == 'add') { 3186 if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); 3187 } else if (status == 'remove') { 3188 if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' ')); 3189 } else { 3190 if (style) button.classList.remove.apply(button.classList, style.split(' ')); 3191 if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); 3192 } 3193 }, 3194 3195 liHeight: function (refresh) { 3196 if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return; 3197 3198 var newElement = elementTemplates.div.cloneNode(false), 3199 menu = elementTemplates.div.cloneNode(false), 3200 menuInner = elementTemplates.div.cloneNode(false), 3201 menuInnerInner = document.createElement('ul'), 3202 divider = elementTemplates.li.cloneNode(false), 3203 dropdownHeader = elementTemplates.li.cloneNode(false), 3204 li, 3205 a = elementTemplates.a.cloneNode(false), 3206 text = elementTemplates.span.cloneNode(false), 3207 header = this.options.header && this.$menu.find('.' + classNames.POPOVERHEADER).length > 0 ? this.$menu.find('.' + classNames.POPOVERHEADER)[0].cloneNode(true) : null, 3208 search = this.options.liveSearch ? elementTemplates.div.cloneNode(false) : null, 3209 actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null, 3210 doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null, 3211 firstOption = this.$element[0].options[0]; 3212 3213 this.sizeInfo.selectWidth = this.$newElement[0].offsetWidth; 3214 3215 text.className = 'text'; 3216 a.className = 'dropdown-item ' + (firstOption ? firstOption.className : ''); 3217 newElement.className = this.$menu[0].parentNode.className + ' ' + classNames.SHOW; 3218 newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating 3219 if (this.options.width === 'auto') menu.style.minWidth = 0; 3220 menu.className = classNames.MENU + ' ' + classNames.SHOW; 3221 menuInner.className = 'inner ' + classNames.SHOW; 3222 menuInnerInner.className = classNames.MENU + ' inner ' + (version.major >= '4' ? classNames.SHOW : ''); 3223 divider.className = classNames.DIVIDER; 3224 dropdownHeader.className = 'dropdown-header'; 3225 3226 text.appendChild(document.createTextNode('\u200b')); 3227 3228 if (this.selectpicker.current.data.length) { 3229 for (var i = 0; i < this.selectpicker.current.data.length; i++) { 3230 var data = this.selectpicker.current.data[i]; 3231 if (data.type === 'option' && $(data.element.firstChild).css('display') !== 'none') { 3232 li = data.element; 3233 break; 3234 } 3235 } 3236 } else { 3237 li = elementTemplates.li.cloneNode(false); 3238 a.appendChild(text); 3239 li.appendChild(a); 3240 } 3241 3242 dropdownHeader.appendChild(text.cloneNode(true)); 3243 3244 if (this.selectpicker.view.widestOption) { 3245 menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true)); 3246 } 3247 3248 menuInnerInner.appendChild(li); 3249 menuInnerInner.appendChild(divider); 3250 menuInnerInner.appendChild(dropdownHeader); 3251 if (header) menu.appendChild(header); 3252 if (search) { 3253 var input = document.createElement('input'); 3254 search.className = 'bs-searchbox'; 3255 input.className = 'form-control'; 3256 search.appendChild(input); 3257 menu.appendChild(search); 3258 } 3259 if (actions) menu.appendChild(actions); 3260 menuInner.appendChild(menuInnerInner); 3261 menu.appendChild(menuInner); 3262 if (doneButton) menu.appendChild(doneButton); 3263 newElement.appendChild(menu); 3264 3265 document.body.appendChild(newElement); 3266 3267 var liHeight = li.offsetHeight, 3268 dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0, 3269 headerHeight = header ? header.offsetHeight : 0, 3270 searchHeight = search ? search.offsetHeight : 0, 3271 actionsHeight = actions ? actions.offsetHeight : 0, 3272 doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, 3273 dividerHeight = $(divider).outerHeight(true), 3274 menuStyle = window.getComputedStyle(menu), 3275 menuWidth = menu.offsetWidth, 3276 menuPadding = { 3277 vert: toInteger(menuStyle.paddingTop) + 3278 toInteger(menuStyle.paddingBottom) + 3279 toInteger(menuStyle.borderTopWidth) + 3280 toInteger(menuStyle.borderBottomWidth), 3281 horiz: toInteger(menuStyle.paddingLeft) + 3282 toInteger(menuStyle.paddingRight) + 3283 toInteger(menuStyle.borderLeftWidth) + 3284 toInteger(menuStyle.borderRightWidth) 3285 }, 3286 menuExtras = { 3287 vert: menuPadding.vert + 3288 toInteger(menuStyle.marginTop) + 3289 toInteger(menuStyle.marginBottom) + 2, 3290 horiz: menuPadding.horiz + 3291 toInteger(menuStyle.marginLeft) + 3292 toInteger(menuStyle.marginRight) + 2 3293 }, 3294 scrollBarWidth; 3295 3296 menuInner.style.overflowY = 'scroll'; 3297 3298 scrollBarWidth = menu.offsetWidth - menuWidth; 3299 3300 document.body.removeChild(newElement); 3301 3302 this.sizeInfo.liHeight = liHeight; 3303 this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight; 3304 this.sizeInfo.headerHeight = headerHeight; 3305 this.sizeInfo.searchHeight = searchHeight; 3306 this.sizeInfo.actionsHeight = actionsHeight; 3307 this.sizeInfo.doneButtonHeight = doneButtonHeight;
vendor: 8,813 bytes, lines 3308-3508
3308 this.sizeInfo.dividerHeight = dividerHeight; 3309 this.sizeInfo.menuPadding = menuPadding; 3310 this.sizeInfo.menuExtras = menuExtras; 3311 this.sizeInfo.menuWidth = menuWidth; 3312 this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz; 3313 this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth; 3314 this.sizeInfo.scrollBarWidth = scrollBarWidth; 3315 this.sizeInfo.selectHeight = this.$newElement[0].offsetHeight; 3316 3317 this.setPositionData(); 3318 }, 3319 3320 getSelectPosition: function () { 3321 var that = this, 3322 $window = $(window), 3323 pos = that.$newElement.offset(), 3324 $container = $(that.options.container), 3325 containerPos; 3326 3327 if (that.options.container && $container.length && !$container.is('body')) { 3328 containerPos = $container.offset(); 3329 containerPos.top += parseInt($container.css('borderTopWidth')); 3330 containerPos.left += parseInt($container.css('borderLeftWidth')); 3331 } else { 3332 containerPos = { top: 0, left: 0 }; 3333 } 3334 3335 var winPad = that.options.windowPadding; 3336 3337 this.sizeInfo.selectOffsetTop = pos.top - containerPos.top - $window.scrollTop(); 3338 this.sizeInfo.selectOffsetBot = $window.height() - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight - containerPos.top - winPad[2]; 3339 this.sizeInfo.selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft(); 3340 this.sizeInfo.selectOffsetRight = $window.width() - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth - containerPos.left - winPad[1]; 3341 this.sizeInfo.selectOffsetTop -= winPad[0]; 3342 this.sizeInfo.selectOffsetLeft -= winPad[3]; 3343 }, 3344 3345 setMenuSize: function (isAuto) { 3346 this.getSelectPosition(); 3347 3348 var selectWidth = this.sizeInfo.selectWidth, 3349 liHeight = this.sizeInfo.liHeight, 3350 headerHeight = this.sizeInfo.headerHeight, 3351 searchHeight = this.sizeInfo.searchHeight, 3352 actionsHeight = this.sizeInfo.actionsHeight, 3353 doneButtonHeight = this.sizeInfo.doneButtonHeight, 3354 divHeight = this.sizeInfo.dividerHeight, 3355 menuPadding = this.sizeInfo.menuPadding, 3356 menuInnerHeight, 3357 menuHeight, 3358 divLength = 0, 3359 minHeight, 3360 _minHeight, 3361 maxHeight, 3362 menuInnerMinHeight, 3363 estimate, 3364 isDropup; 3365 3366 if (this.options.dropupAuto) { 3367 // Get the estimated height of the menu without scrollbars. 3368 // This is useful for smaller menus, where there might be plenty of room 3369 // below the button without setting dropup, but we can't know 3370 // the exact height of the menu until createView is called later 3371 estimate = liHeight * this.selectpicker.current.data.length + menuPadding.vert; 3372 3373 isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot; 3374 3375 // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth) 3376 if (this.selectpicker.isSearching === true) { 3377 isDropup = this.selectpicker.dropup; 3378 } 3379 3380 this.$newElement.toggleClass(classNames.DROPUP, isDropup); 3381 this.selectpicker.dropup = isDropup; 3382 } 3383 3384 if (this.options.size === 'auto') { 3385 _minHeight = this.selectpicker.current.data.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0; 3386 menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert; 3387 minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; 3388 menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0); 3389 3390 if (this.$newElement.hasClass(classNames.DROPUP)) { 3391 menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert; 3392 } 3393 3394 maxHeight = menuHeight; 3395 menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert; 3396 } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { 3397 for (var i = 0; i < this.options.size; i++) { 3398 if (this.selectpicker.current.data[i].type === 'divider') divLength++; 3399 } 3400 3401 menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; 3402 menuInnerHeight = menuHeight - menuPadding.vert; 3403 maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; 3404 minHeight = menuInnerMinHeight = ''; 3405 } 3406 3407 this.$menu.css({ 3408 'max-height': maxHeight + 'px', 3409 'overflow': 'hidden', 3410 'min-height': minHeight + 'px' 3411 }); 3412 3413 this.$menuInner.css({ 3414 'max-height': menuInnerHeight + 'px', 3415 'overflow': 'hidden auto', 3416 'min-height': menuInnerMinHeight + 'px' 3417 }); 3418 3419 // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView 3420 this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1); 3421 3422 if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) { 3423 this.sizeInfo.hasScrollBar = true; 3424 this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth; 3425 } 3426 3427 if (this.options.dropdownAlignRight === 'auto') { 3428 this.$menu.toggleClass(classNames.MENURIGHT, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth)); 3429 } 3430 3431 if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update(); 3432 }, 3433 3434 setSize: function (refresh) { 3435 this.liHeight(refresh); 3436 3437 if (this.options.header) this.$menu.css('padding-top', 0); 3438 3439 if (this.options.size !== false) { 3440 var that = this, 3441 $window = $(window); 3442 3443 this.setMenuSize(); 3444 3445 if (this.options.liveSearch) { 3446 this.$searchbox 3447 .off('input.setMenuSize propertychange.setMenuSize') 3448 .on('input.setMenuSize propertychange.setMenuSize', function () { 3449 return that.setMenuSize(); 3450 }); 3451 } 3452 3453 if (this.options.size === 'auto') { 3454 $window 3455 .off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize') 3456 .on('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize', function () { 3457 return that.setMenuSize(); 3458 }); 3459 } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { 3460 $window.off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize'); 3461 } 3462 } 3463 3464 this.createView(false, true, refresh); 3465 }, 3466 3467 setWidth: function () { 3468 var that = this; 3469 3470 if (this.options.width === 'auto') { 3471 requestAnimationFrame(function () { 3472 that.$menu.css('min-width', '0'); 3473 3474 that.$element.on('loaded' + EVENT_KEY, function () { 3475 that.liHeight(); 3476 that.setMenuSize(); 3477 3478 // Get correct width if element is hidden 3479 var $selectClone = that.$newElement.clone().appendTo('body'), 3480 btnWidth = $selectClone.css('width', 'auto').children('button').outerWidth(); 3481 3482 $selectClone.remove(); 3483 3484 // Set width to whatever's larger, button title or longest option 3485 that.sizeInfo.selectWidth = Math.max(that.sizeInfo.totalMenuWidth, btnWidth); 3486 that.$newElement.css('width', that.sizeInfo.selectWidth + 'px'); 3487 }); 3488 }); 3489 } else if (this.options.width === 'fit') { 3490 // Remove inline min-width so width can be changed from 'auto' 3491 this.$menu.css('min-width', ''); 3492 this.$newElement.css('width', '').addClass('fit-width'); 3493 } else if (this.options.width) { 3494 // Remove inline min-width so width can be changed from 'auto' 3495 this.$menu.css('min-width', ''); 3496 this.$newElement.css('width', this.options.width); 3497 } else { 3498 // Remove inline min-width/width so width can be changed 3499 this.$menu.css('min-width', ''); 3500 this.$newElement.css('width', ''); 3501 } 3502 // Remove fit-width class if width is changed programmatically 3503 if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') { 3504 this.$newElement[0].classList.remove('fit-width'); 3505 } 3506 }, 3507 3508 selectPosition: function () {
3509 this.$bsContainer = $('<div class="bs-container" />'); 3510 3511 var that = this, 3512 $container = $(this.options.container), 3513 pos, 3514 containerPos, 3515 actualHeight, 3516 getPlacement = function ($element) { 3517 var containerPosition = {}, 3518 // fall back to dropdown's default display setting if display is not manually set 3519 display = that.options.display || ( 3520 // Bootstrap 3 doesn't have $.fn.dropdown.Constructor.Default 3521 $.fn.dropdown.Constructor.Default ? $.fn.dropdown.Constructor.Default.display 3522 : false 3523 ); 3524 3525 that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass(classNames.DROPUP, $element.hasClass(classNames.DROPUP)); 3526 pos = $element.offset(); 3527 3528 if (!$container.is('body')) { 3529 containerPos = $container.offset(); 3530 containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop(); 3531 containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft(); 3532 } else { 3533 containerPos = { top: 0, left: 0 }; 3534 } 3535 3536 actualHeight = $element.hasClass(classNames.DROPUP) ? 0 : $element[0].offsetHeight; 3537 3538 // Bootstrap 4+ uses Popper for menu positioning 3539 if (version.major < 4 || display === 'static') { 3540 containerPosition.top = pos.top - containerPos.top + actualHeight; 3541 containerPosition.left = pos.left - containerPos.left; 3542 } 3543 3544 containerPosition.width = $element[0].offsetWidth; 3545 3546 that.$bsContainer.css(containerPosition); 3547 }; 3548 3549 this.$button.on('click.bs.dropdown.data-api', function () { 3550 if (that.isDisabled()) { 3551 return; 3552 } 3553 3554 getPlacement(that.$newElement); 3555 3556 that.$bsContainer 3557 .appendTo(that.options.container) 3558 .toggleClass(classNames.SHOW, !that.$button.hasClass(classNames.SHOW)) 3559 .append(that.$menu); 3560 }); 3561 3562 $(window) 3563 .off('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId) 3564 .on('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId, function () { 3565 var isActive = that.$newElement.hasClass(classNames.SHOW); 3566 3567 if (isActive) getPlacement(that.$newElement); 3568 }); 3569 3570 this.$element.on('hide' + EVENT_KEY, function () { 3571 that.$menu.data('height', that.$menu.height()); 3572 that.$bsContainer.detach(); 3573 }); 3574 }, 3575 3576 createOption: function (data, init) { 3577 var optionData = !data.option ? data : data.option; 3578 3579 if (optionData && optionData.nodeType !== 1) { 3580 var option = (init ? elementTemplates.selectedOption : elementTemplates.option).cloneNode(true); 3581 if (optionData.value !== undefined) option.value = optionData.value; 3582 option.textContent = optionData.text; 3583 3584 option.selected = true; 3585 3586 if (optionData.liIndex !== undefined) { 3587 option.liIndex = optionData.liIndex; 3588 } else if (!init) { 3589 option.liIndex = data.index; 3590 } 3591 3592 data.option = option; 3593 3594 this.selectpicker.main.optionQueue.appendChild(option); 3595 } 3596 }, 3597 3598 setOptionStatus: function (selectedOnly) { 3599 var that = this; 3600 3601 that.noScroll = false; 3602 3603 if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) { 3604 for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) { 3605 var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0], 3606 option = liData.option; 3607 3608 if (option) { 3609 if (selectedOnly !== true) { 3610 that.setDisabled(liData); 3611 } 3612 3613 that.setSelected(liData); 3614 } 3615 } 3616 3617 // append optionQueue (documentFragment with option elements for select options) 3618 if (this.options.source.data) this.$element[0].appendChild(this.selectpicker.main.optionQueue); 3619 } 3620 }, 3621 3622 /** 3623 * @param {Object} liData - the option object that is being changed 3624 * @param {boolean} selected - true if the option is being selected, false if being deselected 3625 */ 3626 setSelected: function (liData, selected) { 3627 // console.log(liData); 3628 // console.log(selected); 3629 3630 selected = selected === undefined ? liData.selected : selected; 3631 3632 var li = liData.element, 3633 activeElementIsSet = this.activeElement !== undefined, 3634 thisIsActive = this.activeElement === li, 3635 prevActive, 3636 a, 3637 // if current option is already active 3638 // OR
3639 // if the current option is being selected, it's NOT multiple, and 3640 // activeElement is undefined: 3641 // - when the menu is first being opened, OR 3642 // - after a search has been performed, OR 3643 // - when retainActive is false when selecting a new option (i.e. index of the newly selected option is not the same as the current activeElement) 3644 keepActive = thisIsActive || (selected && !this.multiple && !activeElementIsSet); 3645 3646 if (!li) return; 3647 3648 if (selected !== undefined) { 3649 liData.selected = selected; 3650 if (liData.option) liData.option.selected = selected; 3651 } else if (selected == true) { 3652 // srSpeak("Selected"); 3653 } else if (selected == false) { 3654 // srSpeak("Unselected"); 3655 } 3656 3657 if (selected && this.options.source.data) { 3658 this.createOption(liData, false); 3659 } 3660 3661 a = li.firstChild; 3662 3663 if (selected) { 3664 this.selectedElement = li; 3665 } 3666 3667 li.classList.toggle('selected', selected); 3668 3669 if (selected) { 3670 li.setAttribute('aria-selected', true); 3671 } else { 3672 if (this.multiple) { 3673 li.setAttribute('aria-selected', false); 3674 } else { 3675 li.removeAttribute('aria-selected'); 3676 } 3677 } 3678 3679 if (keepActive) { 3680 this.focusItem(li, liData); 3681 this.selectpicker.view.currentActive = li; 3682 this.activeElement = li; 3683 } else { 3684 this.defocusItem(li); 3685 } 3686 3687 // TODO remove <a> 3688 if (a) { 3689 a.classList.toggle('selected', selected); 3690 } 3691 3692 if (!keepActive && !activeElementIsSet && selected && this.prevActiveElement !== undefined) { 3693 prevActive = this.prevActiveElement; 3694 3695 this.defocusItem(prevActive); 3696 } 3697 }, 3698 3699 /** 3700 * @param {number} index - the index of the option that is being disabled 3701 * @param {boolean} disabled - true if the option is being disabled, false if being enabled 3702 */ 3703 setDisabled: function (liData) { 3704 var disabled = liData.disabled, 3705 li = liData.element, 3706 a; 3707 3708 if (!li) return; 3709 3710 a = li.firstChild; 3711 3712 li.classList.toggle(classNames.DISABLED, disabled); 3713 3714 if (a) { 3715 if (version.major >= '4') a.classList.toggle(classNames.DISABLED, disabled); 3716 3717 if (disabled) { 3718 a.setAttribute('aria-disabled', disabled); 3719 // a.setAttribute('tabindex', -1); 3720 } else { 3721 a.removeAttribute('aria-disabled'); 3722 // no need to have options in tab index 3723 // a.setAttribute('tabindex', 0); 3724 } 3725 } 3726 }, 3727 3728 isDisabled: function () { 3729 return this.$element[0].disabled; 3730 }, 3731 3732 checkDisabled: function () { 3733 if (this.isDisabled()) { 3734 this.$newElement[0].classList.add(classNames.DISABLED); 3735 this.$button.addClass(classNames.DISABLED).attr('aria-disabled', true); 3736 } else { 3737 if (this.$button[0].classList.contains(classNames.DISABLED)) { 3738 this.$newElement[0].classList.remove(classNames.DISABLED); 3739 this.$button.removeClass(classNames.DISABLED).attr('aria-disabled', false); 3740 } 3741 } 3742 }, 3743 3744 clickListener: function () { 3745 var that = this, 3746 $document = $(document); 3747 3748 $document.data('spaceSelect', false); 3749 3750 this.$button.on('keyup', function (e) { 3751 if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) { 3752 e.preventDefault(); 3753 $document.data('spaceSelect', false); 3754 } 3755 }); 3756 3757 this.$newElement.on('show.bs.dropdown', function () { 3758 if (!that.dropdown && version.major === '4') { 3759 that.dropdown = that.$button.data('bs.dropdown'); 3760 that.dropdown._menu = that.$menu[0]; 3761 } 3762 }); 3763 3764 function clearSelection (e) { 3765 if (that.multiple) { 3766 that.deselectAll(); 3767 } else { 3768 var element = that.$element[0], 3769 prevValue = element.value, 3770 prevIndex = element.selectedIndex, 3771 prevOption = element.options[prevIndex], 3772 prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false;
3773 3774 if (prevData) { 3775 that.setSelected(prevData, false); 3776 } 3777 3778 element.selectedIndex = 0; 3779 3780 changedArguments = [prevIndex, false, prevValue]; 3781 that.$element.triggerNative('change'); 3782 } 3783 3784 // remove selected styling if menu is open 3785 if (that.$newElement.hasClass(classNames.SHOW)) { 3786 if (that.options.liveSearch) { 3787 that.$searchbox.trigger('focus'); 3788 } 3789 3790 that.createView(false); 3791 } 3792 } 3793 3794 this.$button.on('click.bs.dropdown.data-api', function (e) { 3795 if (that.options.allowClear) { 3796 var target = e.target, 3797 clearButton = that.$clearButton[0]; 3798 3799 // IE doesn't support event listeners on child elements of buttons 3800 if (/MSIE|Trident/.test(window.navigator.userAgent)) { 3801 target = document.elementFromPoint(e.clientX, e.clientY); 3802 } 3803 3804 if (target === clearButton || target.parentElement === clearButton) { 3805 e.stopImmediatePropagation(); 3806 clearSelection(e); 3807 } 3808 } 3809 3810 if (!that.$newElement.hasClass(classNames.SHOW)) { 3811 that.setSize(); 3812 } 3813 }); 3814 3815 function setFocus () { 3816 if (that.options.liveSearch) { 3817 that.$searchbox.trigger('focus'); 3818 } else { 3819 that.$menuInner.trigger('focus'); 3820 } 3821 } 3822 3823 function checkPopperExists () { 3824 if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state) { 3825 setFocus(); 3826 } else { 3827 requestAnimationFrame(checkPopperExists); 3828 } 3829 } 3830 3831 this.$element.on('shown' + EVENT_KEY, function () { 3832 if (that.$menuInner[0].scrollTop !== that.selectpicker.view.scrollTop) { 3833 that.$menuInner[0].scrollTop = that.selectpicker.view.scrollTop; 3834 } 3835 3836 if (version.major > 3) { 3837 requestAnimationFrame(checkPopperExists); 3838 } else { 3839 setFocus(); 3840 } 3841 }); 3842 3843 // ensure posinset and setsize are correct before selecting an option via a click 3844 this.$menuInner.on('mouseenter', 'li .dropdown-item', function (e) { 3845 var hoverLi = this.parentElement, 3846 position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, 3847 index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi), 3848 hoverData = that.selectpicker.current.data[index + position0]; 3849 3850 that.focusItem(hoverLi, hoverData, true); 3851 }); 3852 3853 this.$menuInner.on('click', 'li .dropdown-item', function (e, retainActive) { 3854 var $this = $(this), 3855 element = that.$element[0], 3856 position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, 3857 // $items = that.findLis(), 3858 $parent = $this.parent(), 3859 // clickedIndex = $items.index($parent), 3860 clickedIndex = Number($parent.attr('data-index')), 3861 clickedData = that.selectpicker.current.data[clickedIndex + position0], 3862 clickedElement = clickedData.element, 3863 prevValue = getSelectValues.call(that), 3864 prevIndex = element.selectedIndex, 3865 prevOption = element.options[prevIndex], 3866 prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false, 3867 triggerChange = true; 3868 3869 // console.log('that.selectpicker.main.data', that.selectpicker.main.data); 3870 3871 // Don't close on multi choice menu 3872 if (that.multiple && that.options.maxOptions !== 1) { 3873 e.stopPropagation(); 3874 } 3875 3876 e.preventDefault(); 3877 3878 // Don't run if the select is disabled 3879 if (!that.isDisabled() && !$this.parent().hasClass(classNames.DISABLED)) { 3880 var option = clickedData.option, 3881 $option = $(option), 3882 state = option.selected, 3883 optgroupData = that.selectpicker.current.data.find(function (datum) { 3884 return datum.optID === clickedData.optID && datum.type === 'optgroup-label'; 3885 }), 3886 optgroup = optgroupData ? optgroupData.optgroup : undefined, 3887 dataGetter = optgroup instanceof Element ? getOptionData.fromOption : getOptionData.fromDataSource, 3888 optgroupOptions = optgroup && optgroup.children, 3889 maxOptions = parseInt(that.options.maxOptions), 3890 maxOptionsGrp = optgroup && parseInt(dataGetter(optgroup, 'maxOptions')) || false; 3891 3892 if (clickedElement === that.activeElement) retainActive = true; 3893 3894 if (!retainActive) { 3895 that.prevActiveElement = that.activeElement; 3896 that.activeElement = undefined; 3897 } 3898 3899 if (!that.multiple || maxOptions === 1) { // Deselect previous option if not multi select 3900 if (prevData) that.setSelected(prevData, false); 3901 that.setSelected(clickedData, true); 3902 } else { // Toggle the clicked option if multi select. 3903 that.setSelected(clickedData, !state); 3904 that.focusedParent.focus(); 3905 3906 if (maxOptions !== false || maxOptionsGrp !== false) { 3907 var maxReached = maxOptions < getSelectedOptions.call(that).length, 3908 selectedGroupOptions = 0; 3909 3910 if (optgroup && optgroup.children) { 3911 for (var i = 0; i < optgroup.children.length; i++) { 3912 if (optgroup.children[i].selected) selectedGroupOptions++; 3913 } 3914 } 3915 3916 var maxReachedGrp = maxOptionsGrp < selectedGroupOptions; 3917 3918 if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { 3919 if (maxOptions && maxOptions === 1) { 3920 element.selectedIndex = -1; 3921 that.setOptionStatus(true); 3922 } else if (maxOptionsGrp && maxOptionsGrp === 1) { 3923 for (var i = 0; i < optgroupOptions.length; i++) { 3924 var _option = optgroupOptions[i]; 3925 that.setSelected(that.selectpicker.current.data[_option.liIndex], false); 3926 } 3927 3928 that.setSelected(clickedData, true); 3929 } else { 3930 var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, 3931 maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, 3932 maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), 3933 maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), 3934 $notify = $('<div class="notify"></div>'); 3935 // If {var} is set in array, replace it 3936 /** @deprecated */ 3937 if (maxOptionsArr[2]) { 3938 maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]); 3939 maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]); 3940 } 3941 3942 that.$menu.append($notify); 3943 3944 if (maxOptions && maxReached) { 3945 $notify.append($('<div>' + maxTxt + '</div>')); 3946 triggerChange = false;
vendor: 6,946 bytes, lines 3947-4137
3947 that.$element.trigger('maxReached' + EVENT_KEY); 3948 } 3949 3950 if (maxOptionsGrp && maxReachedGrp) { 3951 $notify.append($('<div>' + maxTxtGrp + '</div>')); 3952 triggerChange = false; 3953 that.$element.trigger('maxReachedGrp' + EVENT_KEY); 3954 } 3955 3956 setTimeout(function () { 3957 that.setSelected(clickedData, false); 3958 }, 10); 3959 3960 $notify[0].classList.add('fadeOut'); 3961 3962 setTimeout(function () { 3963 $notify.remove(); 3964 }, 1050); 3965 } 3966 } 3967 } 3968 } 3969 3970 if (that.options.source.data) that.$element[0].appendChild(that.selectpicker.main.optionQueue); 3971 3972 if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { 3973 that.$button.trigger('focus'); 3974 } else if (that.options.liveSearch) { 3975 that.$searchbox.trigger('focus'); 3976 } 3977 3978 // Trigger select 'change' 3979 if (triggerChange) { 3980 if (that.multiple || prevIndex !== element.selectedIndex) { 3981 // $option.prop('selected') is current option state (selected/unselected). prevValue is the value of the select prior to being changed. 3982 changedArguments = [option.index, $option.prop('selected'), prevValue]; 3983 that.$element 3984 .triggerNative('change'); 3985 } 3986 } 3987 } 3988 }); 3989 3990 this.$menu.on('click', 'li.' + classNames.DISABLED + ' .dropdown-item, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.close)', function (e) { 3991 if (e.currentTarget == this) { 3992 e.preventDefault(); 3993 e.stopPropagation(); 3994 if (that.options.liveSearch && !$(e.target).hasClass('close')) { 3995 that.$searchbox.trigger('focus'); 3996 } else { 3997 that.$button.trigger('focus'); 3998 } 3999 } 4000 }); 4001 4002 this.$menuInner.on('click', '.divider, .dropdown-header', function (e) { 4003 e.preventDefault(); 4004 e.stopPropagation(); 4005 if (that.options.liveSearch) { 4006 that.$searchbox.trigger('focus'); 4007 } else { 4008 that.$button.trigger('focus'); 4009 } 4010 }); 4011 4012 this.$menu.on('click', '.' + classNames.POPOVERHEADER + ' .close', function () { 4013 that.$button.trigger('click'); 4014 }); 4015 4016 this.$searchbox.on('click', function (e) { 4017 e.stopPropagation(); 4018 }); 4019 4020 this.$menu.on('click', '.actions-btn', function (e) { 4021 if (that.options.liveSearch) { 4022 that.$searchbox.trigger('focus'); 4023 } else { 4024 that.$button.trigger('focus'); 4025 } 4026 4027 e.preventDefault(); 4028 e.stopPropagation(); 4029 4030 if ($(this).hasClass('bs-select-all')) { 4031 that.selectAll(); 4032 } else { 4033 that.deselectAll(); 4034 } 4035 }); 4036 4037 // this.$button 4038 // .on('focus' + EVENT_KEY, function (e) { 4039 // var tabindex = that.$element[0].getAttribute('tabindex'); 4040 // // only change when button is actually focused 4041 // if (tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { 4042 // // removing this NL 4043 // // apply select element's tabindex to ensure correct order is followed when tabbing to the next element 4044 // // this.setAttribute('tabindex', tabindex); 4045 // // set element's tabindex to -1 to allow for reverse tabbing 4046 // // removing this NL 4047 // // that.$element[0].setAttribute('tabindex', -1); 4048 // // that.selectpicker.view.tabindex = tabindex; 4049 // } 4050 // }) 4051 // .on('blur' + EVENT_KEY, function (e) { 4052 // // removing this NL 4053 // // revert everything to original tabindex 4054 // // if (that.selectpicker.view.tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { 4055 // // that.$element[0].setAttribute('tabindex', that.selectpicker.view.tabindex); 4056 // // this.setAttribute('tabindex', -1); 4057 // // that.selectpicker.view.tabindex = undefined; 4058 // // } 4059 // }); 4060 4061 this.$element 4062 .on('change' + EVENT_KEY, function () { 4063 that.render(); 4064 that.$element.trigger('changed' + EVENT_KEY, changedArguments); 4065 changedArguments = null; 4066 }) 4067 .on('focus' + EVENT_KEY, function () { 4068 if (!that.options.mobile) that.$button[0].focus(); 4069 }); 4070 }, 4071 4072 liveSearchListener: function () { 4073 var that = this; 4074 4075 this.$button.on('click.bs.dropdown.data-api', function () { 4076 if (!!that.$searchbox.val()) { 4077 that.$searchbox.val(''); 4078 that.selectpicker.search.previousValue = undefined; 4079 } 4080 }); 4081 4082 this.$searchbox.on('click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api', function (e) { 4083 e.stopPropagation(); 4084 }); 4085 4086 this.$searchbox.on('input propertychange', function () { 4087 var searchValue = that.$searchbox[0].value; 4088 4089 that.selectpicker.search.elements = []; 4090 that.selectpicker.search.data = []; 4091 4092 if (searchValue) { 4093 that.selectpicker.search.previousValue = searchValue; 4094 4095 if (that.options.source.search) { 4096 that.fetchData(function (builtData) { 4097 that.render(); 4098 that.buildList(undefined, true); 4099 that.noScroll = true; 4100 that.$menuInner.scrollTop(0); 4101 that.createView(true); 4102 showNoResults.call(that, builtData, searchValue); 4103 }, 'search', 0, searchValue); 4104 } else { 4105 var i, 4106 searchMatch = [], 4107 q = searchValue.toUpperCase(), 4108 cache = {}, 4109 cacheArr = [], 4110 searchStyle = that._searchStyle(), 4111 normalizeSearch = that.options.liveSearchNormalize; 4112 4113 if (normalizeSearch) q = normalizeToBase(q); 4114 4115 for (var i = 0; i < that.selectpicker.main.data.length; i++) { 4116 var li = that.selectpicker.main.data[i]; 4117 4118 if (!cache[i]) { 4119 cache[i] = stringSearch(li, q, searchStyle, normalizeSearch); 4120 } 4121 4122 if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) { 4123 if (li.headerIndex > 0) { 4124 cache[li.headerIndex - 1] = true; 4125 cacheArr.push(li.headerIndex - 1); 4126 } 4127 4128 cache[li.headerIndex] = true; 4129 cacheArr.push(li.headerIndex); 4130 4131 cache[li.lastIndex + 1] = true; 4132 } 4133 4134 if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i); 4135 } 4136 4137 for (var i = 0, cacheLen = cacheArr.length; i < cacheLen; i++) {
4138 var index = cacheArr[i], 4139 prevIndex = cacheArr[i - 1], 4140 li = that.selectpicker.main.data[index], 4141 liPrev = that.selectpicker.main.data[prevIndex]; 4142 4143 if (li.type !== 'divider' || (li.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== i)) { 4144 that.selectpicker.search.data.push(li); 4145 searchMatch.push(that.selectpicker.main.elements[index]); 4146 } 4147 } 4148 4149 that.activeElement = undefined; 4150 that.noScroll = true; 4151 that.$menuInner.scrollTop(0); 4152 that.selectpicker.search.elements = searchMatch; 4153 that.createView(true); 4154 showNoResults.call(that, searchMatch, searchValue); 4155 } 4156 } else if (that.selectpicker.search.previousValue) { // for IE11 (#2402) 4157 that.$menuInner.scrollTop(0); 4158 that.createView(false); 4159 } 4160 }); 4161 }, 4162 4163 _searchStyle: function () { 4164 return this.options.liveSearchStyle || 'contains'; 4165 }, 4166 4167 val: function (value) { 4168 var element = this.$element[0]; 4169 4170 if (typeof value !== 'undefined') { 4171 var selectedOptions = getSelectedOptions.call(this), 4172 prevValue = getSelectValues.call(this, selectedOptions); 4173 4174 changedArguments = [null, null, prevValue]; 4175 4176 if (!Array.isArray(value)) value = [ value ]; 4177 4178 value.map(String); 4179 4180 for (var i = 0; i < selectedOptions.length; i++) { 4181 var item = selectedOptions[i]; 4182 4183 if (item && value.indexOf(String(item.value)) === -1) { 4184 this.setSelected(item, false); 4185 } 4186 } 4187 4188 // only update selected value if it matches an existing option 4189 this.selectpicker.main.data.filter(function (item) { 4190 if (value.indexOf(String(item.value)) !== -1) { 4191 this.setSelected(item, true); 4192 return true; 4193 } 4194 4195 return false; 4196 }, this); 4197 4198 if (this.options.source.data) element.appendChild(this.selectpicker.main.optionQueue); 4199 4200 this.$element.trigger('changed' + EVENT_KEY, changedArguments); 4201 4202 if (this.$newElement.hasClass(classNames.SHOW)) { 4203 if (this.multiple) { 4204 this.setOptionStatus(true); 4205 } else { 4206 var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex; 4207 4208 if (typeof liSelectedIndex === 'number') { 4209 this.setSelected(this.selectpicker.current.data[liSelectedIndex], true); 4210 } 4211 } 4212 } 4213 4214 this.render(); 4215 4216 changedArguments = null; 4217 4218 return this.$element; 4219 } else { 4220 return this.$element.val(); 4221 } 4222 }, 4223 4224 changeAll: function (status) { 4225 if (!this.multiple) return; 4226 if (typeof status === 'undefined') status = true; 4227 4228 var element = this.$element[0], 4229 previousSelected = 0, 4230 currentSelected = 0, 4231 prevValue = getSelectValues.call(this); 4232 4233 element.classList.add('bs-select-hidden'); 4234 4235 for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) { 4236 var liData = data[i], 4237 option = liData.option; 4238 4239 if (option && !liData.disabled && liData.type !== 'divider') { 4240 if (liData.selected) previousSelected++; 4241 option.selected = status; 4242 liData.selected = status; 4243 if (status === true) currentSelected++; 4244 } 4245 } 4246 4247 element.classList.remove('bs-select-hidden'); 4248 4249 if (previousSelected === currentSelected) return; 4250 4251 this.setOptionStatus(); 4252 4253 changedArguments = [null, null, prevValue]; 4254 4255 this.$element 4256 .triggerNative('change'); 4257 }, 4258 4259 selectAll: function () { 4260 return this.changeAll(true); 4261 }, 4262 4263 deselectAll: function () { 4264 return this.changeAll(false); 4265 }, 4266 4267 toggle: function (e, state) { 4268 var isActive, 4269 triggerClick = state === undefined; 4270 4271 e = e || window.event; 4272 4273 if (e) e.stopPropagation(); 4274 4275 if (triggerClick === false) { 4276 isActive = this.$newElement[0].classList.contains(classNames.SHOW); 4277 triggerClick = state === true && isActive === false || state === false && isActive === true; 4278 } 4279 4280 if (triggerClick) this.$button.trigger('click.bs.dropdown.data-api'); 4281 }, 4282 4283 open: function (e) { 4284 this.toggle(e, true); 4285 }, 4286 4287 close: function (e) { 4288 this.toggle(e, false); 4289 }, 4290 4291 keydown: function (e) { 4292 var $this = $(this), 4293 isToggle = $this.hasClass('dropdown-toggle'), 4294 $parent = isToggle ? $this.closest('.dropdown') : $this.closest(Selector.MENU), 4295 that = $parent.data('this'), 4296 $items = that.findLis(), 4297 index, 4298 isActive, 4299 liActive, 4300 activeLi, 4301 offset, 4302 updateScroll = false, 4303 downOnTab = e.which === keyCodes.TAB && !isToggle && !that.options.selectOnTab, 4304 isArrowKey = REGEXP_ARROW.test(e.which) || downOnTab, 4305 scrollTop = that.$menuInner[0].scrollTop, 4306 isVirtual = that.isVirtual(), 4307 position0 = isVirtual === true ? that.selectpicker.view.position0 : 0; 4308 4309 // do nothing if a function key is pressed 4310 if (e.which >= 112 && e.which <= 123) return; 4311 4312 isActive = that.$menu.hasClass(classNames.SHOW); 4313 4314 if ( 4315 !isActive && 4316 ( 4317 isArrowKey || 4318 (e.which >= 48 && e.which <= 57) || 4319 (e.which >= 96 && e.which <= 105) || 4320 (e.which >= 65 && e.which <= 90) ||
4321 e.which === keyCodes.SPACE || 4322 e.which === keyCodes.ENTER 4323 ) 4324 ) { 4325 that.$button.trigger('click.bs.dropdown.data-api'); 4326 4327 if (that.options.liveSearch) { 4328 that.$searchbox.trigger('focus'); 4329 return; 4330 } 4331 } 4332 4333 if (e.which === keyCodes.ESCAPE && isActive) { 4334 e.preventDefault(); 4335 that.$button.trigger('click.bs.dropdown.data-api').trigger('focus'); 4336 } 4337 4338 // if the dropdown wasn't active, activte the first item when pushing space, enter or "down" 4339 if ( 4340 !isActive && 4341 ( 4342 e.which === keyCodes.SPACE || 4343 e.which === keyCodes.ENTER || 4344 e.which === keyCodes.ARROW_DOWN 4345 ) 4346 ) { 4347 liActive = that.selectpicker.current.elements[0]; 4348 4349 that.focusItem(liActive); 4350 } 4351 4352 if (isArrowKey) { // if up or down, enter or space 4353 // if (!$items.length) return; 4354 $items = that.findLis(); 4355 4356 liActive = that.activeElement; 4357 // index = liActive ? Array.prototype.indexOf.call($items, liActive) : -1; 4358 // index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1; 4359 index = liActive ? $items.index(liActive) : -1; 4360 // var index = liActive ? Number(liActive.getAttribute('data-index')) : -1; 4361 4362 if (index !== -1) { 4363 that.defocusItem(liActive); 4364 } 4365 4366 if (e.which === keyCodes.ARROW_UP) { // up 4367 if (index !== -1) { 4368 index--; 4369 } 4370 // if (index + position0 < 0) index += $items.length; 4371 if (index + position0 < 0) index += $items.length; // that.selectpicker.current.data.length; 4372 4373 // console.log(index); 4374 // console.log($items); 4375 // console.log('$items.length', $items.length); 4376 4377 if (!that.selectpicker.view.canHighlight[index + position0]) { 4378 index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0; 4379 if (index === -1) { 4380 index = $items.length - 1; 4381 }; 4382 } 4383 } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down 4384 index++; 4385 if (index + position0 >= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex; 4386 4387 if (!that.selectpicker.view.canHighlight[index + position0]) { 4388 index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true); 4389 } 4390 } 4391 4392 e.preventDefault(); 4393 4394 var liActiveIndex = position0 + index; 4395 if (e.which === keyCodes.ARROW_UP) { // up 4396 // scroll to bottom and highlight last option 4397 if (position0 === 0 && index === $items.length - 1) { 4398 // if (position0 === 0 && index === $items.length - 1) { 4399 that.$menuInner[0].scrollTop = that.$menuInner[0].scrollHeight; 4400 4401 liActiveIndex = that.selectpicker.current.elements.length - 1; 4402 } else { 4403 activeLi = that.selectpicker.current.data[liActiveIndex]; 4404 4405 // could be undefined if no results exist 4406 if (activeLi) { 4407 offset = activeLi.position - activeLi.height; 4408 4409 updateScroll = offset < scrollTop; 4410 } 4411 } 4412 } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down 4413 // scroll to top and highlight first option 4414 if (index === that.selectpicker.view.firstHighlightIndex) { 4415 that.$menuInner[0].scrollTop = 0; 4416 4417 liActiveIndex = that.selectpicker.view.firstHighlightIndex; 4418 } else { 4419 activeLi = that.selectpicker.current.data[liActiveIndex]; 4420 4421 // could be undefined if no results exist 4422 if (activeLi) { 4423 offset = activeLi.position - that.sizeInfo.menuInnerHeight; 4424 4425 updateScroll = offset > scrollTop; 4426 } 4427 } 4428 } 4429 4430 liActive = that.selectpicker.current.elements[liActiveIndex]; 4431 4432 that.activeElement = (that.selectpicker.current.data[liActiveIndex] || {}).element; 4433 4434 that.focusItem(liActive); 4435 4436 that.selectpicker.view.currentActive = liActive; 4437 4438 if (updateScroll) that.$menuInner[0].scrollTop = offset; 4439 4440 if (that.options.liveSearch) { 4441 that.$searchbox.trigger('focus'); 4442 } else { 4443 $this.trigger('focus'); 4444 } 4445 } else if ( 4446 (!$this.is('input') && !REGEXP_TAB_OR_ESCAPE.test(e.which)) || 4447 (e.which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory) 4448 ) { 4449 var searchMatch, 4450 matches = [], 4451 keyHistory; 4452 4453 e.preventDefault(); 4454 4455 that.selectpicker.keydown.keyHistory += keyCodeMap[e.which]; 4456 4457 if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel); 4458 that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start(); 4459 4460 keyHistory = that.selectpicker.keydown.keyHistory; 4461 4462 // if all letters are the same, set keyHistory to just the first character when searching
4463 if (/^(.)\1+$/.test(keyHistory)) { 4464 keyHistory = keyHistory.charAt(0); 4465 } 4466 4467 // find matches 4468 for (var i = 0; i < that.selectpicker.current.data.length; i++) { 4469 var li = that.selectpicker.current.data[i], 4470 hasMatch; 4471 4472 hasMatch = stringSearch(li, keyHistory, 'startsWith', true); 4473 4474 if (hasMatch && that.selectpicker.view.canHighlight[i]) { 4475 matches.push(li.element); 4476 } 4477 } 4478 4479 if (matches.length) { 4480 var matchIndex = 0; 4481 4482 // TODO remove a 4483 $items.removeClass('active').find('dropdown-item').removeClass('active'); 4484 4485 // either only one key has been pressed or they are all the same key 4486 if (keyHistory.length === 1) { 4487 matchIndex = matches.indexOf(that.activeElement); 4488 4489 if (matchIndex === -1 || matchIndex === matches.length - 1) { 4490 matchIndex = 0; 4491 } else { 4492 matchIndex++; 4493 } 4494 } 4495 4496 searchMatch = matches[matchIndex]; 4497 4498 activeLi = that.selectpicker.main.data[searchMatch]; 4499 4500 if (scrollTop - activeLi.position > 0) { 4501 offset = activeLi.position - activeLi.height; 4502 updateScroll = true; 4503 } else { 4504 offset = activeLi.position - that.sizeInfo.menuInnerHeight; 4505 // if the option is already visible at the current scroll position, just keep it the same 4506 updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight; 4507 } 4508 4509 liActive = that.selectpicker.main.elements[searchMatch]; 4510 4511 that.activeElement = liActive; 4512 4513 that.focusItem(liActive); 4514 4515 if (liActive) liActive.firstChild.focus(); 4516 4517 if (updateScroll) that.$menuInner[0].scrollTop = offset; 4518 4519 $this.trigger('focus'); 4520 } 4521 } 4522 4523 // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. 4524 // console.log('!that.selectpicker.keydown.keyHistory', !that.selectpicker.keydown.keyHistory); 4525 // console.log('keyCodes.SPACE?', e.which === keyCodes.SPACE); 4526 // console.log('keyCodes', e.which); 4527 if ( 4528 isActive && 4529 ( 4530 e.which === keyCodes.SPACE || 4531 e.which === keyCodes.ENTER || 4532 (e.which === keyCodes.TAB && that.options.selectOnTab) 4533 ) 4534 ) { 4535 // if (e.which !== keyCodes.SPACE) e.preventDefault(); 4536 // console.log(e.which); 4537 // on click of Enter of Space, activate that dropdown item. 4538 if (!that.options.liveSearch && (e.which === keyCodes.ENTER || e.which == keyCodes.SPACE)) { 4539 // console.log('clicked!'); 4540 that.$menuInner.find('.active .dropdown-item').trigger('click', true); // retain active class 4541 $this.trigger('focus'); 4542 4543 if (!that.options.liveSearch) { 4544 // Prevent screen from scrolling if the user hits the spacebar 4545 e.preventDefault(); 4546 // Fixes spacebar selection of dropdown items in FF & IE 4547 $(document).data('spaceSelect', true); 4548 } 4549 } 4550 } 4551 }, 4552 4553 mobile: function () { 4554 // ensure mobile is set to true if mobile function is called after init 4555 this.options.mobile = true; 4556 this.$element[0].classList.add('mobile-device'); 4557 }, 4558 4559 refresh: function () { 4560 var that = this; 4561 // activeElement = that.activeElement; 4562 var activeElementIndex = this.selectpicker.current.elements.indexOf(this.activeElement); 4563 // var activeElementIndex = this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)] 4564 // update options if data attributes have been changed 4565 var config = $.extend({}, this.options, getAttributesObject(this.$element), this.$element.data()); // in this order on refresh, as user may change attributes on select, and options object is not passed on refresh 4566 this.options = config; 4567 4568 if (this.options.source.data) { 4569 this.render(); 4570 this.buildList(); 4571 } else { 4572 this.fetchData(function () { 4573 that.render(); 4574 that.buildList(); 4575 }); 4576 } 4577 4578 this.checkDisabled(); 4579 4580 this.setStyle(); 4581 this.setWidth(); 4582 4583 this.setSize(true); 4584 4585 this.$element.trigger('refreshed' + EVENT_KEY); 4586 4587 // refocus the element with focus after a refresh 4588 if (activeElementIndex !== -1) { 4589 var li = this.selectpicker.current.data[activeElementIndex].element; 4590 var liData = this.selectpicker.current.data[activeElementIndex]; 4591 this.focusItem(li, liData); 4592 this.selectpicker.view.currentActive = li; 4593 this.activeElement = li; 4594 } 4595 }, 4596 4597 hide: function () { 4598 this.$newElement.hide(); 4599 }, 4600 4601 show: function () { 4602 this.$newElement.show(); 4603 }, 4604 4605 remove: function () { 4606 this.$newElement.remove(); 4607 this.$element.remove(); 4608 }, 4609 4610 destroy: function () { 4611 this.$newElement.before(this.$element).remove(); 4612 4613 if (this.$bsContainer) { 4614 this.$bsContainer.remove(); 4615 } else { 4616 this.$menu.remove(); 4617 } 4618 4619 if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) { 4620 this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption); 4621 } 4622 4623 this.$element 4624 .off(EVENT_KEY) 4625 .removeData('selectpicker') 4626 .removeClass('bs-select-hidden selectpicker mobile-device'); 4627 4628 $(window).off(EVENT_KEY + '.' + this.selectId); 4629 } 4630 }; 4631 4632 // SELECTPICKER PLUGIN DEFINITION 4633 // ============================== 4634 function Plugin (option) { 4635 // get the args of the outer function.. 4636 var args = arguments; 4637 // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
4638 // to get lost/corrupted in android 2.3 and IE9 #715 #775 4639 var _option = option; 4640 4641 [].shift.apply(args); 4642 4643 // if the version was not set successfully 4644 if (!version.success) { 4645 // try to retreive it again 4646 try { 4647 version.full = (getVersion() || '').split(' ')[0].split('.'); 4648 } catch (err) { 4649 // fall back to use BootstrapVersion if set 4650 if (Selectpicker.BootstrapVersion) { 4651 version.full = Selectpicker.BootstrapVersion.split(' ')[0].split('.'); 4652 } else { 4653 version.full = [version.major, '0', '0']; 4654 4655 console.warn( 4656 'There was an issue retrieving Bootstrap\'s version. ' + 4657 'Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. ' + 4658 'If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.', 4659 err 4660 ); 4661 } 4662 } 4663 4664 version.major = version.full[0]; 4665 version.success = true; 4666 } 4667 4668 if (version.major >= '4') { 4669 // some defaults need to be changed if using Bootstrap 4 4670 // check to see if they have already been manually changed before forcing them to update 4671 var toUpdate = []; 4672 4673 if (Selectpicker.DEFAULTS.style === classNames.BUTTONCLASS) toUpdate.push({ name: 'style', className: 'BUTTONCLASS' }); 4674 if (Selectpicker.DEFAULTS.iconBase === classNames.ICONBASE) toUpdate.push({ name: 'iconBase', className: 'ICONBASE' }); 4675 if (Selectpicker.DEFAULTS.tickIcon === classNames.TICKICON) toUpdate.push({ name: 'tickIcon', className: 'TICKICON' }); 4676 4677 classNames.DIVIDER = 'dropdown-divider'; 4678 classNames.SHOW = 'show'; 4679 classNames.BUTTONCLASS = 'btn-light'; 4680 classNames.POPOVERHEADER = 'popover-header'; 4681 classNames.ICONBASE = ''; 4682 classNames.TICKICON = 'bs-ok-default'; 4683 4684 for (var i = 0; i < toUpdate.length; i++) { 4685 var option = toUpdate[i]; 4686 Selectpicker.DEFAULTS[option.name] = classNames[option.className]; 4687 } 4688 } 4689 4690 if (version.major > '4') { 4691 Selector.DATA_TOGGLE = 'data-bs-toggle="dropdown"'; 4692 } 4693 4694 var value; 4695 var chain = this.each(function () { 4696 var $this = $(this); 4697 if ($this.is('select')) { 4698 var data = $this.data('selectpicker'), 4699 options = typeof _option == 'object' && _option; 4700 4701 // for backwards compatibility 4702 // (using title as placeholder is deprecated - remove in v2.0.0) 4703 if (options.title) options.placeholder = options.title; 4704 4705 if (!data) { 4706 var dataAttributes = $this.data(); 4707 4708 for (var dataAttr in dataAttributes) { 4709 if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { 4710 delete dataAttributes[dataAttr]; 4711 } 4712 } 4713 4714 var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, getAttributesObject($this), dataAttributes, options); // this is correct order on initial render 4715 config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), dataAttributes.template, options.template); 4716 config.source = $.extend({}, Selectpicker.DEFAULTS.source, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.source : {}), options.source); 4717 $this.data('selectpicker', (data = new Selectpicker(this, config))); 4718 } else if (options) { 4719 for (var i in options) { 4720 if (Object.prototype.hasOwnProperty.call(options, i)) { 4721 data.options[i] = options[i]; 4722 } 4723 } 4724 } 4725 4726 if (typeof _option == 'string') { 4727 if (data[_option] instanceof Function) { 4728 value = data[_option].apply(data, args); 4729 } else { 4730 value = data.options[_option]; 4731 } 4732 } 4733 } 4734 }); 4735 4736 if (typeof value !== 'undefined') { 4737 // noinspection JSUnusedAssignment 4738 return value; 4739 } else { 4740 return chain; 4741 } 4742 } 4743 4744 var old = $.fn.selectpicker; 4745 $.fn.selectpicker = Plugin; 4746 $.fn.selectpicker.Constructor = Selectpicker; 4747 4748 // SELECTPICKER NO CONFLICT 4749 // ======================== 4750 $.fn.selectpicker.noConflict = function () { 4751 $.fn.selectpicker = old; 4752 return this; 4753 }; 4754 4755 // get Bootstrap's keydown event handler for either Bootstrap 4 or Bootstrap 3 4756 function keydownHandler () { 4757 if (version.major < 5) { 4758 if ($.fn.dropdown) {
4759 // wait to define until function is called in case Bootstrap isn't loaded yet 4760 var bootstrapKeydown = $.fn.dropdown.Constructor._dataApiKeydownHandler || $.fn.dropdown.Constructor.prototype.keydown; 4761 return bootstrapKeydown.apply(this, arguments); 4762 } 4763 } else { 4764 return Dropdown.dataApiKeydownHandler; 4765 } 4766 } 4767 4768 $(document) 4769 .off('keydown.bs.dropdown.data-api') 4770 .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > [' + Selector.DATA_TOGGLE + ']', keydownHandler) 4771 .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > .dropdown-menu', keydownHandler) 4772 .on('keydown' + EVENT_KEY, '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', Selectpicker.prototype.keydown) 4773 .on('focusin.modal', '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', function (e) { 4774 e.stopPropagation(); 4775 }); 4776 4777 // SELECTPICKER DATA-API 4778 // ===================== 4779 document.addEventListener('DOMContentLoaded', function () { 4780 $('.selectpicker').each(function () { 4781 var $selectpicker = $(this); 4782 Plugin.call($selectpicker, $selectpicker.data()); 4783 }); 4784 }); 4785})(jQuery); 4786 4787 4788})); 4789 4790/******/ (function(modules) { // webpackBootstrap 4791/******/ // The module cache 4792/******/ var installedModules = {}; 4793/******/ 4794/******/ // The require function 4795/******/ function __webpack_require__(moduleId) { 4796/******/ 4797/******/ // Check if module is in cache 4798/******/ if(installedModules[moduleId]) { 4799/******/ return installedModules[moduleId].exports; 4800/******/ } 4801/******/ // Create a new module (and put it into the cache) 4802/******/ var module = installedModules[moduleId] = { 4803/******/ i: moduleId, 4804/******/ l: false, 4805/******/ exports: {} 4806/******/ }; 4807/******/ 4808/******/ // Execute the module function 4809/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 4810/******/ 4811/******/ // Flag the module as loaded 4812/******/ module.l = true; 4813/******/ 4814/******/ // Return the exports of the module 4815/******/ return module.exports; 4816/******/ } 4817/******/ 4818/******/ 4819/******/ // expose the modules object (__webpack_modules__) 4820/******/ __webpack_require__.m = modules; 4821/******/ 4822/******/ // expose the module cache 4823/******/ __webpack_require__.c = installedModules; 4824/******/ 4825/******/ // define getter function for harmony exports 4826/******/ __webpack_require__.d = function(exports, name, getter) { 4827/******/ if(!__webpack_require__.o(exports, name)) { 4828/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 4829/******/ } 4830/******/ }; 4831/******/ 4832/******/ // define __esModule on exports 4833/******/ __webpack_require__.r = function(exports) { 4834/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 4835/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 4836/******/ } 4837/******/ Object.defineProperty(exports, '__esModule', { value: true }); 4838/******/ }; 4839/******/ 4840/******/ // create a fake namespace object 4841/******/ // mode & 1: value is a module id, require it 4842/******/ // mode & 2: merge all properties of value into the ns 4843/******/ // mode & 4: return value when already ns object 4844/******/ // mode & 8|1: behave like require 4845/******/ __webpack_require__.t = function(value, mode) { 4846/******/ if(mode & 1) value = __webpack_require__(value); 4847/******/ if(mode & 8) return value; 4848/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 4849/******/ var ns = Object.create(null); 4850/******/ __webpack_require__.r(ns); 4851/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 4852/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 4853/******/ return ns; 4854/******/ }; 4855/******/ 4856/******/ // getDefaultExport function for compatibility with non-harmony modules 4857/******/ __webpack_require__.n = function(module) {
4858/******/ var getter = module && module.__esModule ? 4859/******/ function getDefault() { return module['default']; } : 4860/******/ function getModuleExports() { return module; }; 4861/******/ __webpack_require__.d(getter, 'a', getter); 4862/******/ return getter; 4863/******/ }; 4864/******/ 4865/******/ // Object.prototype.hasOwnProperty.call 4866/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 4867/******/ 4868/******/ // __webpack_public_path__ 4869/******/ __webpack_require__.p = "/"; 4870/******/ 4871/******/ 4872/******/ // Load entry module and return exports 4873/******/ return __webpack_require__(__webpack_require__.s = 10); 4874/******/ }) 4875/************************************************************************/ 4876/******/ ({ 4877
4878/***/ "./src/components/heroes/heroes.js": 4879/*!*****************************************!*\ 4880 !*** ./src/components/heroes/heroes.js ***! 4881 \*****************************************/ 4882/*! no static exports found */ 4883/***/ (function(module, exports, __webpack_require__) { 4884 4885"use strict"; 4886 // import { tns } from "../../js/main.script"; 4887 4888(function ($, Drupal) { 4889 $(document).ready(function () { 4890 var tnsCarouselPrimary = document.querySelectorAll(".heroes-primary"); 4891 tnsCarouselPrimary.forEach(function (slider) { 4892 // if( $('.heroes-primary .heroes__item').length > 1) { 4893 var heroes_primary__slider = document.tnsAda.init({ 4894 container: slider.querySelector(".heroes-primary .heroes__row"), 4895 controlsContainer: slider.querySelector(".tns__controls"), 4896 // navContainer: slider.querySelector(".tns__dots"), 4897 // prevButton: slider.querySelector(".tns__arrow.prev"), 4898 // nextButton: slider.querySelector(".tns__arrow.next"), 4899 navPosition: "top", 4900 gutter: 1, 4901 nav: true, 4902 controls: true, 4903 buttonPosition: 'after', 4904 navBetweenControls: true, 4905 controlWrap: "<div class='tns__controls'></div>", 4906 controlsText: ["<span class='sr-only'>previous slide</span>", "<span class='sr-only'>next slide</span>"], 4907 onInit: function onInit(info) { 4908 // debugger; 4909 // console.log(slider); 4910 $(slider).find(".heroes").css("display", "flex"); // setTimeout(() => { 4911 // $(slider).find(".tns-inner").children().not(".heroes__row").wrap("<div class='tns__controls'></div>"); 4912 // }, "1000"); 4913 // if ($(info).find(".heroes__item").length > 1) { 4914 // info.controlsContainer.setAttribute("tabindex", -1); 4915 // info.nextButton.setAttribute("tabindex", 3); 4916 // info.prevButton.setAttribute("tabindex", 3); 4917 // document 4918 // .querySelectorAll(".tns-slide-cloned a") 4919 // .forEach(function (btn) { 4920 // btn.setAttribute("tabindex", -1); 4921 // }); 4922 // } 4923 } 4924 }); // } 4925 }); // if( $('.heroes-secondary .heroes__item').length > 1) { 4926 4927 var tnsCarouselSecondary = document.querySelectorAll(".heroes-secondary"); 4928 tnsCarouselSecondary.forEach(function (slider) { 4929 var heroes_secondary__slider = document.tnsAda.init({ 4930 container: slider.querySelector(".heroes-secondary .heroes__row"), 4931 controlsContainer: slider.querySelector(".tns__controls"), 4932 // navContainer: slider.querySelector(".tns__dots"), 4933 // prevButton: slider.querySelector(".tns__arrow.prev"), 4934 // nextButton: slider.querySelector(".tns__arrow.next"), 4935 navPosition: "top", 4936 nav: true, 4937 controls: true, 4938 buttonPosition: 'after', 4939 navBetweenControls: true, 4940 controlWrap: "<div class='tns__controls'></div>", 4941 controlsText: ["<span class='sr-only'>previous slide</span>", "<span class='sr-only'>next slide</span>"], 4942 onInit: function onInit(info) {// $(slider).find(".tns-inner").children().not(".heroes__row").wrap("<div class='tns__controls'></div>"); 4943 // info.controlsContainer.setAttribute("tabindex", -1); 4944 // info.nextButton.setAttribute("tabindex", 3); 4945 // info.prevButton.setAttribute("tabindex", 3); 4946 // document 4947 // .querySelectorAll(".tns-slide-cloned a") 4948 // .forEach(function (btn) { 4949 // btn.setAttribute("tabindex", -1); 4950 // }); 4951 } 4952 }); // } 4953 }); 4954 }); 4955})(jQuery, Drupal); 4956 4957/***/ }), 4958 4959/***/ 10: 4960/*!***********************************************!*\ 4961 !*** multi ./src/components/heroes/heroes.js ***! 4962 \***********************************************/ 4963/*! no static exports found */ 4964/***/ (function(module, exports, __webpack_require__) { 4965 4966module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/heroes/heroes.js */"./src/components/heroes/heroes.js"); 4967 4968 4969/***/ }) 4970 4971/******/ });; 4972/******/ (function(modules) { // webpackBootstrap 4973/******/ // The module cache 4974/******/ var installedModules = {}; 4975/******/ 4976/******/ // The require function 4977/******/ function __webpack_require__(moduleId) { 4978/******/ 4979/******/ // Check if module is in cache 4980/******/ if(installedModules[moduleId]) { 4981/******/ return installedModules[moduleId].exports; 4982/******/ } 4983/******/ // Create a new module (and put it into the cache) 4984/******/ var module = installedModules[moduleId] = { 4985/******/ i: moduleId, 4986/******/ l: false, 4987/******/ exports: {} 4988/******/ }; 4989/******/ 4990/******/ // Execute the module function 4991/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 4992/******/ 4993/******/ // Flag the module as loaded
vendor: 2,823 bytes, lines 4994-5059
4994/******/ module.l = true; 4995/******/ 4996/******/ // Return the exports of the module 4997/******/ return module.exports; 4998/******/ } 4999/******/ 5000/******/ 5001/******/ // expose the modules object (__webpack_modules__) 5002/******/ __webpack_require__.m = modules; 5003/******/ 5004/******/ // expose the module cache 5005/******/ __webpack_require__.c = installedModules; 5006/******/ 5007/******/ // define getter function for harmony exports 5008/******/ __webpack_require__.d = function(exports, name, getter) { 5009/******/ if(!__webpack_require__.o(exports, name)) { 5010/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 5011/******/ } 5012/******/ }; 5013/******/ 5014/******/ // define __esModule on exports 5015/******/ __webpack_require__.r = function(exports) { 5016/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5017/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5018/******/ } 5019/******/ Object.defineProperty(exports, '__esModule', { value: true }); 5020/******/ }; 5021/******/ 5022/******/ // create a fake namespace object 5023/******/ // mode & 1: value is a module id, require it 5024/******/ // mode & 2: merge all properties of value into the ns 5025/******/ // mode & 4: return value when already ns object 5026/******/ // mode & 8|1: behave like require 5027/******/ __webpack_require__.t = function(value, mode) { 5028/******/ if(mode & 1) value = __webpack_require__(value); 5029/******/ if(mode & 8) return value; 5030/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 5031/******/ var ns = Object.create(null); 5032/******/ __webpack_require__.r(ns); 5033/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 5034/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 5035/******/ return ns; 5036/******/ }; 5037/******/ 5038/******/ // getDefaultExport function for compatibility with non-harmony modules 5039/******/ __webpack_require__.n = function(module) { 5040/******/ var getter = module && module.__esModule ? 5041/******/ function getDefault() { return module['default']; } : 5042/******/ function getModuleExports() { return module; }; 5043/******/ __webpack_require__.d(getter, 'a', getter); 5044/******/ return getter; 5045/******/ }; 5046/******/ 5047/******/ // Object.prototype.hasOwnProperty.call 5048/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 5049/******/ 5050/******/ // __webpack_public_path__ 5051/******/ __webpack_require__.p = "/"; 5052/******/ 5053/******/ 5054/******/ // Load entry module and return exports 5055/******/ return __webpack_require__(__webpack_require__.s = 9); 5056/******/ }) 5057/************************************************************************/ 5058/******/ ({ 5059
5060/***/ "./src/components/header/header.js": 5061/*!*****************************************!*\ 5062 !*** ./src/components/header/header.js ***! 5063 \*****************************************/ 5064/*! no static exports found */ 5065/***/ (function(module, exports, __webpack_require__) { 5066 5067"use strict"; 5068 5069 5070(function ($, Drupal) { 5071 var valueTerm = $("#term"); 5072 var searchToggle = false; 5073 var w = window.innerWidth; 5074 Drupal.behaviors.header = { 5075 attach: function attach(context) { 5076 $(".navbar-actions .icon", context).on("click", function (e) { 5077 Drupal.behaviors.header.toggleSearch(context); 5078 5079 if ($("body").hasClass("page__header--active")) { 5080 $(".navbar-actions .icon").attr({ 5081 "aria-expanded": "true", 5082 "aria-label": "Close search", 5083 title: "Close search" 5084 }); 5085 } else { 5086 $(".navbar-actions .icon").attr({ 5087 "aria-expanded": "false", 5088 "aria-label": "Open search", 5089 title: "Open search" 5090 }); 5091 } 5092 }); 5093 $(".we-mega-menu-li", context).on("mousedown", function (e) { 5094 if (searchToggle) Drupal.behaviors.header.toggleSearch(context); 5095 }); 5096 $(window).resize(function () { 5097 var btnCloseMenu = $(".btn-close"); 5098 5099 if (w != window.innerWidth && window.innerWidth <= 768) { 5100 $("body").removeClass("page__header--active"); 5101 $("body").removeClass("toggled"); 5102 $(".navbar-we-mega-menu").removeClass("we-mobile-megamenu-active has-clicked"); 5103 $(".we-mega-menu-submenu").removeAttr("style"); 5104 btnCloseMenu.removeClass("d-none"); 5105 searchToggle = false; 5106 } 5107 }); 5108 }, 5109 toggleSearch: function toggleSearch(context) { 5110 $("body").toggleClass("page__header--active"); 5111 searchToggle = !searchToggle; 5112 var btnCloseMenu = $(".btn-close"); 5113 5114 if (searchToggle) { 5115 if (window.innerWidth >= 768) { 5116 $(".we-mega-menu-li.dropdown-menu").removeClass("clicked"); 5117 } 5118 5119 Drupal.behaviors.header.setFocusSearch(context); 5120 btnCloseMenu.addClass("d-none"); 5121 } else { 5122 btnCloseMenu.removeClass("d-none"); 5123 } 5124 }, 5125 clearSearchTerm: function clearSearchTerm(context) { 5126 valueTerm.val(""); 5127 }, 5128 setFocusSearch: function setFocusSearch(context) { 5129 valueTerm.focus(); 5130 } 5131 }; 5132})(jQuery, Drupal); 5133 5134/***/ }), 5135 5136/***/ 9: 5137/*!***********************************************!*\ 5138 !*** multi ./src/components/header/header.js ***! 5139 \***********************************************/ 5140/*! no static exports found */ 5141/***/ (function(module, exports, __webpack_require__) { 5142 5143module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/header/header.js */"./src/components/header/header.js"); 5144 5145 5146/***/ }) 5147 5148/******/ });; 5149/******/ (function(modules) { // webpackBootstrap 5150/******/ // The module cache 5151/******/ var installedModules = {}; 5152/******/ 5153/******/ // The require function 5154/******/ function __webpack_require__(moduleId) { 5155/******/ 5156/******/ // Check if module is in cache 5157/******/ if(installedModules[moduleId]) { 5158/******/ return installedModules[moduleId].exports; 5159/******/ } 5160/******/ // Create a new module (and put it into the cache) 5161/******/ var module = installedModules[moduleId] = { 5162/******/ i: moduleId, 5163/******/ l: false, 5164/******/ exports: {} 5165/******/ }; 5166/******/ 5167/******/ // Execute the module function 5168/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 5169/******/ 5170/******/ // Flag the module as loaded 5171/******/ module.l = true; 5172/******/ 5173/******/ // Return the exports of the module 5174/******/ return module.exports; 5175/******/ } 5176/******/ 5177/******/ 5178/******/ // expose the modules object (__webpack_modules__) 5179/******/ __webpack_require__.m = modules; 5180/******/ 5181/******/ // expose the module cache 5182/******/ __webpack_require__.c = installedModules; 5183/******/ 5184/******/ // define getter function for harmony exports 5185/******/ __webpack_require__.d = function(exports, name, getter) { 5186/******/ if(!__webpack_require__.o(exports, name)) { 5187/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 5188/******/ } 5189/******/ }; 5190/******/ 5191/******/ // define __esModule on exports 5192/******/ __webpack_require__.r = function(exports) { 5193/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5194/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5195/******/ } 5196/******/ Object.defineProperty(exports, '__esModule', { value: true }); 5197/******/ }; 5198/******/ 5199/******/ // create a fake namespace object 5200/******/ // mode & 1: value is a module id, require it 5201/******/ // mode & 2: merge all properties of value into the ns 5202/******/ // mode & 4: return value when already ns object 5203/******/ // mode & 8|1: behave like require 5204/******/ __webpack_require__.t = function(value, mode) { 5205/******/ if(mode & 1) value = __webpack_require__(value); 5206/******/ if(mode & 8) return value; 5207/******/ if((mode & 4) && typeof value === 'object' && value && value.__esMo
vendor: 1,304 bytes, lines 5207-5236
5207dule) return value; 5208/******/ var ns = Object.create(null); 5209/******/ __webpack_require__.r(ns); 5210/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 5211/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 5212/******/ return ns; 5213/******/ }; 5214/******/ 5215/******/ // getDefaultExport function for compatibility with non-harmony modules 5216/******/ __webpack_require__.n = function(module) { 5217/******/ var getter = module && module.__esModule ? 5218/******/ function getDefault() { return module['default']; } : 5219/******/ function getModuleExports() { return module; }; 5220/******/ __webpack_require__.d(getter, 'a', getter); 5221/******/ return getter; 5222/******/ }; 5223/******/ 5224/******/ // Object.prototype.hasOwnProperty.call 5225/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 5226/******/ 5227/******/ // __webpack_public_path__ 5228/******/ __webpack_require__.p = "/"; 5229/******/ 5230/******/ 5231/******/ // Load entry module and return exports 5232/******/ return __webpack_require__(__webpack_require__.s = 13); 5233/******/ }) 5234/************************************************************************/ 5235/******/ ({ 5236
5237/***/ "./src/components/navbar/navbar.js": 5238/*!*****************************************!*\ 5239 !*** ./src/components/navbar/navbar.js ***! 5240 \*****************************************/ 5241/*! no static exports found */ 5242/***/ (function(module, exports) { 5243 5244(function ($, Drupal) { 5245 Drupal.behaviors.navbar = { 5246 attach: function attach(context) { 5247 var $navbar = $('#navbar'), 5248 prevScroll = 0, 5249 scrollDir = 'up'; 5250 $(document).off('scroll.navdir').on('scroll.navdir', function () { 5251 var st = $(window).scrollTop(); 5252 5253 if (st < prevScroll && scrollDir === 'down') { 5254 //console.log('up',st); 5255 scrollDir = 'up'; 5256 $navbar.addClass('scroll-dir-up'); 5257 prevScroll = st; 5258 return; 5259 } 5260 5261 if (st > prevScroll && scrollDir === 'up' && st > 100) { 5262 //console.log('down',st); 5263 $navbar.removeClass('scroll-dir-up'); 5264 scrollDir = 'down'; 5265 } 5266 5267 prevScroll = st; 5268 return; 5269 }); 5270 } 5271 }; 5272})(jQuery, Drupal); 5273 5274/***/ }), 5275 5276/***/ 13: 5277/*!***********************************************!*\ 5278 !*** multi ./src/components/navbar/navbar.js ***! 5279 \***********************************************/ 5280/*! no static exports found */ 5281/***/ (function(module, exports, __webpack_require__) { 5282 5283module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/navbar/navbar.js */"./src/components/navbar/navbar.js"); 5284 5285 5286/***/ }) 5287 5288/******/ });; 5289/** 5290* DO NOT EDIT THIS FILE. 5291* See the following change record for more information, 5292* https://www.drupal.org/node/2815083 5293* @preserve 5294**/ 5295function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } 5296function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } 5297function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } 5298function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 5299function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } 5300function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } 5301(function ($, Drupal, cookies) { 5302 var deprecatedMessageSuffix = "is deprecated in Drupal 9.0.0 and will be removed in Drupal 10.0.0. Use the core/js-cookie library instead. See https://www.drupal.org/node/3104677"; 5303 var isFunction = function isFunction(obj) { 5304 return Object.prototype.toString.call(obj) === '[object Function]'; 5305 }; 5306 var parseCookieValue = function parseCookieValue(value, parseJson) { 5307 if (value.indexOf('"') === 0) { 5308 value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 5309 } 5310 try { 5311 value = decodeURIComponent(value.replace(/\+/g, ' ')); 5312 return parseJson ? JSON.parse(value) : value; 5313 } catch (e) {} 5314 }; 5315 var reader = function reader(cookieValue, cookieName, converter, readUnsanitized, parseJson) { 5316 var value = readUnsanitized ? cookieValue : parseCookieValue(cookieValue, parseJson); 5317 if (converter !== undefined && isFunction(converter)) { 5318 return converter(value, cookieName); 5319 } 5320 return value; 5321 };
5322 $.cookie = function (key) { 5323 var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; 5324 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 5325 Drupal.deprecationError({ 5326 message: "jQuery.cookie() ".concat(deprecatedMessageSuffix) 5327 }); 5328 if (value !== undefined && !isFunction(value)) { 5329 var attributes = _objectSpread(_objectSpread({}, $.cookie.defaults), options); 5330 if (typeof attributes.expires === 'string' && attributes.expires !== '') { 5331 attributes.expires = new Date(attributes.expires); 5332 } 5333 var cookieSetter = cookies.withConverter({ 5334 write: function write(cookieValue) { 5335 return encodeURIComponent(cookieValue); 5336 } 5337 }); 5338 value = $.cookie.json && !$.cookie.raw ? JSON.stringify(value) : String(value); 5339 return cookieSetter.set(key, value, attributes); 5340 } 5341 var userProvidedConverter = value; 5342 var cookiesShim = cookies.withConverter({ 5343 read: function read(cookieValue, cookieName) { 5344 return reader(cookieValue, cookieName, userProvidedConverter, $.cookie.raw, $.cookie.json); 5345 } 5346 }); 5347 if (key !== undefined) { 5348 return cookiesShim.get(key); 5349 } 5350 var results = cookiesShim.get();
5351 Object.keys(results).forEach(function (resultKey) { 5352 if (results[resultKey] === undefined) { 5353 delete results[resultKey]; 5354 } 5355 }); 5356 return results; 5357 }; 5358 $.cookie.defaults = _objectSpread({ 5359 path: '' 5360 }, cookies.defaults); 5361 $.cookie.json = false; 5362 $.cookie.raw = false; 5363 $.removeCookie = function (key, options) { 5364 Drupal.deprecationError({ 5365 message: "jQuery.removeCookie() ".concat(deprecatedMessageSuffix) 5366 }); 5367 cookies.remove(key, _objectSpread(_objectSpread({}, $.cookie.defaults), options)); 5368 return !cookies.get(key); 5369 }; 5370})(jQuery, Drupal, window.Cookies);; 5371(function ($, Drupal) { 5372 Drupal.behaviors.provinceSelector = { 5373 attach: function (context, settings) { 5374 // When juicer.io block is enabled it breaks jQuery.once, The following 5375 // is a fix for this behavior. 5376 let queryString = window.location.search; 5377 let urlParams = new URLSearchParams(queryString); 5378 let regionFocus = urlParams.get('regionFocus'); 5379 if (regionFocus != null) { 5380 $("#region-select").focus(); 5381 var simpleLiveCurl=location.protocol + '//' + location.host + location.pathname; 5382 window.history.replaceState( {} , 'regionFocus', simpleLiveCurl); 5383 } 5384 let $selector = null; 5385 let $selector_mobile = null; 5386 if (typeof jQuery.fn.once !== "undefined") { 5387 $selector = $("#province-selector select").once("provinceSelector"); 5388 $selector_mobile = $("#province-selector-mobile select").once( 5389 "provinceSelector" 5390 ); 5391 } else { 5392 $selector = $("#province-selector select"); 5393 $selector_mobile = $("#province-selector-mobile select"); 5394 } 5395 provinceSelector.setDefault(); 5396 // Bypass megamenu caching issue 5397 const activeProvince = provinceSelector.getProvince(); 5398 5399 $('option', $selector_mobile).removeAttr('selected') 5400 $selector_mobile.val(activeProvince); 5401 5402 $selector.on("change", () => { 5403 const region = $("option:selected", $selector).data("region"); 5404 provinceSelector.setCookie($selector.val(), region); 5405 }); 5406 5407 $selector_mobile.on("change", () => { 5408 // Fix issue with variable undefined 5409 let $sMobile = $("#province-selector-mobile select"); 5410 const region = $("option:selected", $sMobile).data("region"); 5411 provinceSelector.setCookie($sMobile.val(), region); 5412 }); 5413 }, 5414 }; 5415 5416 // Helper object. 5417 const provinceSelector = { 5418 provinceCookie: "currentProvince", 5419 regionCookie: "currentRegion", 5420 setDefault: () => { 5421 // Get default province from backend integration. 5422 $.cookie( 5423 provinceSelector.provinceCookie, drupalSettings.defaultProvince, 5424 { path: "/" } 5425 ); 5426 $.cookie( 5427 provinceSelector.regionCookie, drupalSettings.defaultRegion, 5428 { path: "/" } 5429 ); 5430 }, 5431 setCookie: (province, region) => { 5432 $.cookie(provinceSelector.provinceCookie, province, { path: "/" }); 5433 $.cookie(provinceSelector.regionCookie, region, { path: "/" }); 5434 // document.location.reload(true); 5435 let queryString = window.location.search; 5436 let urlParams = new URLSearchParams(queryString); 5437 urlParams.delete('regionFocus'); 5438 urlParams.set('regionFocus', ''); 5439 document.location.href += '?' + urlParams; 5440 }, 5441 getProvince: () => { 5442 return $.cookie(provinceSelector.provinceCookie) 5443 } 5444 }; 5445})(jQuery, Drupal); 5446; 5447/******/ (function(modules) { // webpackBootstrap 5448/******/ // The module cache 5449/******/ var installedModules = {}; 5450/******/ 5451/******/ // The require function 5452/******/ function __webpack_require__(moduleId) { 5453/******/ 5454/******/ // Check if module is in cache 5455/******/ if(installedModules[moduleId]) { 5456/******/ return installedModules[moduleId].exports; 5457/******/ } 5458/******/ // Create a new module (and put it into the cache) 5459/******/ var module = installedModules[moduleId] = { 5460/******/ i: moduleId, 5461/******/ l: false, 5462/******/ exports: {} 5463/******/ }; 5464/******/ 5465/******/ // Execute the module function 5466/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 5467/******/ 5468/******/ // Flag the module as loaded
vendor: 2,824 bytes, lines 5469-5534
5469/******/ module.l = true; 5470/******/ 5471/******/ // Return the exports of the module 5472/******/ return module.exports; 5473/******/ } 5474/******/ 5475/******/ 5476/******/ // expose the modules object (__webpack_modules__) 5477/******/ __webpack_require__.m = modules; 5478/******/ 5479/******/ // expose the module cache 5480/******/ __webpack_require__.c = installedModules; 5481/******/ 5482/******/ // define getter function for harmony exports 5483/******/ __webpack_require__.d = function(exports, name, getter) { 5484/******/ if(!__webpack_require__.o(exports, name)) { 5485/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 5486/******/ } 5487/******/ }; 5488/******/ 5489/******/ // define __esModule on exports 5490/******/ __webpack_require__.r = function(exports) { 5491/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5492/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5493/******/ } 5494/******/ Object.defineProperty(exports, '__esModule', { value: true }); 5495/******/ }; 5496/******/ 5497/******/ // create a fake namespace object 5498/******/ // mode & 1: value is a module id, require it 5499/******/ // mode & 2: merge all properties of value into the ns 5500/******/ // mode & 4: return value when already ns object 5501/******/ // mode & 8|1: behave like require 5502/******/ __webpack_require__.t = function(value, mode) { 5503/******/ if(mode & 1) value = __webpack_require__(value); 5504/******/ if(mode & 8) return value; 5505/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 5506/******/ var ns = Object.create(null); 5507/******/ __webpack_require__.r(ns); 5508/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 5509/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 5510/******/ return ns; 5511/******/ }; 5512/******/ 5513/******/ // getDefaultExport function for compatibility with non-harmony modules 5514/******/ __webpack_require__.n = function(module) { 5515/******/ var getter = module && module.__esModule ? 5516/******/ function getDefault() { return module['default']; } : 5517/******/ function getModuleExports() { return module; }; 5518/******/ __webpack_require__.d(getter, 'a', getter); 5519/******/ return getter; 5520/******/ }; 5521/******/ 5522/******/ // Object.prototype.hasOwnProperty.call 5523/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 5524/******/ 5525/******/ // __webpack_public_path__ 5526/******/ __webpack_require__.p = "/"; 5527/******/ 5528/******/ 5529/******/ // Load entry module and return exports 5530/******/ return __webpack_require__(__webpack_require__.s = 11); 5531/******/ }) 5532/************************************************************************/ 5533/******/ ({ 5534
5535/***/ "./src/components/mega-nav/mega-nav.js": 5536/*!*********************************************!*\ 5537 !*** ./src/components/mega-nav/mega-nav.js ***! 5538 \*********************************************/ 5539/*! no static exports found */ 5540/***/ (function(module, exports, __webpack_require__) { 5541 5542"use strict"; 5543 // import {MmenuLight} from './mmenu-light.js' 5544 5545(function ($, Drupal) { 5546 $(document).ready(function () { 5547 //focus trap 5548 function focusTrap(trapSelector) { 5549 // Focus Trap: Causes the tab key to loop focus within the given selector. 5550 var focusableElements = 'button:not(.hidden), [href]:not(.hidden), input:not(.hidden), select:not(.hidden), textarea:not(.hidden), [tabindex]:not([tabindex="-1"])'; // All focusable elements 5551 5552 document.addEventListener("keydown", function (e) { 5553 console.log("KEYDOWN"); 5554 var trap = document.querySelector(trapSelector); // If the key pressed is not 'Tab' or the trap element is not present: do nothing 5555 5556 console.log("TRAP:", trap); 5557 var isTabPressed = e.key === "Tab" || e.keyCode === 9; 5558 5559 if (!isTabPressed || !trap) { 5560 return; 5561 } 5562 5563 var focusableContent = trap.querySelectorAll(focusableElements), 5564 firstFocusableElement = focusableContent[0], 5565 // first focusable element 5566 lastFocusableElement = focusableContent[focusableContent.length - 1]; // last focusable element 5567 5568 if (e.shiftKey) { 5569 // if shift + tab on first element, focus the last focusable element 5570 if (document.activeElement === firstFocusableElement) { 5571 lastFocusableElement.focus(); // 5572 5573 e.preventDefault(); 5574 } 5575 } else { 5576 // if tab on last element, focus the first focusable element 5577 if (document.activeElement === lastFocusableElement) { 5578 firstFocusableElement.focus(); 5579 e.preventDefault(); 5580 } 5581 } 5582 }); 5583 } 5584 5585 focusTrap("#main-menu-mobile"); 5586 setTimeout(function () { 5587 $(".mm-ocd").attr("role", "dialog").attr("aria-hidden", "true"); 5588 }, "1000"); // Clone Main Menu. 5589 5590 var mainMenu = $("#main-menu").html(); 5591 var providenceSelector = $("#province-selector").html(); 5592 var socialLinks = $("#block-dempsters-block-social-links > ul.nav").html(); 5593 var socialLinks2 = $(".block-language ul.links.nav").html(); 5594 $("#main-menu").after('<div id="main-menu-mobile" class="main-nav main-menu-wrapper d-block d-lg-none">' + '<div id="mobileNav" class="container"><a href="/" class="navbar-brand d-flex align-items-center " tabindex="0"><h1 class="sr-only">Dempster\'s</h1><img width="130px" height="86px" alt="Dempster\'s" src="/themes/custom/dempsters/logo.svg"><div class="d-flex flex-column logo-text"></div></a><div class="navbar-actions mobile"><button aria-label="Open search" aria-controls="search-container" id="menu-search" aria-expanded="false" class="btn icon icon-search icon-fill-tertiary hidden" title="Open search"></button></div> <button id="main-menu-button-close" class="menu-button d-block hidden" aria-label="Close" href="#main-menu-mobile-close"><i class="icon icon-close-bold icon-fill-tertiary"></i></button></div>' + mainMenu + "</div>"); 5595 $("#main-menu-mobile .main-menu").append("<li class='nav-item providence-item'><div id='province-selector-mobile'>" + providenceSelector + "</div></li>"); 5596 $("#main-menu-mobile .main-menu").append("<li class='nav-item language-item'><div id='language-selector'></div></li>"); 5597 $("#main-menu-mobile .main-menu").append("<li class='nav-item social-item'><ul id='social-menu'>" + socialLinks + "</ul></li>"); 5598 $("#province-selector-mobile label").attr("for", "region-selector-mobile"); 5599 $("#province-selector-mobile #region-select").attr("id", "region-selector-mobile"); 5600 setTimeout(function () { 5601 var languageSelector = $(".block-language ul.links.nav li").not(".is-active").html(); 5602 $(".language-item #language-selector").append(languageSelector); 5603 $('#main-menu-mobile #region-select-warning').removeAttr('id').attr('id', 'region-select-warning-mobile'); 5604 }, 1000); 5605 setTimeout(function () { 5606 $("#mobileNav #province-selector-mobile option").attr("id", "width_tmp_option_mb"); //UPDATES NAV HEIGHT VARIABLE FOR SEARCH MODAL 5607 5608 var root = document.documentElement; 5609 var navHeight = $('#navbar').height();
5610 console.log('NAV HEIGHT', navHeight); 5611 root.style.setProperty('--navbar-height', navHeight + "px"); 5612 }, 2000); //INSIDE MENU SEARCH BUTTON 5613 5614 $('#menu-search').on('click', function () { 5615 $('#main-menu-button-close').trigger('click'); 5616 setTimeout(function () { 5617 $('#navbar .mobile .icon-search').trigger('click'); 5618 }, 100); 5619 }); //add custom menback button 5620 5621 var backText = Drupal.t("Back"); 5622 $("#main-menu-mobile .main-menu").find(".dropdown-menu").prepend("<li class='nav-item'><button class='mm-back-button'>" + backText + "</button></li>"); 5623 var $backbutton = $("#main-menu-mobile .main-menu .dropdown-menu .mm-back-button"); 5624 $("#main-menu-mobile #products-submenu").removeAttr("id").attr("id", "products-submenu-mobile"); 5625 $("#main-menu-button-close").on("click", function () { 5626 $(".mm-ocd").attr("aria-hidden", "true"); 5627 }); //submenu open on click or keypress 5628 5629 $("#main-menu-mobile .main-menu>li:first-of-type").on("click", function () { 5630 $("#main-menu-mobile .main-menu > li:not(:first-of-type)").addClass("d-none hidden"); 5631 $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").addClass("d-none hidden").attr("tabindex", "-1"); 5632 $("#products-submenu").focus(); 5633 }); 5634 $("#main-menu-mobile .main-menu>li:first-of-type").on("keypress", function (event) { 5635 console.log("KEYPRESS"); 5636 5637 if (event.which == 13 || event.which == 32) { 5638 $("#main-menu-mobile .main-menu > li:not(:first-of-type)").addClass("d-none hidden"); 5639 $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").addClass("d-none hidden").attr("tabindex", "-1"); 5640 $("#products-submenu").focus(); 5641 } 5642 }); //submenu close on click or keypress 5643 5644 $(".mm-back-button").on("click", function () { 5645 console.log("back button pressed"); 5646 setTimeout(function () { 5647 $("#main-menu-mobile .main-menu > li:not(:first-of-type)").removeClass("d-none hidden"); 5648 $("#main-menu-mobile .main-menu").removeClass("mm-spn--open mm-spn--parent"); 5649 $(".main-menu .active .dropdown-menu").removeClass("mm-spn--open"); 5650 $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").removeClass("d-none hidden").attr("tabindex", "0"); 5651 $("#main-menu-button-close").focus(); 5652 }, 100); 5653 }); 5654 $(".mm-back-button").on("keypress", function (event) { 5655 console.log("KEYPRESS"); 5656 5657 if (event.which == 13 || event.which == 32) { 5658 setTimeout(function () { 5659 $("#main-menu-mobile .main-menu > li:not(:first-of-type)").removeClass("d-none hidden"); 5660 $("#main-menu-mobile .main-menu").removeClass("mm-spn--open mm-spn--parent"); 5661 $(".main-menu .active .dropdown-menu").removeClass("mm-spn--open"); 5662 $("#main-menu-mobile .main-menu > li:not(:first-of-type) a, #main-menu-mobile .main-menu > li:not(:first-of-type) label, #main-menu-mobile .main-menu > li:not(:first-of-type) select").removeClass("d-none hidden").attr("tabindex", "0"); 5663 $("#main-menu-button-close").focus(); 5664 }, 100); 5665 } 5666 }); 5667 Drupal.attachBehaviors(document.getElementById("province-selector-mobile")); // Add MmenuLight. 5668 5669 var menu = new MmenuLight(document.querySelector("#main-menu-mobile"), "(max-width: 992px)"); 5670 var navigator = menu.navigation({ 5671 selectedClass: "dropdown", 5672 slidingSubmenus: true, 5673 title: "Main Screen" 5674 }); // const navigator = menu.navigation(); 5675 5676 var drawer = menu.offcanvas({ 5677 position: "right", 5678 title: "Main Screen" 5679 }); 5680 navigator.openPanel(document.querySelector("ul")); // Open the menu. 5681 5682 document.querySelector('button[href="#main-menu-mobile"]').addEventListener("click", function (evnt) { 5683 evnt.preventDefault(); 5684 var openButton = document.getElementById("main-menu-button"); 5685 openButton.classList.add("hidden"); 5686 var closeButton = document.getElementById("main-menu-button-close"); 5687 closeButton.classList.remove("hidden"); 5688 drawer.open(); 5689 $(closeButton).focus(); 5690 $(".mm-ocd").removeAttr("aria-hidden", "false"); 5691 }); 5692 document.querySelector('button[href="#main-menu-mobile-close"]').addEventListener("click", function (evnt) { 5693 evnt.preventDefault(); 5694 var openButton = document.getElementById("main-menu-button"); 5695 openButton.classList.remove("hidden"); 5696 var closeButton = document.getElementById("main-menu-button-close"); 5697 closeButton.classList.add("hidden"); 5698 drawer.close(); 5699 $(".mm-ocd").attr("aria-hidden", "true"); 5700 $(openButton).focus(); 5701 }); 5702 $("#main-menu-mobile li.dropdown").on("click", function () { 5703 //$(this).addClass('active').removeClass('off').siblings().addClass('off').removeClass('active'); // no need to add .off 5704 $(this).addClass("active").siblings().removeClass("active"); 5705 }); // Main menu active class. 5706 // Nos produits 5707 5708 if ($("body").hasClass("node-921896") || $("body").hasClass("path-products") || $("body").hasClass("path-produits") || $("body").hasClass("page-node-type-products") || $("body").hasClass("page-term-bread-type")) { 5709 $(".main-nav .nav-link.dropdown-toggle").each(function () { 5710 if ($(this).text() == "Our products" || $(this).text() == "Nos produits") {
5711 $(this).closest(".nav-item").addClass("active"); 5712 } 5713 }); 5714 } // Nos recettes 5715 5716 5717 if ($("body").hasClass("page-node-type-recipes")) { 5718 $(".main-nav .nav-link").each(function () { 5719 if ($(this).attr("data-drupal-link-system-path") == "node/921901") { 5720 $(this).closest(".nav-item").addClass("active"); 5721 } 5722 }); 5723 } // Nutrition & Bien-Ãtre 5724 5725 5726 if ($("body").hasClass("page-node-type-blog")) { 5727 $(".main-nav .nav-link").each(function () { 5728 if ($(this).attr("data-drupal-link-system-path") == "node/922741") { 5729 $(this).closest(".nav-item").addClass("active"); 5730 } 5731 }); 5732 } // Detect Valid Keyboard Clicks 5733 // https://karlgroves.com/2014/11/24/ridiculously-easy-trick-for-keyboard-accessibility 5734 5735 5736 function a11yClick(event) { 5737 if (event.type === "click") { 5738 return true; 5739 } else if (event.type === "keypress") { 5740 var code = event.charCode || event.keyCode; 5741 5742 if (code === 32 || code === 13) { 5743 return true; 5744 } 5745 } else { 5746 return false; 5747 } 5748 } 5749 5750 $(".main-nav .nav-link.dropdown-toggle").on("keypress", function (event) { 5751 event.preventDefault(); 5752 5753 if (a11yClick(event) === true) { 5754 if ($(window).innerWidth() >= 992) { 5755 $(this).trigger("click"); 5756 } else { 5757 navigator.openPanel(document.querySelector("#main-menu-mobile .dropdown-menu")); 5758 $("#main-menu-mobile .menu-item__item").first().find("a").focus(); 5759 } 5760 } 5761 }); // Resizes the width of #region-select dynamically according to the width of the selected option 5762 5763 $("#width_tmp_option").html($("#province-selector #region-select option:selected").text()); 5764 $("#province-selector #region-select").width($("#width_tmp_select").width()); 5765 $("#province-selector #region-select").change(function () { 5766 $("#width_tmp_option").html($("#province-selector #region-select option:selected").text()); 5767 $(this).width($("#width_tmp_select").width()); 5768 }); 5769 }); 5770})(jQuery, Drupal); 5771 5772/***/ })
5772, 5773 5774/***/ 11: 5775/*!***************************************************!*\ 5776 !*** multi ./src/components/mega-nav/mega-nav.js ***! 5777 \***************************************************/ 5778/*! no static exports found */ 5779/***/ (function(module, exports, __webpack_require__) { 5780 5781module.exports = __webpack_require__(/*! /var/www/html/dev_bc_dempsters/html/web/themes/custom/dempsters/src/components/mega-nav/mega-nav.js */"./src/components/mega-nav/mega-nav.js"); 5782 5783 5784/***/ }) 5785 5786/******/ });;
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.