1// / <reference path="../bcls-config.js" /> 2// / <reference path="../lib/lodash.min.js" /> 3 4var BCLS = BCLS || {}; 5var VMInitialRequest = 0; 6 7BCLS.ProductListVM = function ProductListVM() { 8 var $this = this; 9 var InitialParam = ''; 10 var cidersOrigin = getParameterByName('type'); 11 12 this.LS_KEY = 'bcls.details-aggregations'; 13 this.LS_FILTER_KEY = 'bcls.filter-state'; 14 15 this.MainContainerDefaultPadding = jQuery('.bcls-main-container').css('padding-top'); 16 this.ControlBarTemplate = ko.observable('product-list-control-bar'); 17 this.Page = ko.observable(1); 18 this.TotalPages = ko.observable(0); 19 this.PageSize = 24; 20 this.Category = ko.observable(null); 21 this.SubCategory = ko.observable(null); 22 this.SubSubCategory = ko.observable(null); 23 this.Style = ko.observable(null); 24 this.SubCategoryUrl = ko.observable(null); 25 this.SubSubCategoryUrl = ko.observable('#'); 26 this.StyleUrl = ko.observable(null); 27 this.breadcrumbGroup = getParameterByName('group'); 28 this.SearchQuery = ko.observable(''); 29 this.SearchTerms= ko.observable(''); 30 this.ProductResults = ko.observableArray(); 31 this.TotalProducts = ko.observable(); 32 this.GrabbingProducts = ko.observable(false); 33 this.Sort = ko.observable('name.raw'); 34 this.SortLast = ko.observable(null); 35 this.SortDirection = ko.observable('asc'); 36 this.FilterAggregations = ko.observable(); 37 this.NoMoreProducts = false; 38 this.ProductDefinition = null; 39 this.FilterAggregationsSummary = ko.observable(); 40 this.MobileFiltersVisible = ko.observable(false); 41 this.SlideoutProducts = ko.observable(false); 42 this.LayoutType = ko.observable(Cookies.get(BCLS.Config.ProductListViewCookieKey) || 'grid'); 43 this.PromotionData = ko.observable(null); 44 this.MaxFilterItems = 8; 45 this.FieldsToCollapse = [ 46 'Price', 47 'Volume' 48 ]; 49 this.InitialRequestBody = null; 50 this.NonFacets = ['class.id', 'category.id', 'clause', 'subCategory.id']; 51 this.LastSection = null; 52 this.loading = ko.observable(true); 53 this.updateFilter = ko.observable(false); 54 this.filterKeys = ko.observable(false); 55 56 function getParameterByName(name, url) { 57 if (!url) { 58 url = window.location.href; 59 } 60 name = new URLSearchParams(url).get(name); 61 name = name.replace('coolers/ciders', 'coolers & ciders'); 62 63 return name; 64 } 65 66 67 68 function createAppendUrl(filterKeys) { 69 var newAppendUrl = ''; 70 _.forIn(filterKeys, function(value, key){ 71 key = convertFilterTags(key); 72 if(value == "Cider" && cidersOrigin != null){ 73 value = cidersOrigin; 74 } 75 76 if ( key == 'price' ) { 77 var priceAdjustedForES = []; 78 value.forEach( function( price ) { 79 if ( price !== undefined ) { 80 price = price.replace('-10.0', '-9.99') 81 .replace('-20.0', '-19.99') 82 .replace('-50.0', '-49.99') 83 .replace('-100.0', '-99.99') 84 .replace('-200.0', '-199.99') 85 .replace('-500.0', '-499.99'); 86 87 priceAdjustedForES.push(price); 88 } 89 }) 90 value = priceAdjustedForES; 91 } 92 93 if ( key == 'volume' ) { 94 var volumeAdjustedForES = []; 95 value.forEach( function( volume ) { 96 if ( volume !== undefined ) { 97 volume = volume.replace('-0.25', '-0.249') 98 .replace('-0.5', '-0.499') 99 .replace('-0.75', '-0.749') 100 .replace('-1.0', '-0.999') 101 .replace('-1.25', '-1.249') 102 .replace('-1.5', '-1.499') 103 .replace('-1.75', '-1.749') 104 .replace('-2.0', '-1.999') 105 .replace('-3.0', '-2.999') 106 .replace('-4.0', '-3.999'); 107 volumeAdjustedForES.push(volume); 108 } 109 }) 110 value = volumeAdjustedForES; 111 } 112 newAppendUrl += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(value); 113 }); 114 return newAppendUrl.toLowerCase(); 115 } 116 117 function convertFilterTags(filterTag) { 118 119 switch(filterTag) { 120 case 'productType': 121 return 'type'; 122 case 'productCategory': 123 return 'maincategory'; 124 case 'productSubCategory': 125 return 'subcategory'; 126 case 'redVarietal': 127 return 'red'; 128 case 'featured': 129 return 'special'; 130 case 'countryName.raw': 131 return 'country'; 132 case 'region.raw': 133 return 'region'; 134 case 'whiteVarietal': 135 return 'white'; 136 case 'currentPrice': 137 return 'price'; 138 case 'certificates': 139 return 'cert'; 140 case 'class.description': 141 return 'subtype'; 142 case 'category.description': 143 return 'categoryclass'; 144 default: 145 break; 146 } 147 return filterTag; 148 } 149 150 this.LayoutType.subscribe(function (newVal) { 151 Cookies.set(BCLS.Config.ProductListViewCookieKey, newVal); 152 }); 153 154 this.ItemsWithCounts = function (items) { 155 return _.filter(items, function (item) { 156 return item.item.doc_count > 0 || item.isSelected(); 157 }); 158 }; 159 160 this.FallBackImgSrcs = BCLS.Config.FallBackImgSrcs; 161 162 this.ToggleSlideoutFilters = function () { 163 var lastItem = $this.SlideoutProducts(); 164 $this.SlideoutProducts(!$this.SlideoutProducts()); 165 }; 166 167 this.CategoryUrl = ko.computed(function () { 168 if ($this.SubCategory() == 'Filtered') { 169 return window.location.href; 170 } else if ($this.SubCategory() != undefined) { 171 return '/product-catalogue?category=' + encodeURIComponent($this.Category()); 172 } 173 return '#'; 174 }); 175 176 this.HasItemCheckedBelowShowMore = function (section) { 177 return _.findLastIndex($this.ItemsWithCounts(section.Items), function (sec) { return sec.isSelected(); }) >= $this.MaxFilterItems; 178 }; 179 180 this.updateSubCategoryUrl = function () { 181 var sub_url = '#'; 182 183 if ($this.SubCategory() != null) { 184 var param = 'type'; 185 if ( $this.SubCategory() == 'featured' || $this.SubCategory() == 'promotions' || $this.SubCategory() == 'country' ) { 186 param = 'group'; 187 } 188 if ( $this.Category() == 'beer' ) { 189 param = 'maincategory'; 190 } 191 192 if ( $this.SubSubCategory() != null && $this.SubCategory() == 'other wine') { // remove SubSubCategory() != null to fix other wine > all other wine conflict 193 param = 'group'; 194 } 195 196 // make featured subsubcategory -> subcatagory 197 if($this.SubSubCategory() === 'featured') { 198 sub_url = '/product-catalogue?category=' + encodeURIComponent($this.Category()) + '&' + param + '=' + encodeURIComponent($this.SubSubCategory()); 199 } else { 200 sub_url = '/product-catalogue?category=' + encodeURIComponent($this.Category()) + '&' + param + '=' + encodeURIComponent($this.SubCategory()); 201 } 202 203 if ($this.SubCategory() == 'bc vqa') { 204 param = 'special'; 205 sub_url = '/product-catalogue?category=' + encodeURIComponent($this.Category()) + '&' + param + '=' + encodeURIComponent($this.SubCategory()); 206 } 207 208 if ($this.SubCategory() == 'sale') { 209 sub_url = '/product-catalogue?group=sale&special=on%20sale' 210 } 211 212 if ($this.SubCategory() == 'promotions') { 213 sub_url = '/product-catalogue?' + param + '=' + encodeURIComponent($this.SubCategory()); 214 } 215 } 216 $this.SubCategoryUrl(sub_url); 217 }; 218 219 this.updateSubSubCategoryUrl = function (item) { 220 var sub_url = $this.SubCategoryUrl(); 221 var subsub_url = sub_url; 222 if ( item !== null ) { 223 if ( item.key === 'type' && item.term === 'other wine' ) { 224 subsub_url = sub_url + '&' + item.key + '=' + encodeURIComponent('all other wine'); 225 } else { 226 subsub_url = sub_url + '&' + item.key + '=' + encodeURIComponent(item.term); 227 } 228 } 229 $this.SubSubCategoryUrl(subsub_url); 230 }; 231 232 this.updateStyleUrl = function () { 233 var sub_url = '#'; 234 235 if ($this.Category() != null ) { 236 var param = 'type'; 237 238 if ( $this.Category() == 'beer' ) { 239 param = 'style'; 240 } 241 242 sub_url = '/product-catalogue?category=' + encodeURIComponent($this.Category()) + '&' + param + '=' + encodeURIComponent($this.Style()); 243 } 244 245 $this.StyleUrl(sub_url); 246 }; 247 248 this.HasPromotion = ko.computed(function () { 249 return getParameterByName('promotionId') != null; 250 }); 251 252 this.ShowListView = function () { 253 $this.LayoutType('list'); 254 $this.UpdateAvailability($this.ProductResults()); 255 }; 256 257 this.ShowGridiew = function () { 258 $this.LayoutType('grid'); 259 $this.UpdateAvailability($this.ProductResults()); 260 }; 261 262 this.ToggleView = function () { 263 $this.LayoutType($this.LayoutType() == 'grid' ? 'list' : 'grid'); 264 265 }; 266 267 this.GetFilterCounts = function (section) { 268 return _($this.FilterAggregationsSummary())
269 .filter(function (x) { return ((section || '') == '' || x.key == section); }) 270 .map(function (x) { return x.Items; }) 271 .flatten() 272 .filter(function (x) { return x.isSelected(); }) 273 .value() 274 .length; 275 }; 276 277 this.SelectedFilters = ko.computed(function (section) { 278 let paramGroup = getParameterByName('group'); 279 let paramCategoryclass = getParameterByName('categoryclass'); 280 281 return _($this.FilterAggregationsSummary()) 282 .filter(function (x) { return ((section || '') == '' || x.key == section); }) 283 .map(function (x) { return x.Items; }) 284 .flatten() 285 .filter(function (x) { 286 if ( (paramGroup == 'sale' || paramGroup == 'promotions' ) && paramCategoryclass) { 287 switch(x.item.key) { 288 case 'Beer': 289 case 'Spirits': 290 case 'Coolers & Ciders': 291 case 'Wine': 292 let newCategory = paramCategoryclass.split(',')[0]; 293 if (newCategory !== x.item.key.toLowerCase()) { 294 x.isSelected(false); 295 } 296 break; 297 default: 298 break; 299 } 300 } 301 return x.isSelected(); 302 }) 303 .value(); 304 }); 305 306 this.FiltersSelected = ko.computed(function (section) { 307 return $this.SelectedFilters().length > 0 || false; 308 }); 309 310 this.GroupedResults = ko.computed(function () { 311 return _($this.ProductResults()) 312 .map(function (x, i) { return {item: x, index: i}; }) 313 .groupBy(function (x) { return Math.floor(x.index / 4); }) 314 .map(function (x) { 315 var items = _.map(x, function (x) { return x.item; }); 316 317 return [items.slice(0, 2), items.slice(2)]; 318 }).value(); 319 }); 320 321 this.ClearAllFilters = function (section) { 322 $this.GrabbingProducts(true); 323 324 _($this.FilterAggregationsSummary()) 325 .filter(function (x) { return ((section || '') == '' || x.key == section); }) 326 .map(function (x) { return x.Items; }) 327 .flatten() 328 .each(function (x) { 329 if (x.item.key == 'On Sale' && getParameterByName('group') == 'sale') { 330 x.isSelected(true); 331 } else if (x.item.key == 'BCL Select' && getParameterByName('group') == 'promotions' && getParameterByName('special').includes('bcl select' )) { 332 x.isSelected(true); 333 } 334 else if (x.item.key == 'New Product' && getParameterByName('group') == 'promotions' && getParameterByName('special').includes('new product')) { 335 x.isSelected(true); 336 } 337 else{ 338 x.isSelected(false); 339 } 340 }); 341 342 343 $this.GrabbingProducts(false); 344 $this.GrabProducts(1, true); 345 }; 346 347 this.HideMobileFilters = function () { 348 $this.MobileFiltersVisible(false); 349 }; 350 351 this.ShowMobileFilters = function () { 352 if (window.scrollY) { 353 window.scroll(0, 0); // reset the scroll position to the top left of the document. 354 } 355 356 $this.MobileFiltersVisible(!$this.MobileFiltersVisible()); 357 }; 358 359 this.FormatedSearchQuery = ko.computed(function () { 360 //return ($this.SearchQuery() || '').replace(/\+/g, ' ').replace(/"/g, ''); 361 return ($this.SearchQuery() || '').replace(/\+/g, ' '); 362 }); 363 364 this.SectionHasItems = function (section) { 365 return _.sum( 366 _.map( 367 section.Items, function (x) { 368 return x.item.doc_count; 369 } 370 ) 371 ) > 0; 372 }; 373 374 this.GetFilterKeys = function (filterData) { 375 if (filterData == null) { return {}; } 376 return _.map(filterData, function (item) { 377 return _(item.Items) 378 .filter(function (x) { 379 if (x.item.key == 'On Sale' && getParameterByName('group') == 'sale') { // Do not let users to deselect Sale filter 380 x.isSelected(true); 381 } 382 383 if ((x.item.key == 'BCL Select') && getParameterByName('group') == 'promotions' && getParameterByName('special').includes('bcl select')) { // Do not let users to deselect Promotions filter 384 x.isSelected(true); 385 } 386 387 if (( x.item.key == 'New Product') && getParameterByName('group') == 'promotions' && getParameterByName('special').includes('new product')) { // Do n
387ot let users to deselect Promotions filter 388 x.isSelected(true); 389 } 390 391 return x.isSelected(); 392 }) 393 .map(function (x) { 394 return '(' + item.key + ':' + (item.type === 'range' ? '[' + x.item.key.toString().replace(/\-/g, '+TO+') + ']' : '"' + encodeURIComponent(x.item.key.toString()) + '"') + ')'; 395 }) 396 .value(); 397 }); 398 }; 399 400 this.ToggleSort = function (sortKey) { 401 if (($this.SortLast() == null || ($this.SortLast() != 'name.raw' && $this.Sort() !== sortKey)) && getParameterByName('search') !== null) { 402 $this.SortLast(sortKey); 403 if (sortKey == 'name.raw') { 404 $this.SortDirection('asc') 405 } else { 406 $this.SortDirection('desc') 407 } 408 $this.Sort(sortKey); 409 410 $this.Page(1); 411 $this.GrabProducts(1, true); 412 } else { 413 $this.SortLast(sortKey); 414 if ($this.Sort() == sortKey) { 415 $this.SortDirection($this.SortDirection() == 'asc' ? 'desc' : 'asc'); 416 } 417 else { 418 if (sortKey == 'name.raw') { 419 $this.SortDirection('asc') 420 } else { 421 $this.SortDirection('desc') 422 } 423 $this.Sort(sortKey); 424 } 425 426 $this.Page(1); 427 $this.GrabProducts(1, true); 428 } 429 }; 430 431 this.GetFilterBuckets = function (aggData) { 432 if (aggData.buckets) { 433 return aggData.buckets; 434 } 435 else if (aggData.varietals) { 436 return aggData.varietals.buckets; 437 } 438 439 return null; 440 }; 441 442 this.IESpacingFixCheck = function (item) { 443 var ua = window.navigator.userAgent; 444 445 if (ua.indexOf('Trident/') > 0 || ua.indexOf('MSIE ') > 0) // If Internet Explorer, return version number 446 { 447 item.innerText = ' ' + item.innerText; 448 } 449 }; 450 451 this.GrabProducts = function GrabProducts(page, clearResults, scrollToTop) { 452 453 454 VMInitialRequest += 1; 455 456 if (page === undefined || page === null ) { 457 // $this.GrabbingProducts(false); 458 return; 459 } 460 461 if ($this.GrabbingProducts() == true) { return; } 462 463 $this.GrabbingProducts(true); 464 465 var this_sort = $this.Sort() + ':' + $this.SortDirection(); 466 467 if ( $this.SortLast() == null && getParameterByName('search') != null ) { 468 this_sort = '_score:'; 469 // apparently by not doing custom sorting will allow search results to actually show all of it 470 } 471 472 if (VMInitialRequest == 1) { 473 InitialParam = (getParameterByName('category') != null ? 'category=' + encodeURIComponent(getParameterByName('category')) : '') + 474 (getParameterByName('search') != null ? '&search=' + encodeURIComponent(getParameterByName('search')) : '')+ 475 (getParameterByName('type') != null ? '&type=' + encodeURIComponent(getParameterByName('type')) : '')+ 476 ($this.PromotionData() != null ? '&promotion=' + encodeURIComponent($this.PromotionData().short_title) + '&sku=' : '') + 477 ($this.PromotionData() != null && $this.PromotionData().skus != null ? encodeURIComponent($this.PromotionData().skus.map(function (item) { return item; }).join(',')) : ''); 478 // override to do sort by score with pages 479 if ( getParameterByName('search') != null ) { 480 // this_sort = '_score:desc'; 481 $this.Sort('_score'); 482 this_sort = '_score:desc'; 483 } 484 485 if (getParameterByName('group') == 'sale' || getParameterByName('group') == 'promotions' ) { 486 InitialParam = ''; 487 } 488 } 489 var filters = $this.GetFilterKeys($this.FilterAggregationsSummary()); 490 var searchUrl = BCLS.Config.SearchEndPoint; 491 var filterCount = _.filter(filters, function (x) { return x.length > 0;}).length; 492 var urlParams = 493 (getParameterByName('category') != null ? '&category=' + encodeURIComponent(getParameterByName('category')) : '') + 494 (getParameterByName('categoryclass') != null ? '&categoryclass=' + encodeURIComponent(getParameterByName('categoryclass')) : '') + 495 (getParameterByName('search') != null ? '&search=' + encodeURIComponent(getParameterByName('search')) : '') + 496 (getParameterByName('subtype') != null ? '&subtype=' + encodeURIComponent(getParameterByName('subtype')) : '') + 497 (getParameterByName('maincategory') != null ? '&maincategory=' + encodeURIComponent(getParameterByName('maincategory')) : '') + 498 (getParameterByName('subcategory') != null ? '&subcategory=' + encodeURIComponent(getParameterByName('subcategory')) : '') + 499 (getParameterByName('style') != null ? '&style=' + encodeURIComponent(getParameterByName('style')) : '') + 500 (getParameterByName('group') != null ? '&group=' + encodeURIComponent(getParameterByName('group')) : '') + 501 (getParameterByName('special') != null ? '&special=' + encodeURIComponent(getParameterByName('special')) : '') + 502 (getParameterByName('sub') != null ? '&sub=' + encodeURIComponent(getParameterByName('sub')) : '') + 503 (getParameterByName('subsub') != null ? '&subsub=' + encodeURIComponent(getParameterByName('subsub')) : '') + 504 (getParameterByName('red') != null ? '&red=' + encodeURIComponent(getParameterByName('red')) : '') + 505 (getParameterByName('white') != null ? '&white=' + encodeURIComponent(getParameterByName('white')) : '') + 506 (getParameterByName('cert') != null ? '&cert=' + encodeURIComponent(getParameterByName('cert')) : '') + 507 (getParameterByName('sku') != null ? '&sku=' + encodeURIComponent(getParameterByName('sku')) : '') + 508 (getParameterByName('type') != null ? '&type=' + encodeURIComponent(getParameterByName('type')) : '') + 509 (getParameterByName('price') != null ? '&price=' + encodeURIComponent(getParameterByName('price')) : '') + 510 (getParameterByName('volume') != null ? '&volume=' + encodeURIComponent(getParameterByName('volume')) : '') + 511 (getParameterByName('country') != null ? '&country=' + encodeURIComponent(getParameterByName('country')) : '') + 512 (getParameterByName('region') != null ? '®ion=' + encodeURIComponent(getParameterByName('region')) : '') + 513 (getParameterByName('sku') != null ? '&sku=' + encodeURIComponent(getParameterByName('sku')) : '') + 514 (getParameterByName('q') != null ? '&q=' + encodeURIComponent(getParameterByName('q')) : '') + 515 ($this.PromotionData() != null ? '&promotion=' + encodeURIComponent($this.PromotionData().short_title) + '&sku=' : '') + 516 ($this.PromotionData() != null && $this.PromotionData().skus != null ? encodeURIComponent($this.PromotionData().skus.map(function (item) { return item; }).join(',')) : ''); 517 if(getParameterByName('type') === 'rose') {
518 urlParams = urlParams.replace('type=rose', 'type=rose%20wine') 519 } 520 var sortUrl = '&' + 521 ('sort=' + this_sort) + 522 ('&size=' + $this.PageSize) + 523 ('&page=' + $this.Page()); 524 525 526 if (getParameterByName('sort') !== null) { 527 this_sort = getParameterByName('sort'); 528 } 529 530 if (getParameterByName('page') !== null) { 531 $this.Page(getParameterByName('page')); 532 } 533 534 535 536 var url = searchUrl + '?' + 537 ('sort=' + this_sort) + 538 urlParams + 539 ('&size=' + $this.PageSize) + 540 ('&page=' + $this.Page()); 541 // if there is no request body OR this is not an initial request (eg. A filter update) 542 if ($this.InitialRequestBody != null || VMInitialRequest > 1) { 543 var filterKeys = _($this.FilterAggregationsSummary()) 544 .map(function (parent) { return _.map(_.filter(parent.Items, function (item) { return item.isSelected(); }), function (child) { 545 return {section: parent.key, item: child}; }); }) 546 .flatten() 547 .groupBy(function (item) { return item.section; }) 548 .mapValues(function (item) { return _.map(item, function (filter) { return filter.item.item.key; }); }) 549 .value(); 550 551 if (getParameterByName('categoryclass') != null) { 552 // limit category selection to only 1 553 let categoryArray = getParameterByName('categoryclass').split(','); 554 let newCategoryArray = filterKeys['category.description'] || []; 555 let categoryUpdate = []; 556 if (categoryArray.length == newCategoryArray.length) { 557 categoryUpdate = newCategoryArray; 558 } else { 559 categoryUpdate = _.filter(newCategoryArray, function (category) { 560 return categoryArray.indexOf(category.toLowerCase()) == -1; 561 }) 562 } 563 if (categoryUpdate.length == 0) { 564 delete filterKeys['category.description']; 565 } else { 566 filterKeys['category.description'] = [categoryUpdate[0]]; 567 } 568 } 569 570 571 // Clears any checked children filters if category is unchecked 572 if (getParameterByName('group') == 'sale' || getParameterByName('group') == 'promotions') { 573 574 if (!filterKeys['category.description']) { 575 delete filterKeys['productType']; 576 delete filterKeys['redVarietal']; 577 delete filterKeys['whiteVarietal']; 578 delete filterKeys['productCategory']; // Beer Type 579 delete filterKeys['productSubCategory']; // Beer Sub-type 580 delete filterKeys['style']; // Beer Style 581 delete filterKeys['class.description']; // Spirits Sub-type 582 } 583 584 if (!filterKeys['productCategory']) { 585 delete filterKeys['productSubCategory']; // Beer Sub-type 586 } 587 588 if (filterKeys['productType'] && !filterKeys['productType'].includes('Whisky / Whiskey')) { 589 delete filterKeys['class.description']; // Spirits > Whisky / Whiskey > Whisky filter section 590 } 591 } 592 593 594 $this.getCategories(filterKeys); 595 $this.filterKeys(filterKeys); 596 597 // function checks your your filters and generates an appending url to update url with 598 var appendUrl = createAppendUrl(filterKeys); 599 var group = getParameterByName('group'); 600 601 if (group !== null) { 602 appendUrl = '&group=' + group + appendUrl; 603 } 604 if (InitialParam == '') { 605 appendUrl = appendUrl.replace('&', ''); 606 } 607 608 var requestFunc = jQuery.post.bind($this, searchUrl + '?' + InitialParam + appendUrl + sortUrl, JSON.stringify(_.merge({}, 609 $this.InitialRequestBody, filterKeys, {_lastSection: $this.LastSection}))); 610 var stateObj = {test: "test"}; 611 var newURL = 'product-catalogue?' + InitialParam + appendUrl + sortUrl; 612 history.replaceState(stateObj, "filtered", newURL); 613 } else { 614 615 if (getParameterByName('sort') !== null) { 616 this_sort = getParameterByName('sort'); 617 var sorts = this_sort.split(':'); 618 $this.Sort(sorts[0]); 619 $this.SortDirection(sorts[1]); 620 } 621 622 var requestFunc = jQuery.get.bind($this, url); 623 if (getParameterByName('page') !== null) { 624 page = getParameterByName('page'); 625 } 626 627 } 628 requestFunc() 629 .done(function (data) { 630 631 if (clearResults || false) { 632 $this.NoMoreProducts = false;
633 $this.ProductResults([]); 634 } 635 $this.InitialRequestBody = _.pickBy(data.search, function (value, key) { return $this.NonFacets.indexOf(key) > -1; }); 636 $this.InitialRequestBody = null; 637 638 let productHits = []; 639 640 if ( data.hits !== undefined ) { 641 productHits = data.hits.hits; 642 } else { 643 data.hits = { 644 total: 0, 645 total_pages: 0 646 }; 647 } 648 649 // add search highlight 650 if ( $this.SearchTerms() !== '' && $this.SearchTerms().length > 0 ) { 651 var searchTerms = $this.SearchTerms().join(' ').toUpperCase().split(' '); 652 var newProductHits = productHits.map(function (hit, index) { 653 var newHit = hit; 654 var productNames = hit._source.name.split(' '); 655 656 var newNames = productNames.map(function (word) { 657 if ( searchTerms.indexOf(word) >= 0) { 658 return '<b>' + word + '</b>'; 659 } else { 660 return word; 661 } 662 }); 663 664 newNames = newNames.join(' '); 665 666 newHit._source.name = newNames; 667 return newHit; 668 }); 669 productHits = newProductHits; 670 } 671 672 ko.utils.arrayPushAll($this.ProductResults, productHits); 673 674 // console.info(productHits.length); 675 676 if (productHits.length && productHits.length == 0) { 677 $this.NoMoreProducts = true; 678 } 679 680 $this.TotalProducts(data.hits.total); 681 682 var newFilterAggregations = data.aggregations; 683 var lastSectionKey = data.search._lastSection; 684 var lastSectionIndex = null; 685 var lastSectionData = null; 686 687 // if there is a last section, preserve last section 688 if ( lastSectionKey == null || lastSectionKey == undefined ) { 689 $this.FilterAggregations(data.aggregations); 690 } else if ( data.search[lastSectionKey] == undefined ) { 691 $this.FilterAggregations(data.aggregations); 692 } else { 693 if (lastSectionKey == 'productType') { 694 lastSectionKey = 'Type'; 695 } 696 if (lastSectionKey == 'redVarietal') { 697 lastSectionKey = 'Red Varietal'; 698 } 699 if (lastSectionKey == 'whiteVarietal') { 700 lastSectionKey = 'White Varietal'; 701 } 702 if (lastSectionKey == 'currentPrice') { 703 lastSectionKey = 'Price'; 704 } 705 if (lastSectionKey == 'volume') { 706 lastSectionKey = 'Volume'; 707 } 708 if (lastSectionKey == 'countryName.raw') { 709 lastSectionKey = 'Country'; 710 } 711 if (lastSectionKey == 'region') { 712 lastSectionKey = 'Region'; 713 } 714 if (lastSectionKey == 'style') { 715 lastSectionKey = 'Style'; 716 } 717 if (lastSectionKey == 'certificates') { 718 lastSectionKey = 'Other'; 719 } 720 if (lastSectionKey == 'class.description') { 721 lastSectionKey = 'Whisky'; 722 } 723 if (lastSectionKey == 'category.description') { 724 lastSectionKey = 'Category'; 725 } 726 if (lastSectionKey == 'productCategory') { // Beer's maincategory Type (space included) 727 lastSectionKey = 'Type '; 728 } 729 // get previous aggregations and replace current section with previous data 730 // to preserver data 731 var lastAggregation = $this.FilterAggregations(); 732 if ( lastAggregation[lastSectionKey] !== undefined ) { 733 newFilterAggregations[lastSectionKey] = lastAggregation[lastSectionKey]; 734 } 735 $this.FilterAggregations(newFilterAggregations); 736 } 737 738 $this.FilterAggregationsSummary(_.orderBy(_.map(newFilterAggregations, $this.BuildSummaryItem), 'order')); 739 740 $this.Page(page); 741 $this.TotalPages(data.hits.total_pages); 742 743 _( 744 _.intersectionWith( 745 $this.FilterAggregationsSummary(), 746 _.keys(data.search), 747 function(filter, key) { 748 return key == filter.key; 749 } 750 ) 751 ) 752 .map(function(item) { 753 return { 754 filter: item, 755 itemsToSelect: 756 data.search[item.key] instanceof Array 757 ? data.search[item.key] 758 : [data.search[item.key]], 759 }; 760 }) 761 .map(function(item) { 762 return _.intersectionWith( 763 item.filter.Items, 764 item.itemsToSelect, 765 function(item, selectKey) { 766 if ( 767 Object.prototype.toString.call(selectKey) === 768 '[object String]' 769 ) { 770 // prices 771 selectKey = selectKey 772 .replace('-9.99', '-10.0') 773 .replace('-19.99', '-20.0') 774 .replace('-49.99', '-50.0') 775 .replace('-99.99', '-100.0') 776 .replace('-199.99', '-200.0') 777 .replace('-499.99', '-500.0'); 778 779 // volumes 780 selectKey = selectKey 781 .replace('-0.249', '-0.25') 782 .replace('-0.499', '-0.5') 783 .replace('-0.749', '-0.75') 784 .replace('-0.999', '-1.0') 785 .replace('-1.249', '-1.25') 786 .replace('-1.499', '-1.5') 787 .replace('-1.749', '-1.75') 788 .replace('-1.999', '-2.0') 789 .replace('-2.999', '-3.0') 790 .replace('-3.999', '-4.0'); 791 } 792 793 if ( 794 _.isString(item.item.key) && 795 _.isString(selectKey) 796 ) { 797 return ( 798 item.item.key.toLowerCase() == 799 selectKey.toLowerCase() 800 ); 801 } else { 802 return item.item.key == selectKey; 803 } 804 } 805 ); 806 })
807 .flattenDeep() 808 .each(function(item) { 809 item.isSelected(true); 810 }); 811 812 if (window.localStorage) { 813 window.localStorage.setItem($this.LS_KEY, ko.toJSON($this.FilterAggregationsSummary())); 814 window.localStorage.setItem($this.LS_FILTER_KEY, true); 815 } 816 817 if ($this.SlideoutProducts()) { 818 _.each($this.FilterAggregationsSummary(), function (item) { 819 if (item.key != ($this.LastSection || '')) { item.expanded(false); } 820 else { item.expanded(true); } 821 }); 822 } 823 else { 824 _.each(_.filter($this.FilterAggregationsSummary(), $this.HasCheckedItems), function (item) { item.expanded(true); }); 825 _.each(_.filter($this.FilterAggregationsSummary(), $this.HasCheckedItems), function (item) { if ($this.HasItemCheckedBelowShowMore(item)) { item.expandMoreItems(true); } }); 826 } 827 828 if (scrollToTop) { 829 window.scrollTo(0, 0); 830 } 831 832 setTimeout(function () { 833 // jQuery('.product-list-container .product-list-item h3').matchHeight({ byRow: false }); 834 jQuery('.product-list-container .product-list-item .col-xs-8').matchHeight({byRow: false}); 835 $this.loading(false); 836 }, 100); 837 838 $this.UpdateAvailability(productHits); 839 $this.GrabbingProducts(false); 840 }) 841 .always(function (data) { 842 // console.info('always'); 843 // remove loading even if response is 500 844 $this.loading(false); 845 $this.GrabbingProducts(false); 846 }); 847 }; 848 849 this.UpdateAvailability = function(productHits) { 850 if (productHits.length && productHits.length > 0 ) { 851 var skus_array = productHits.map( function( product ) { 852 if ( product._id !== undefined ) { 853 return product._id; 854 } 855 }); 856 857 var skus = skus_array.join(','); 858 var url = BCLS.Config.ProductInventorySumEndpoint + '?skus=' + skus; 859 860 jQuery.get( url, function( data1 ) { 861 }).done(function(data) { 862 var inventory = 0; 863 864 skus_array.forEach(function( sku ) { 865 if (data[sku] !== undefined) { 866 inventory = data[sku].available; 867 } 868 if (inventory > 0) { 869 jQuery('#availability-' + sku).text('In Stock'); 870 } else { 871 jQuery('#availability-' + sku).text('Out of Stock'); 872 } 873 if (data[sku] === undefined){ 874 jQuery('#availability-' + sku).text('Out of Stock'); 875 } 876 }); 877 }) 878 } 879 } 880 881 var DisplayValueFormatters = { 882 ml: function (item) { 883 var from = item.from || 0; 884 var to = item.to || 0; 885 // minus 0.001 so it will show 0.999 instead of 1.0 886 887 if ( from < 0.999 ) { 888 from = ( from.toFixed(3) * 1000 ) + ' mL'; 889 } else { 890 from = ( from.toFixed(2) ) + ' L'; 891 } 892 893 if ( to == 0 ) { 894 to = '+'; 895 } else if ( to <= 1 ) { 896 to = ' - ' + ( ( to.toFixed(3) * 1000 ) - 1) + ' mL'; 897 } else { 898 to = ' - ' + ( to.toFixed(3) - 0.001 ) + ' L'; 899 } 900 901 return from + to; 902 }, 903 dollars: function (item) { 904 // minus 0.01 so it shows 9.99 instead of 10 905 var from = '$' + (item.from || 0).toFixed(2); 906 var to = null; 907 if (item.to == null || item.to == undefined) { 908 to = '+'; 909 } else { 910 to = ' - ' + (item.to - 0.01).toFixed(2); 911 } 912 return from + to; 913 } 914 }; 915 916 function isSelectedUpdate(section) { 917 $this.LastSection = section.key; 918 919 if (!$this.SlideoutProducts()) { 920 // window.scrollTo(0, 0); 921 } 922 923 $this.GrabProducts(1, true); 924 } 925 926 var AggregatorFormatters = { 927 range: function (key, section, item) { 928 var unit = (BCLS.Config.ProductFilterDefinitionsUnits[key] || 'raw'); 929 var isSelected = ko.observable(false); 930 isSelected.subscribe(isSelectedUpdate.bind(null, section)); 931 932 return { 933 isSelected: isSelected, 934 displayValue: (DisplayValueFormatters[unit] ? 935 DisplayValueFormatters[unit](item) : 936 (item.from + ' - ' + item.to)), 937 item: item, 938 hide: (key == 'Price' ? item.doc_count == 0 : false) 939 }; 940 }, 941 terms: function (key, section, item) { 942 var unit = (BCLS.Config.ProductFilterDefinitionsUnits[key] || 'raw'); 943 var isSelected = ko.observable(false); 944 var keyCapitalized = toCapitalized(item.key); 945 isSelected.subscribe(isSelectedUpdate.bind(null, section)); 946 947 return { 948 displayValue: (DisplayValueFormatters[unit] ? DisplayValueFormatters[unit](item) : item.key), 949 isSelected: isSelected, 950 item: item, 951 }; 952 } 953 }; 954 955 this.ToggleSection = function (section) { 956 var curVal = section.expanded(); 957 958 if ($this.SlideoutProducts() && !curVal) { 959 _.forEach($this.FilterAggregationsSummary(), function (item) { item.expanded(false); }); 960 } 961 962 section.expanded(!curVal); 963 964 if ($this.SlideoutProducts() && !curVal) { 965 jQuery('.filters-container')[0].scrollTop = jQuery(".filters-container h3[data-skey='" + section.key + "']")[0].offsetTop; 966 } 967 }; 968 969 this.HasCheckedItems = function (section) { 970 return _.reduce(section.Items, function (ag, item) { return item.isSelected() || ag; }, false); 971 }; 972 973 this.BuildSummaryItem = function (item, key) { 974 var type = _.keys(BCLS.Config.ProductFilterDefinitions.aggs[key])[0]; 975 var index = _.keys(BCLS.Config.ProductFilterDefinitions.aggs).indexOf(key); 976 var keyName = (BCLS.Config.ProductFilterDefinitions.aggs[key].terms || BCLS.Config.ProductFilterDefinitions.aggs[key].range).field; 977 978 var section = { 979 key: keyName, 980 type: type, 981 expanded: ko.observable(!($this.FieldsToCollapse.indexOf(key) > -1)), 982 expandMoreItems: ko.observable(false), 983 SummaryHeader: key, // .replace(/\-/g, ' ') 984 Items: null, 985 order: index 986 }; 987 988 var items = _.map(item.buckets, AggregatorFormatters[type].bind(null, key, section)); 989 section.Items = items; 990 991 let paramGroup = getParameterByName('group'); 992 let paramCategoryclass = getParameterByName('categoryclass'); 993 let paramType = getParameterByName('type') ? getParameterByName('type').split(',') : [];; 994 let paramSpecial = getParameterByName('special') ? getParameterByName('special').split(',') : []; 995 let paramCert = getParameterByName('cert') ? getParameterByName('cert').split(',') : []; 996 let paramBeerType = getParameterByName('maincategory') ? getParameterByName('maincategory').split(',') : []; 997 998 if (paramGroup == 'sale' || paramGroup == 'promotions' ) { 999 switch (key) { 1000 case 'Category': 1001 sortedItems = []; 1002 _.each(section.Items, function (filter) { 1003 switch (filter.displayValue) { 1004 case 'Wine': 1005 sortedItems[0] = filter; 1006 break; 1007 case 'Beer': 1008 sortedItems[1] = filter; 1009 break; 1010 case 'Spirits': 1011 sortedItems[2] = filter; 1012 break; 1013 case 'Coolers & Ciders': 1014 sortedItems[3] = filter; 1015 break; 1016 default: 1017 break; 1018 } 1019 }); 1020 section.Items = sortedItems; 1021 break; 1022 case 'Red Varietal': 1023 case 'White Varietal': 1024 if (paramCategoryclass == 'wine') { 1025 break; 1026 } 1027 section.Items = []; 1028 break; 1029 case 'Type': 1030 if (paramCategoryclass == 'spirits' || paramCategoryclass == 'wine' || paramCategoryclass == 'coolers & ciders') { 1031 break; 1032 } 1033 section.Items = []; 1034 break; 1035 case 'Type ': 1036 if (paramCategoryclass == 'beer') { 1037 break; 1038 } 1039 section.Items = []; 1040 break; 1041 case 'Sub-type': 1042 if (paramCategoryclass == 'beer' && paramBeerType.includes('domestic beer')) { 1043 break; 1044 } 1045 section.Items = []; 1046 break; 1047 case 'Style': 1048 if (paramCategoryclass == 'beer') { 1049 break; 1050 } 1051 section.Items = []; 1052 break; 1053 case 'Whisky': 1054 if (paramType.includes('whisky / whiskey')) { 1055 break; 1056 } 1057 section.Items = []; 1058 break; 1059 default: 1060 break; 1061 } 1062 1063 } else { 1064 if (key == 'Category') { 1065 section.Items = []; 1066 } 1067 } 1068 1069 // hide all other temporary featured promotions 1070 if (key == 'Featured') { 1071 section.Items = _.map(section.Items, function (filter) { 1072 switch(filter.displayValue) { 1073 case 'BC VQA': 1074 case 'BCL Select': 1075 case 'New Product': 1076 case 'On Sale': 1077 return filter; 1078 default: 1079 filter.hide = true; 1080 filter.item.doc_count = 0; 1081 return filter; 1082 } 1083 }) 1084 } 1085 1086 // hide custom BC VQA & VQA cert field filter in Other 1087 if (key == 'Other') { 1088 section.Items = _.map(section.Items, function (filter) { 1089 switch(filter.displayValue) { 1090 case 'BC VQA': 1091 filter.hide = true; 1092 filter.item.doc_count = 0; 1093 return filter; 1094 case 'All VQA': 1095 if (paramSpecial.includes('bc vqa') || paramCert.includes('vqa ontario') ) { 1096 filter.hide = true; 1097 filter.item.doc_count = 0; 1098 } 1099 return filter 1100 default: 1101 return filter; 1102 } 1103 }) 1104 } 1105 1106 return section; 1107 }; 1108 1109 this.IncrementPage = function (inc) { 1110 var nextPage = $this.Page() + (inc || 1); 1111 if (nextPage > $this.TotalPages() || nextPage < 1) { return; } 1112 1113 $this.Page(nextPage); 1114 $this.GrabProducts(nextPage, true, true); 1115 }; 1116 1117 this.SetMobileFilterHeight = function () { 1118 // This calculation is for mobile filters: 1119 var windowHeight = jQuery(window).height(); 1120 var filtersOffset = jQuery('.filters-column').offset().top;
1121 var clearApplyHeight = jQuery('.clear-apply-filter-container').height(); 1122 1123 1124 jQuery('.filters-container').css('height', (windowHeight - filtersOffset - clearApplyHeight) + 'px'); 1125 jQuery('body').css({height: windowHeight + 'px', overflow: 'hidden'}); 1126 }; 1127 1128 $this.SlideoutProducts.subscribe(function (val) { 1129 if (val) { 1130 _.forEach($this.FilterAggregationsSummary(), function (item) { item.expanded(false); }); 1131 // window.scrollTo(0, 0); 1132 $this.SetMobileFilterHeight(); 1133 } 1134 else { 1135 jQuery('.filters-container').css('height', 'auto'); 1136 jQuery('body').css({height: 'auto', overflow: 'visible'}); 1137 jQuery('.bcls-main-container').css({position: 'static'/* , "padding-top": $this.MainContainerDefaultPadding */}); 1138 } 1139 }); 1140 1141 $this.ToggleSubItemsExpanded = function (item) { 1142 item.expandMoreItems(!item.expandMoreItems()); 1143 }; 1144 1145 jQuery(window).resize(function () { 1146 if ($this.SlideoutProducts()) { 1147 $this.SetMobileFilterHeight(); 1148 } 1149 }); 1150 1151 this.getCategories = function (filterKeys) { 1152 var SubCategory = []; 1153 var SubSubCategory = []; 1154 var Style = []; 1155 var group = $this.breadcrumbGroup; 1156 var subsub_item = null; 1157 var subsub_item_key = null; 1158 // filterKeys will be null if user clicks menu, else redirected by filters 1159 if ( filterKeys == null ) { 1160 var category_description = getParameterByName('categoryclass'); 1161 var type = getParameterByName('type'); 1162 var subtype = getParameterByName('subtype'); 1163 var special = getParameterByName('special'); 1164 var countryName = getParameterByName('country'); 1165 var region = getParameterByName('region'); 1166 var red = getParameterByName('red'); 1167 var white = getParameterByName('white'); 1168 var cert = getParameterByName('cert'); 1169 var maincategory = getParameterByName('maincategory'); 1170 var subcategory = getParameterByName('subcategory'); 1171 var style = getParameterByName('style'); 1172 } else { 1173 var category_description = filterKeys['category.description'] ? filterKeys['category.description'] : null; 1174 var type = filterKeys.productType ? filterKeys.productType : null; 1175 var subtype = filterKeys['class.description'] ? filterKeys['class.description'] : null; 1176 var special = filterKeys.featured ? filterKeys.featured : null; 1177 var countryName = filterKeys['countryName.raw'] ? filterKeys['countryName.raw'] : null; 1178 var region = filterKeys['region.raw'] ? filterKeys['region.raw'] : null; 1179 var red = filterKeys.redVarietal ? filterKeys.redVarietal : null; 1180 var white = filterKeys.whiteVarietal ? filterKeys.whiteVarietal : null; 1181 var cert = filterKeys['certificates'] ? filterKeys['certificates'] : null; 1182 var maincategory = filterKeys['productCategory'] ? filterKeys['productCategory'] : null; 1183 var subcategory = filterKeys['productSubCategory'] ? filterKeys['productSubCategory'] : null; 1184 var style = filterKeys['style'] ? filterKeys['style'] : null; 1185 1186 if (maincategory !== null) { 1187 type = filterKeys.productCategory; 1188 } 1189 } 1190 1191 if ( type ) { 1192 if(cidersOrigin == 'domestic cider'){ 1193 type = 'domestic cider' 1194 } 1195 if(cidersOrigin == 'import cider'){ 1196 type = 'import cider' 1197 } 1198 SubCategory = type; 1199 } 1200 if ( maincategory ) { 1201 SubCategory = maincategory; 1202 } 1203 1204 if ( subtype ) { 1205 subsub_item_key = 'subtype'; 1206 SubSubCategory = subtype; 1207 } 1208 if ( red ) { 1209 subsub_item_key = 'red'; 1210 SubSubCategory = red; 1211 } 1212 if ( white ) { 1213 subsub_item_key = 'white'; 1214 SubSubCategory = white; 1215 } 1216 1217 // overriding sub and subsub depends on group 1218 if ( group == 'country' || group == 'all countries' ) { 1219 SubCategory = ['country']; 1220 subsub_item_key = 'country'; 1221 SubSubCategory = countryName; 1222 } 1223 1224 if (countryName) { 1225 SubSubCategory = countryName; 1226 } 1227 1228 if (maincategory) { 1229 type = maincategory; 1230 } 1231 if (subcategory) { 1232 subsub_item_key = 'subcategory'; 1233 SubSubCategory = subcategory; 1234 } 1235 1236 if (style) { 1237 Style = style; 1238 } 1239 1240 if (group == 'promotions') { 1241 SubCategory = ['promotions']; 1242 if ( special != null ) { 1243 subsub_item_key = 'special'; 1244 SubSubCategory = special; 1245 } 1246 } 1247 1248 if (group == 'sale') { 1249 SubCategory = ['sale']; 1250 if (category_description != null) { 1251 subsub_item_key = 'categoryclass'; 1252 SubSubCategory = category_description; 1253 } else { 1254 subsub_item_key = ''; 1255 SubSubCategory = ''; 1256 } 1257 Style = ''; 1258 } 1259 if (group == 'featured') { 1260 SubCategory = ['promotions']; 1261 SubSubCategory = ['featured']; 1262 } 1263 1264 if ( group == 'other wine' ) { 1265 SubCategory = ['other wine']; 1266 if(type === 'rose') { 1267 type = 'rose wine' 1268 } 1269 SubSubCategory = type; 1270 subsub_item_key = 'type'; 1271 if(type !== null) { 1272 if(type[0] === 'Other Wine') { 1273 SubSubCategory = ['all other wine']; 1274 } 1275 } 1276 // key for attributes (All VQA, BC VQA, VQA Ontario, Kosher, Organic, De-Alcoholized Wine) is cert 1277 if(type == null && cert != ''){ 1278 SubSubCategory = cert; 1279 subsub_item_key = 'cert'; 1280 } 1281 } 1282 1283 // BC VQA overrides the other type as Sub Category because there is another nested Other Wine 1284 if (special) { 1285 if (special == 'bc vqa' || (special.length == 1 && special[0].toLowerCase() == 'bc vqa')) { 1286 SubCategory = ['bc vqa']; 1287 } 1288 } 1289 1290 if ( Array.isArray(SubCategory) ) { 1291 SubCategory = SubCategory.join(','); 1292 } 1293 1294 if ( Array.isArray(SubSubCategory) ) { 1295 SubSubCategory = SubSubCategory.join(','); 1296 } 1297 1298 if ( Array.isArray(Style) ) { 1299 Style = Style.join(','); 1300 } 1301 1302 if ( SubCategory !== null && SubCategory !== undefined ) { 1303 SubCategory = SubCategory.replace('null,', '').toLowerCase(); 1304 } 1305 1306 if ( SubSubCategory !== null && SubSubCategory !== undefined ) { 1307 SubSubCategory = SubSubCategory.replace('null,', '').toLowerCase(); 1308 } 1309 1310 if ( Style !== null && Style !== undefined ) { 1311 Style = Style.replace('null,', '').toLowerCase(); 1312 } 1313 1314 if ( SubSubCategory !== null && SubSubCategory !== undefined && SubSubCategory.indexOf(',') >= 0 ) { 1315 SubSubCategory = null; 1316 } 1317 1318 if ( SubCategory !== null && SubCategory !== undefined && SubCategory.indexOf(',') >= 0 ) { 1319 SubCategory = null; 1320 SubSubCategory = null; 1321 } 1322 1323 if ( Style !== null && Style !== undefined && Style.indexOf(',') >= 0 ) { 1324 Style = null; 1325 // SubSubCategory = null; 1326 } 1327 1328 if ( subsub_item_key !== null && SubSubCategory !== undefined && SubSubCategory !== null ) { 1329 subsub_item = { 1330 key: subsub_item_key, 1331 term: SubSubCategory 1332 }; 1333 } 1334 1335 // override special breadcrumb names 1336 if ( SubSubCategory == 'exclusive' ) { 1337 SubSubCategory = 'BCL Select'; 1338 } 1339 if ( SubSubCategory == 'bcl select' ) { 1340 SubSubCategory = 'BCL Select'; 1341 } 1342 if ( SubSubCategory == 'new product' ) { 1343 SubSubCategory = "what's new"; 1344 } 1345 1346 $this.Category(getParameterByName('category')); 1347 $this.SubCategory(SubCategory); 1348 $this.SubSubCategory(SubSubCategory); 1349 $this.Style(Style); 1350 $this.updateSubCategoryUrl(); 1351 $this.updateSubSubCategoryUrl(subsub_item); 1352 $this.updateStyleUrl(); 1353 1354 }; 1355 1356 (function Init() { 1357 1358 // We create a case insensitive function for finding menu elements for highlighting. 1359 // modified from: http://stackoverflow.com/a/40475075 1360 jQuery.expr[':'].ContainsInsensitive = jQuery.expr.createPseudo(function (arg) { 1361 return function (elem) { 1362 return jQuery(elem).text().toLowerCase().indexOf(arg.toLowerCase()) >= 0; 1363 }; 1364 }); 1365 1366 1367 1368 $this.getCategories(null); 1369 var promoEl = jQuery('#promotionData'); 1370 if (promoEl !== null && promoEl !== undefined && promoEl.val() !== null && promoEl.val() !== undefined) { 1371 $this.PromotionData(JSON.parse(promoEl.val())); 1372 } else { 1373 $this.PromotionData(null) 1374 } 1375 1376 $this.Category(getParameterByName('category')); 1377 1378 $this.SearchQuery(getParameterByName('search')); 1379 1380 1381 if ($this.SearchQuery()) { 1382 // $this.SearchQuery($this.SearchQuery().replace('\"', '').replace(/"/g, '')); 1383 $this.SearchTerms($this.SearchQuery().split(' ')); 1384 $this.SearchQuery($this.SearchQuery()); 1385 jQuery('#header-search').val($this.SearchQuery()); 1386 jQuery('#mobile-header-search').val($this.SearchQuery()); 1387 } 1388 1389 if (window.localStorage && window.localStorage.getItem($this.LS_FILTER_KEY)) { 1390 if (getParameterByName('group') !== 'sale' && getParameterByName('group') !== 'promotions' ) { 1391 var filterData = JSON.parse(window.localStorage.getItem($this.LS_KEY)); 1392 _.each(filterData, function (item) { 1393 item.expanded = ko.observable(item.expanded); 1394 item.expandMoreItems = ko.observable(item.expandMoreItems); 1395 _.each(item.Items, function (item) { item.isSelected = ko.observable(item.isSelected); item.isSelected.subscribe($this.GrabProducts.bind(null, 1, true)); }); 1396 }); 1397 $this.FilterAggregationsSummary(filterData); 1398 $this.BackButtonRestore = true; 1399 } 1400 } 1401 1402 $this.GrabProducts($this.Page(), true); 1403 1404 jQuery('body').addClass('bcls-product-list-page'); 1405 1406 setTimeout(function () { 1407 jQuery('#superfish-main-toggle').click(function () { 1408 $this.SlideoutProducts(false); 1409 }); 1410 }, 200); 1411 1412 var superfish = jQuery('#superfish-main'); 1413 1414 if ($this.Category() != null && $this.Category() !== '') { 1415 // toUpperCase works fine for the main menu. Consider using the Case Insensitive version for consistency. 1416 var main_level_link = superfish.find("li > a:contains('" + $this.Category().toUpperCase() + "')"); 1417 main_level_link.addClass('active'); 1418 1419 var main_level = main_level_link.parent(); 1420 main_level.addClass('active'); 1421 1422 if ($this.SubCategory() != null && $this.SubCategory() !== '' ) { 1423 sub_level_link = main_level.find("ul > li > .sf-depth-2:ContainsInsensitive('" + $this.SubCategory() + "')"); 1424 sub_level_link.addClass('active'); 1425 sub_level_link.parent().addClass('active'); // TODO: do we need to do this? 1426 } 1427 1428 if ($this.SubSubCategory() != null && $this.SubSubCategory() !== '' ) { 1429 subsub_level_link = main_level.find("ul > li > .sf-depth-3:ContainsInsensitive('" + $this.SubSubCategory() + "')"); 1430 subsub_level_link.addClass('active'); 1431 subsub_level_link.parent().addClass('active'); // TODO: do we need to do this? 1432 } 1433 } 1434 1435 // Sale page filters uses SubCategory for the first breadcrumb and SubSubCategory for the children (ie. Home / Sale / Wine) 1436 if ( $this.SubCategory() == 'sale') { 1437 let main_level_link = superfish.find("li > a:contains('" + $this.SubCategory().toUpperCase() + "')"); 1438 // let main_level_link = superfish.find("li > a:contains('SALE')"); 1439 main_level_link.addClass('active'); 1440 let main_level = main_level_link.parent(); 1441 if ($this.SubSubCategory() != null && $this.SubSubCategory() !== '' ) { 1442 sub_level_link = main_level.find("ul > li > .sf-depth-2:ContainsInsensitive('" + $this.SubSubCategory() + "')"); 1443 sub_level_link.addClass('active'); 1444 sub_level_link.parent().addClass('active'); // TODO: do we need to do this? 1445 } 1446 } 1447 1448 })(); 1449}; 1450 1451function toCapitalized(string) 1452{ 1453 return string.charAt(0).toUpperCase() + string.slice(1); 1454} 1455 1456jQuery(document).ready( function($) { 1457 1458 if ($('.path-promotion li.featured li.Exclusive').length || 1459 $('.path-promotion li.featured li.On.Sale').length || 1460 $('.path-promotion li.featured li.BCL.Select').length || 1461 $('.path-promotion li.featured li.New.Product').length ) 1462 { 1463 $('.path-promotion').addClass('show-featured'); 1464 } 1465});
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.