1 2function reloadAllLinkedFieldsExtra(renderEngine) { //TODO: MOVE, move to separate publisher-only file 3 var otherFields = []; 4 jQuery("div.PubFieldMenu[data-include-linked-field-content='True']").each(function (index, item) { 5 var fieldIdFound = jQuery(item).data("fieldid"); 6 otherFields.push(fieldIdFound); 7 }); 8 renderEngine.reloadPageCallback(otherFields); 9}; 10 11function reloadSingleElement(renderEngine, nodeId, activePlid, area, fieldId, element) { //TODO: MOVE, move to separate publisher-only file 12 var item = jQuery("#Field_" + fieldId + " div.WebPubElement[data-elementid=" + element + "]"); 13 if (item.length <= 0) {//implies this element has not been rendered in the field. Let us add a placholder at the end of the field, or if this field contains 14 //linked content, we must add it in front of all the dynamic content 15 var field = jQuery("div.ajax-field[data-field-id=" + fieldId + "]"); 16 var placeholder = "<div id='plcholder" + fieldId + "' data-fieldid='" + fieldId + "' class='WebPubElement'/>"; 17 if (field.length > 0) { 18 var linkedChildren = field.children(".WebPubElement.linked-element"); 19 if (linkedChildren.length > 0) { 20 jQuery(linkedChildren[0]).before(placeholder); 21 } 22 else { 23 field.append(placeholder); 24 25 } 26 item = jQuery("#plcholder" + fieldId); 27 } 28 } 29 if (nodeId == null) 30 nodeId = jQuery('#hidden-nodeid').text(); 31 32 var width = Math.round(jQuery(item).width()); 33 if (item.length > 0) { 34 var params = { 35 NodeId: nodeId, 36 Width: width, 37 ActivePlid: activePlid, 38 AreaName: area, 39 FieldId: fieldId, 40 ElementId: element, 41 ForceNormalMode: false, 42 ForcedLayoutId: 0 43 }; 44 renderEngine.fieldRenderService.PostAction("RenderSingleElement", params).then(function (result) { 45 if (result && result.Success) { 46 jQuery(item).replaceWith(result.Content); 47 } 48 }); 49 } 50}; 51 52function reloadDummyFields(renderEngine, deviceSize) { 53
54 //first, find the area that contains the dummy fields 55 var container = jQuery('.layout-picker').find('.load-later'); 56 if (container.length > 0) { 57 var nodeId = jQuery('#hidden-nodeid').text(); 58 var param = { 59 areaName: 'LayoutPicker', 60 nodeId: nodeId, 61 isEdm: false, 62 deviceSize: deviceSize 63 }; 64 renderEngine.service.GetAction("RenderAreaFramework", param).then( 65 function (result) { 66 if (result != undefined && result.length > 0) { 67 container.html(result); 68 } 69 renderEngine.updateFields(".ajax-field.not-loaded-dummy", "", false, false, true, 0); 70 scaleLayoutPicker(); 71 }); 72 73 } 74 //then fetch the new field framework as it might have been changed 75 //then update the content of the fields 76 77}; 78 79function scaleLayoutPicker () { 80 var layoutPickerContainer = jQuery(".PublisherContainer.layout-picker"); 81 if (layoutPickerContainer != null) { 82 var layoutSelectorFields = layoutPickerContainer.find('.web-pub-field.container.dummy'); 83 84 layoutSelectorFields.each(function (index, element) { 85 var myField = jQuery(element) 86 var contentHeight = myField.height(); 87 var contentWidth = myField.width(); 88 var availableWidth = 170; 89 var availableHeight = 100; 90 var scale = Math.min( 91 availableWidth / contentWidth, 92 availableHeight / contentHeight 93 ); 94 //todo: find out why the height isn't always correct 95 myField.css("position", "absolute"); 96 97 var translateVertical = "0 0px"; 98 myField.css("transform-origin", translateVertical); 99 100 myField.css("transform", "scale(" + scale + ")"); 101 var layoutName = myField.data("layout-name"); 102 103 if (myField.hasClass("selected")) { 104 jQuery(myField).wrap("<div class='layout-picker-wrapper selected'></div>"); 105 } else { 106 jQuery(myField).wrap("<div class='layout-picker-wrapper'></div>"); 107 } 108 jQuery(myField.parent()).before("<div class='layout-name'>" + layoutName + "</div>"); 109 110 }); 111 } 112}; 113 114function replaceFieldExtra(renderEngine, fieldId, nodeId, isEdm) {//todo: move to publisher script 115 var areaContainer = jQuery("#Field_" + fieldId).closest("div.area-content-container");//[data-area-name='" +areaName + "']"); 116 if (areaContainer.length > 0) { 117 if (nodeId == undefined || nodeId == 0) 118 nodeId = jQuery('#hidden-nodeid').text(); 119 if (isEdm == undefined) 120 isEdm = false; 121 122 var width = Math.round(jQuery(areaContainer).width()); 123 var param = { 124 FieldId: fieldId, 125 NodeId: nodeId, 126 IsEdm: isEdm, 127 Width: width, 128 ActivePlid: 0, 129 ActiveArticleId: 0, 130 AreaUniqueId: areaContainer[0].id 131 }; 132 133 renderEngine.fieldRenderService.PostAction("RenderField", param).then(function (result) { 134 if (result && result.Response.length > 0) { 135 jQuery("#Field_" + fieldId).replaceWith(result.Response); 136 EnableLinksForArticlesWithBackground(); 137 } 138 }); 139 140 } 141}; 142 143function addFieldToAreaExtra(renderEngine, areaName, fieldId, nodeId) {//todo: move to publisher script 144 var areaContainer = jQuery("div.area-content-container[data-area-name='" + areaName + "']"); 145 if (areaContainer.length > 0) { 146 var width = Math.round(jQuery(areaContainer).width()); 147 var param = { 148 AreaName: areaName, 149 FieldId: fieldId, 150 NodeId: nodeId, 151 Width: width, 152 ActivePlid: 0, 153 ActiveArticleId: 0, 154 AreaUniqueId: areaContainer[0].id 155 }; 156 157 renderEngine.fieldRenderService.PostAction("RenderField", param).then(function (result) { 158 if (result && result.Response.length > 0) { 159 if (result.AddToEnd) 160 jQuery(areaContainer).append(result.Response); 161 else { 162 var existingFields = jQuery(areaContainer).find(".web-pub-field"); 163 if (existingFields.length > 0) { 164 jQuery(existingFields[0]).before(result.Response); 165 } 166 else $(areaContainer).append(result.Response); 167 }
168 EnableLinksForArticlesWithBackground(); 169 } 170 }); 171 172 } 173}; 174 175//todo: move to another file (getLibrary call from RenderFilter) 176function fetchAttributeValues(renderEngine, attributeId, target, targetId, nodeId, fieldId) { 177 var queryFilterParam = renderEngine.getParameterByName("Filter"); 178 var queryMinParam = renderEngine.getParameterByName("Min"); 179 var queryMaxParam = renderEngine.getParameterByName("Max"); 180 var pageIndex = renderEngine.getParameterByName("pageID"); 181 var fieldRequestFilter = { 182 NodeId: nodeId, 183 Url: document.location.pathname + document.location.search, 184 Filter: queryFilterParam, 185 MinPrice: queryMinParam, 186 MaxPrice: queryMaxParam, 187 SearchString: renderEngine.getParameterByName("q"), 188 ClientId: targetId, 189 PageIndex: pageIndex, 190 FilterCacheKey: '' 191 } 192 193 renderEngine.service.PostAction("RenderAttribute", { AttributeId: attributeId, FieldId: fieldId, RequestFilter: fieldRequestFilter }).then( 194 function (result) { 195 if (result != null) { 196 updateAttributeContent(result); 197 } 198 } 199 ); 200}; 201 202function updateAttributeContent (result) { 203 if (result.Success) { 204 $('#' + result.ClientId).html(result.Response); 205 } 206}; 207function toggleGroupVariants(renderEngine, obj) { 208 try { 209 var data = { group: obj.checked }; 210 211 jQuery("div.ajax-field[data-field-is-productlist=1]").data("grouped-variants", obj.checked); 212 213 var service = new WebApiService("AttributeFilter"); 214 service.GetAction("ToggleGroupVariants", data).then(function (result) { 215 var newUrl = renderEngine.getCurrentFirstPage(); 216 renderEngine.CurrentPageNumber = 1; 217 window.history.pushState(newUrl, '', newUrl); 218 renderEngine.SetAllowedUseOfProductCache(false); 219 renderEngine.reloadPageListingOnlyCallback(false); 220 }); 221 } catch (e) { 222 alert("Exception: " + e); 223 } 224}; 225 226function toggleStockMode (renderEngine, obj) { 227 try { 228 var data = { show: obj.checked }; 229 var service = new WebApiService("AttributeFilter") 230 service.GetAction("ToggleShowOnlyStock", data).then(function (result) { 231 renderEngine.CurrentPageNumber = 1; 232 renderEngine.resetAutoScrolledPages(); 233 renderEngine.SetAllowedUseOfProductCache(false); 234 var newUrl = renderEngine.getCurrentFirstPage(); 235 renderEngine.CurrentPageNumber = 1; 236 window.history.pushState(newUrl, '', newUrl); 237 renderEngine.reloadPageListingOnlyCallback(false); 238 239 }); 240 } catch (e) { 241 alert("Exception: " + e); 242 } 243}; 244 245function toggleStockModeFjernlager (renderEngine, obj) { 246 try { 247 var data = { show: obj.checked }; 248 var service = new WebApiService("AttributeFilter") 249 service.GetAction("ToggleShowOnlyStockFjernlager", data).then(function (result) { 250 renderEngine.CurrentPageNumber = 1; 251 renderEngine.resetAutoScrolledPages(); 252 renderEngine.SetAllowedUseOfProductCache(false); 253 var newUrl = renderEngine.getCurrentFirstPage(); 254 renderEngine.CurrentPageNumber = 1; 255 window.history.pushState(newUrl, '', newUrl); 256 renderEngine.reloadPageListingOnlyCallback(false); 257 }); 258 } catch (e) { 259 alert("Exception: " + e); 260 } 261}; 262 263 264function removeAttributeExtra(url, parsedFilter) { 265 var parsedUrl = decodeURIComponent(url); 266 var newLocation = parsedUrl.replace(parsedFilter, ""); 267 if (newLocation.substring(newLocation.length - 1) === '|') //find pipe at the end (|) 268 newLocation = newLocation.substring(0, newLocation.length - 1); 269 270 var indexOfPipeAfterFilter = newLocation.indexOf('Filter=|'); //check if there is a remaining pipe at the beginning of the filter 271 if (indexOfPipeAfterFilter > 1) 272 newLocation = newLocation.replace('|', ""); 273 274 275 if (newLocation.substring(newLocation.length - 7) === 'Filter=') 276 newLocation = newLocation.substring(0, newLocation.length - 7); 277 278 if (newLocation.substring(newLocation.length - 1) === '&') 279 newLocation = newLocation.substring(0, newLocation.length - 1); 280 281 if (newLocation.substring(newLocation.length - 1) === '?') 282 newLocation = newLocation.substring(0, newLocation.length - 1); 283 284 newLocation = newLocation.replace('||', '|'); //If we remove an attribute from the middle, we'll have an extra pipe which can be removed. 285 286 return newLocation; 287}; 288 289function removeAttributeValueFromLink(attributeID, attributeValueID) { 290 var url = new String(document.location.href); 291 url = decodeURIComponent(url); 292 var attValRegexp = new RegExp(attributeValueID, 'ig'); 293 var indexBeforeAttributeValue; 294 var m; 295 while (m = attValRegexp.exec(url)) { //Find all occurences of the string. It might be a substring of another, so we will check if it is an exact match 296 297 indexBeforeAttributeValue = m.index; 298 var endOfStringIndex = m.index + attributeValueID.length; //index of right after string... 299 300 if (endOfStringIndex >= url.length) { //we've reached end url, so it's OK 301 break; 302 //} else if (url.substr(indexBeforeAttributeValue + attributeValueID.length, 1).match(/(^|~)/i)) { //we've found the ^ character, so it's the end of the search string and thus OK 303 } else { 304 var substring = url.substr(indexBeforeAttributeValue + attributeValueID.length, 1); 305 if (substring === "~" || substring === "^") 306 break; 307 308 } 309 310 } 311 312 var newLink = ''; 313 if (url.substr(indexBeforeAttributeValue - 1, 1) == '^' || 314 url.substr(indexBeforeAttributeValue + attributeValueID.length, 1) == '^') { 315 if (url.substr(indexBeforeAttributeValue - 1, 1) == ':') { 316 newLink = url.replace(attributeValueID + '^', ''); 317 } else { 318 if ((indexBeforeAttributeValue + attributeValueID.length) >= url.length) { 319 newLink = url.substr(0, indexBeforeAttributeValue); 320 if (newLink.substr(newLink.length - 1, 1) === "^") 321 newLink = newLink.substr(0, newLink.length - 1); 322 } 323 else { 324 newLink = url.replace('^' + attributeValueID, ''); 325 } 326 327 } 328 return newLink; 329 } else { 330 return removeAttributeExtra(url, attributeID + ':' + attributeValueID); 331 } 332}; 333 334function addValueToQueryStringExtra(renderEngine, me, attributeId, attributeValueId) { 335 336 if (jQuery(me).hasClass("disabled")) 337 return;//shouldn't allow clicks when the disabled class i set. 338 339 jQuery(me).addClass("attribute-spinner"); 340 var loc = document.location.href; 341 var searchLoc = decodeURIComponent(renderEngine.getParameterByName('Filter')); 342 var newLocation = ""; 343 var attributeValueIdExisted = false; 344 if (searchLoc.length > 0) { 345 var currentAttributes = searchLoc.split('|'); 346 for (var i = 0; i < currentAttributes.length; i++) { 347 var attributeAndValues = currentAttributes[i].split(':'); 348 if (attributeAndValues.length >= 2) { 349 //first entry in array should be the attributeId and the second a list of attributeValues 350 if (attributeAndValues[0] === attributeId) { 351 var attributeValues = attributeAndValues[1].split('^'); 352 for (var j = 0; j < attributeValues.length; j++) { 353 var currentAttributeValueId = attributeValues[j];
354 if (currentAttributeValueId === attributeValueId) 355 attributeValueIdExisted = true; 356 } 357 } 358 } 359 } 360 361 362 } 363 scrollViewToTopOfPage(jQuery(me).parents("[data-scrolltime]").data("scrolltime")); 364 if (attributeValueIdExisted) { 365 newLocation = removeAttributeValueFromLink(attributeId, attributeValueId); 366 RemoveAttributeValueLinkFromDom(attributeValueId); 367 368 } else { 369 newLocation = encodeURI(CreateUrl(loc, attributeId + ':' + attributeValueId)); 370 var titleOfRemoved = me.text; 371 AddDivForRemovingAttributeValue(attributeValueId, attributeId, titleOfRemoved); 372 } 373 374 newLocation = RemovePageNumberFromLink(newLocation); 375 376 window.history.pushState(attributeId + ':' + attributeValueId, document.title, newLocation); 377 378 var searchLocAfterFiltering = decodeURIComponent(renderEngine.getParameterByName('Filter')); 379 380 informShopOfFilterActivation(renderEngine, searchLocAfterFiltering); 381 382 renderEngine.CurrentPageNumber = 1; 383 setInternalListOfOpenFilters(renderEngine); 384 renderEngine.updateSelectedAttributeListVisibility(); 385 renderEngine.updateFields(".ajax-field", "#AttributeListBox", true, false, false, 0); 386}; 387 388function informShopOfFilterActivation(renderEngine, currentFilter) { 389 var data = { clientHasFilter: currentFilter !== null && currentFilter !== undefined && currentFilter.length > 0 }; 390 renderEngine.filterService.GetAction("SetFilterActive", data).then(function (result) { 391 jQuery("#cbxGroupVariants").prop("checked", result); 392 }); 393}; 394 395function setInternalListOfOpenFilters(renderEngine) { 396 var openAttributes = jQuery("#AttributeListBox div.AttributeBox.show-extra-values"); 397 var openAttributesList = []; 398 openAttributes.each(function (index, item) { 399 openAttributesList.push(jQuery(item).data("attribute-id")); 400 }); 401 renderEngine.openAttributesList = openAttributesList; 402 403}; 404 405//Removes filter and keep parameters from the url. 406function RemoveFilter() { 407 var url = new String(document.location.href); 408 url = url.replace(keepFilterOpen, ""); 409 var startIndex = url.indexOf("&Filter=", 0); 410 var skipone = startIndex >= 0 ? 1 : 0; 411 412 if (startIndex < 0) 413 startIndex = url.indexOf("Filter=", 0); 414 415 var endIndex = url.indexOf("&", startIndex + skipone); 416 417 418 if (startIndex >= 0) { 419 var newUrl = url.substring(0, startIndex); 420 421 if (endIndex > 0) 422 newUrl = newUrl + url.substring(endIndex, url.length - 1); 423 424 newUrl = RemovePageNumberFromLink(newUrl); 425 426 RemoveAllAttributeValueLinkFromDom(); 427 428 mcWeb.ajaxRenderEngine.CurrentPageNumber = 1; 429 window.history.pushState(newUrl, '', newUrl); 430 mcWeb.ajaxRenderEngine.updateSelectedAttributeListVisibility(); 431 mcWeb.ajaxRenderEngine.reloadPageListingOnlyCallback(false);//todo: sørg for at denne ber om å rendre filteret på nytt når den kalles her i fra. 432 //reloadPageCallback(); 433 //document.location = newUrl; 434 } else 435 location.reload(true); 436} 437 438function RemoveAttributeValueLinkFromDom(attributeValueId) { 439 jQuery("div.SelectedAttribute[data-attribute-value-id='" + attributeValueId + "']").remove(); 440} 441 442function RemoveAllAttributeValueLinkFromDom() { 443 jQuery("div.SelectedAttribute").remove(); 444 jQuery("div.SearchFilterAttributes .attribute-value a.selected").removeClass("selected"); 445} 446 447 448function AddDivForRemovingAttributeValue(attributeValueId, attributeId, title) { 449 jQuery("div.SelectedAttributeBox .filter-selection").append("<div class=\"SelectedAttribute\" data-attribute-value-id=\"" + 450 attributeValueId + "\"> <a onclick=\"mcWeb.ajaxRenderEngine.addValueToQueryString(this,'" + 451 attributeId + "','" + attributeValueId + "');\" title=\"" + title + "\">" + title + "</a></div>"); 452} 453 454this.fetchAttributeValuesExtra = function (renderEngine, attributeId, targetId, nodeId, fieldId) { 455 var queryFilterParam = renderEngine.getParameterByName("Filter"); 456 var queryMinParam = renderEngine.getParameterByName("Min"); 457 var queryMaxParam = renderEngine.getParameterByName("Max"); 458 var pageIndex = renderEngine.getParameterByName("pageID"); 459 var fieldRequestFilter = { 460 NodeId: nodeId, 461 Url: document.location.pathname + document.location.search, 462 Filter: queryFilterParam, 463 MinPrice: queryMinParam, 464 MaxPrice: queryMaxParam, 465 SearchString: renderEngine.getParameterByName("q"), 466 ClientId: targetId, 467 PageIndex: pageIndex, 468 FilterCacheKey: '' 469 } 470 471 renderEngine.service.PostAction("RenderAttribute", { AttributeId: attributeId, FieldId: fieldId, RequestFilter: fieldRequestFilter }).then( 472 function (result) { 473 if (result != null) { 474 updateAttributeContent(result); 475 } 476 } 477 ); 478}; 479 480 481function CreateUrl(currentUrl, valToAdd) { 482 var url = decodeURIComponent(currentUrl); 483 484 url = RemovePageNumberFromLink(url); 485 486 var filterIndex = url.indexOf('Filter='); 487 if (filterIndex >= 0) { 488 filterIndex += 7; 489 var indexOfColonInNewValue = valToAdd.indexOf(':'); 490 491 var existingAttributeID = valToAdd.substr(0, indexOfColonInNewValue); 492 493 var startOfExistingAttributeIDInUrl = McIndexOf(url, existingAttributeID + ':'); 494 if (startOfExistingAttributeIDInUrl >= 0) { 495 var startOfUrl = url.substr(0, startOfExistingAttributeIDInUrl + existingAttributeID.length + 1); 496 var endOfUrl = url.substr(startOfExistingAttributeIDInUrl + existingAttributeID.length + 1, url.length); 497 var attributeValueID = valToAdd.substr(indexOfColonInNewValue + 1, valToAdd.length); 498 return startOfUrl + attributeValueID + '^' + endOfUrl; 499 500 } else { 501 return url.substring(0, filterIndex) + valToAdd + '|' + url.substring(filterIndex, url.length); 502 } 503 } else { 504 if (url.indexOf('?') < 0) { 505 url += '?'; 506 } else { 507 if (url.substr(url.length - 1, 1) != '&' && url.substr(url.length - 1, 1) != '?') 508 url += '&'; 509 } 510 511 url += 'Filter=' + valToAdd;
512 //url += 'Filter=' + valToAdd; 513 return url; 514 } 515} 516 517function replaceAll(find, replace, str) { 518 return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); 519}; 520 521function escapeRegExp(str) { 522 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 523}; 524 525function RemovePageNumberFromLink(url) { 526 var index = url.indexOf('pageID='); 527 if (index >= 0) { 528 var urlPartWithPageID = url.substring(index, url.length); 529 var urlPartWithoutPageID = urlPartWithPageID.substring(7, urlPartWithPageID.length); 530 var indexOfFirstAmpersand = urlPartWithoutPageID.indexOf('&', 1); 531 if (indexOfFirstAmpersand > 0) { 532 var tmp = urlPartWithoutPageID.substring(indexOfFirstAmpersand, urlPartWithoutPageID.length); 533 return tmp; 534 } else { 535 return replaceAll(urlPartWithPageID, '', url); 536 } 537 } else 538 return url; 539} 540 541function scrollViewToTopOfPage(scrolltime) { 542 if (scrolltime == null || scrolltime < 0) 543 return; 544 545 var scrollTo = jQuery(jQuery(".FieldSorter.CenterContentDynamicAdList")[0]); 546 if (scrollTo.length <= 0) 547 scrollTo = jQuery(jQuery(".FieldSorter.CenterContentDynamicProdListAlternate")[0]); 548 if (scrollTo.length === 0) 549 return; 550 551 552 var position = scrollTo.offset().top - 250; 553 jQuery([document.documentElement, document.body]).animate({ 554 scrollTop: position 555 }, scrolltime); 556 557 558}; 559 560function scrollToNextPageExtra(renderEngine, element) { 561 try { 562 var url = element.getAttribute("data-next-page-url"); 563 var nextPageIndex = parseInt(element.getAttribute("data-next-page-index")); 564 if (nextPageIndex > renderEngine.CurrentPageNumber) { 565 //CurrentPageNumber may be off when we started on page > 1. We must reset currentpage here since we know which is to be the next page 566 if (nextPageIndex > 1) 567 renderEngine.CurrentPageNumber = nextPageIndex - 1; 568 569 var title = element.getAttribute("title"); 570 window.history.pushState(url, document.title + ' - ' + title, url); 571 renderEngine.updateFields(".ajax-field[data-field-is-productlist=1]", 572 "#AttributeListBox", 573 true, 574 true, 575 false, 576 0, 577 nextPageIndex); //todo: check that we're actually only changing page, because otherwise we need to set the param doNotRenderFilter to false 578 updateScroller(renderEngine, element); 579 } 580 return false; //indicate navgiation is complete 581 } catch (e) { 582 return true; //must navigate using the link 583 } 584}; 585 586function updateScroller(renderEngine, element) { 587 588 renderEngine.service.GetAction("GetNextPageUrl", { currentUrl: jQuery(element).data("next-page-url"), currentIndex: renderEngine.CurrentPageNumber }).then( 589 function (result) { 590 if (result != null) { 591 renderEngine.CurrentPageNumber = renderEngine.CurrentPageNumber + 1; 592 if (renderEngine.CurrentPageNumber > renderEngine.HighestPageNumberSeen) 593 renderEngine.HighestPageNumberSeen = renderEngine.CurrentPageNumber; 594 595 jQuery(element).data("next-page-url", result); 596 var nextIndex = parseInt(jQuery(element).data("next-page-index")); 597 jQuery(element).data("next-page-index", nextIndex + 1); 598 599 } 600 } 601 ); 602}; 603 604function handleScrollExtra(renderEngine, mcUtils) { 605 if (renderEngine.HasMorePages && !renderEngine.LoadingFromScroll && !renderEngine.fieldUpdateInProgress && (renderEngine.PagingMode == 3 || renderEngine.AutoScrolledPages < 3)) { 606 doScrollHandling(renderEngine, mcUtils); 607 } 608 else if (renderEngine.HasMorePages && !renderEngine.LoadingFromScroll && renderEngine.fieldUpdateInProgress && (renderEngine.PagingMode == 3 || renderEngine.AutoScrolledPages < 3)) { 609 //need to delay the scroll handling and try again, in case we complete the ongoing field update and it subsequently needs to handle the scroll 610 setTimeout(function () { 611 if (!renderEngine.HasMorePages || renderEngine.LoadingFromScroll || renderEngine.fieldUpdateInProgress || renderEngine.PagingMode < 3 || renderEngine.AutoScrolledPages >= 3) 612 return; 613 614 doScrollHandling(renderEngine, mcUtils); 615 }, 500); 616 } 617}; 618 619function doScrollHandling(renderEngine, mcUtils) { 620 var scrollerContainer = jQuery(".field-paging-container"); 621 if (scrollerContainer.length > 0 && mcUtils.isElementInView(scrollerContainer)) { 622 var scrollerTag = jQuery(".field-paging-next:visible"); 623 if (scrollerTag != null && scrollerTag.length > 0 && mcUtils.isElementInView(scrollerTag)) { 624 renderEngine.LoadingFromScroll = true; //pause event-checking on scrolling 625 renderEngine.AutoScrolledPages = renderEngine.AutoScrolledPages + 1; 626 scrollToNextPageExtra(renderEngine, scrollerTag[0]); 627 } 628 } 629}; 630 631 632function startSaleCountDown($field) { 633 var timer = setInterval(function () { 634 635 var now = new Date().getTime(); 636 $field.find(".WebPubElement .sale-countdown").each(function (index) { 637 var salesCountdown = jQuery(this); 638 var endDate = new Date(salesCountdown.data("bid-expires")).getTime(); 639 var t = endDate - now; 640 641 if (t >= 0) { 642 var days = Math.floor(t / (1000 * 60 * 60 * 24)); 643 var hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 644 var mins = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)); 645 var secs = Math.floor((t % (1000 * 60)) / 1000); 646 647 jQuery(salesCountdown).find(".timer-days").html(days + 648 "<span class='label'>DAY(S)</span>"); 649 650 jQuery(salesCountdown).find(".timer-hours").html(("0" + hours).slice(-2) + 651 "<span class='label'>HR(S)</span>"); 652 653 jQuery(salesCountdown).find(".timer-mins").html(("0" + mins).slice(-2) + 654 "<span class='label'>MIN(S)</span>"); 655 656 jQuery(salesCountdown).find(".timer-secs").html(("0" + secs).slice(-2) + 657 "<span class='label'>SEC(S)</span>"); 658 } else { 659 //the price for this product should now be invalid 660 salesCountdown.removeClass("sale-countdown"); 661 salesCountdown.data("bid-expires", ""); 662 salesCountdown.html(''); 663 } 664 }); 665 666 }, 1000); 667} 668 669function fillLightboxWithContentExtra(renderEngine, fieldData, lightboxContainer) { 670 for (var i = 0; i < fieldData.Data.length; i++) { 671 var data = fieldData.Data[i]; 672 if (data.Response.length <= 0) { 673 continue; 674 } 675 data.targetField = jQuery('#' + data.ClientId); 676 if (data.targetField != null && data.targetField != undefined) { 677 //add a placeholder where the field was found, so we can put it back when the lightbox is closed 678 data.targetField.hide(); 679 jQuery(data.targetField).html(data.Response); 680 var fields = jQuery(data.targetField).closest(".web-pub-field.container, .web-pub-field.container-fluid"); 681 682 fields.after("<div style='display:none;' data-placeholder-id='" + fields[0].id + "'/>"); 683 var fieldPopupHtml = jQuery(fields).detach(); 684 lightboxContainer.append(fieldPopupHtml); 685 data.targetField.show(); 686 if (data.LoadFilter) { 687 updateFilterContentExtra(renderEngine,data); 688 689 } 690 renderEngine.refineInsertedContent(data.targetField, data); 691 if (fieldData.InitializeRoyalSlider) 692 InitializeRoyalSliderInAds("#" + data.ClientId + " .variant-slider"); 693 } 694 695 renderEngine.initialiseAdLinks(); 696 } 697}; 698 699function searchAtttributesExtra (target) { 700 jQuery(target).siblings().removeClass('search-hidden'); 701 702 const searchQuery = target.value.toLowerCase(); 703 704 if (searchQuery.length < 1) { 705 jQuery(target).parent().removeClass('search-show-extra-values'); 706 jQuery(target).siblings('a').removeClass('toggle-hidden'); 707 jQuery(target).siblings('a').show(); 708 return; 709 } 710 711 jQuery(target).parent().addClass('search-show-extra-values'); 712 jQuery(target).siblings('a').addClass('toggle-hidden'); 713 714 const elements = jQuery(target).siblings('.attribute-value').find('a'); 715 716 717 elements.filter(function (index) { 718 const title = jQuery(this).attr('title').toLowerCase(); 719 return !title.includes(searchQuery) && !jQuery(this).hasClass('selected'); 720 }).parent().addClass('search-hidden'); 721}; 722 723function updateVariantMatrixField(data) { 724 var listingField = jQuery('.matrix-popup .ajax-field[data-field-products-set-clientside="1"]'); 725 if (listingField != null && listingField.length > 0) { 726 if (data != undefined && data != null && data.variantMatrix != undefined && data.variantMatrix != null 727 && data.variantMatrix.VariantChilds != undefined && data.variantMatrix.VariantChilds != null) { 728 var children = ""; 729 730 for (var i = 0; i < data.variantMatrix.VariantChilds.length; i++) { 731 children += data.variantMatrix.VariantChilds[i].ProduktLagerId + ","; 732 } 733 listingField.attr('data-Plids', children); 734 listingField.attr('data-variant-sorting', 'true'); 735 } 736 } 737}; 738 739function loadLightboxFields (renderEngine) { 740 if (jQuery('body.listtype-grid').length > 0) { 741 renderEngine.ListingTypeGrid = true; 742 } 743 744 var pageParam = renderEngine.getParameterByName('pageID'); 745 if (pageParam.length > 0) { 746 renderEngine.InitialPageNumber = parseInt(pageParam); 747 renderEngine.CurrentPageNumber = renderEngine.InitialPageNumber; 748 renderEngine.HighestPageNumberSeen = renderEngine.InitialPageNumber; 749 renderEngine.LowestPageNumberSeen = renderEngine.InitialPageNumber; 750 751 } 752 var articleIdentifier = jQuery("div#current-article-id"); 753 if (articleIdentifier.length > 0) { 754 renderEngine.currentArticleId = jQuery(articleIdentifier[0]).data("current-article"); 755 } 756 757 renderEngine.CheckStatistics = ( 758 window.D4AiActive != undefined && 759 window.D4AiActive && 760 window.D4AiRegisterStats != undefined && 761 window.D4AiRegisterStats); 762
763 var loadFirstParams = { 764 targetKey: "div.modal div .ajax-field.not-loaded", 765 filterTargetKey: "#AttributeListBox", 766 onlyUpdateProductList: false, 767 doNotRenderFilter: false, 768 useDummyData: false, 769 popupFilter: 0, 770 nextPageNumber: 0 771 }; 772 773 renderEngine.fieldsToLoad = []; 774 renderEngine.fieldsToLoad.push(loadFirstParams); 775 776 renderEngine.runUpdateFields(); 777}; 778function shouldDelayLoadingFilter(attributeFilterParent) { 779 if (attributeFilterParent == undefined || attributeFilterParent == null || attributeFilterParent.length <= 0 || attributeFilterParent[0].id !== "AttributeListBox") { 780 return false; 781 } 782 return jQuery("#filter-toggle").length > 0 && jQuery("#filter-toggle").data("expandlevel").length > 0 && !jQuery("#filter-content").is(":visible"); 783}; 784 785function storeFilterLoadCall (renderEngine, parent, manufacturerId) { 786 renderEngine.delayLoadFilterParent = parent; 787 renderEngine.delayLoadFilterManufacturerId = manufacturerId; 788 PubSub.subscribe("AjaxRenderingEngine.onFilterLoadRequested", function (message, data) { 789 if (renderEngine.delayLoadFilterLoaded) 790 return;//loaded already 791 792 loadAttributeFilterNotYetLoaded(renderEngine, renderEngine.delayLoadFilterParent, renderEngine.delayLoadFilterManufacturerId, false); 793 }); 794}; 795 796//todo: move to secondary file (getLibrary call - "filterutils") 797function loadAttributeFilterNotYetLoaded(renderEngine, attributeFilterParent, manufacturerid, allowDelay) { 798 if (allowDelay && shouldDelayLoadingFilter(attributeFilterParent)) { 799 // delay loading filter until the user clicks the show filter button 800 renderEngine.delayLoadFilterLoaded = false;//allow filter loading 801 storeFilterLoadCall(renderEngine, attributeFilterParent, manufacturerid); 802 return; 803 } 804 renderEngine.delayLoadFilterLoaded = true;//filter loading now requested, prevent additional calls 805 806 jQuery(attributeFilterParent).addClass("attribute-spinner"); 807 var queryFilterParam = renderEngine.getParameterByName("Filter"); 808 var queryMinParam = renderEngine.getParameterByName("Min"); 809 var queryMaxParam = renderEngine.getParameterByName("Max"); 810 var pageIndex = renderEngine.getParameterByName("pageID"); 811 var listingFields = jQuery(".ajax-field[data-field-is-productlist='1']"); 812 var cacheKey = ''; 813 if (renderEngine.urlParamsFilterIsValidFor === null || renderEngine.urlParamsFilterIsValidFor === queryFilterParam) { 814 renderEngine.urlParamsFilterIsValidFor = queryFilterParam; 815 if (listingFields.length > 0) { 816 cacheKey = jQuery(listingFields[0]).attr("data-cachekey"); 817 } 818 } 819 820 821 var fieldRequestFilter = { 822 NodeId: jQuery('#hidden-nodeid').text(), 823 Url: document.location.pathname + document.location.search, 824 Filter: queryFilterParam, 825 MinPrice: queryMinParam, 826 MaxPrice: queryMaxParam, 827 SearchString: renderEngine.getParameterByName("q"), 828 ClientId: '', 829 PageIndex: pageIndex, 830 FilterCacheKey: cacheKey, 831 ManufacturerId: manufacturerid 832 } 833 834 835 var notProcessedFields = attributeFilterParent.find(".not-processed"); 836 837 if (notProcessedFields.length > 0) { 838 var cachingparams = { 839 RequestFilter: fieldRequestFilter, 840 FieldId: jQuery(notProcessedFields[0]).data("fieldid") 841 }; 842 843 renderEngine.service.PostAction("CacheProductFilter", cachingparams).then(function (result) { 844 if (result.Success) 845 fieldRequestFilter.FilterCacheKey = result.CacheKey; 846 847 checkAttributeVisibility(renderEngine, attributeFilterParent, fieldRequestFilter); 848 }); 849 } else { 850 jQuery(attributeFilterParent).find('.is-processed .hidden.AttributeBox').removeClass('hidden'); 851 if (allowDelay) { 852 //no filters to show, only the menu, must show it immediately 853 attributeFilterParent.css("height", ""); 854 renderEngine.unhideProductMenu(); 855 } 856 jQuery(attributeFilterParent).removeClass("attribute-spinner"); 857 } 858 859}; 860 861function checkAttributeVisibility(renderEngine, attributeFilterParent, fieldRequestFilter) { 862 var attributesToProcess = attributeFilterParent.find(".not-processed"); 863 var itemsToProcess = attributesToProcess.length; 864 var itemsProcessed = 0; 865 var notProcessedAttributeFilters = attributeFilterParent.find(".not-processed"); 866 867 if (notProcessedAttributeFilters.length === 0) {
868 attributeFilterParent.find(".is-processed .hidden").removeClass("hidden"); 869 } 870 else { 871 var filterItems = []; 872 notProcessedAttributeFilters.each(function (index, item) { 873 const $item = jQuery(item); 874 var itemParam = { 875 AttributeId: $item.data("aid"), 876 NodeId: $item.data("nodeid"), 877 FieldId: $item.data("fieldid"), 878 Identifier: item.id 879 } 880 filterItems.push(itemParam); 881 }); 882 renderEngine.service.PostAction("CheckAttributeVisibility", { FilterItems: filterItems, RequestFilter: fieldRequestFilter, OnlyFirstItemWhenNotCached:true }).then(function (result) { 883 if (!!result && result.Success) { 884 for (var i = 0; i < result.Items.length; i++) { 885 var item = result.Items[i]; 886 const $itemDiv = jQuery('#' + item.Identifier); 887 $itemDiv.prevAll(".is-processed").find(".hidden.AttributeBox").removeClass("hidden"); 888 if (item.Visible) { 889 $itemDiv.replaceWith(item.RenderedData); 890 } 891 else { 892 $itemDiv.replaceWith(''); 893 } 894 895 var nextItem = $itemDiv.next(); 896 if (nextItem.length > 0 && !nextItem.hasClass("not-process")) { 897 nextItem.find("div.AttributeBox").removeClass("hidden"); 898 } 899 itemsProcessed++; 900 } 901 } 902 jQuery(attributeFilterParent).removeClass("attribute-spinner"); 903 904 if (itemsProcessed >= itemsToProcess) { //we're done, let's show the menu 905 attributeFilterParent.css("height", ""); 906 renderEngine.unhideProductMenu(); 907 } 908 909 if (!result.HasCachedResponse && itemsProcessed < itemsToProcess) 910 checkAttributeVisibilityRemainingitems(renderEngine, attributeFilterParent, fieldRequestFilter); 911 912 }); 913 914 } 915}; 916 917 918function checkAttributeVisibilityRemainingitems(renderEngine, attributeFilterParent, fieldRequestFilter) { 919 var attributesToProcess = attributeFilterParent.find(".not-processed"); 920 var itemsToProcess = attributesToProcess.length; 921 var itemsProcessed = 0; 922 var notProcessedAttributeFilters = attributeFilterParent.find(".not-processed"); 923 924 if (notProcessedAttributeFilters.length === 0) { 925 attributeFilterParent.find(".is-processed .hidden").removeClass("hidden"); 926 } 927 else { 928 notProcessedAttributeFilters.each(function (index, item) { 929 var filterItems = []; 930 const $item = jQuery(item); 931 var itemParam = { 932 AttributeId: $item.data("aid"), 933 NodeId: $item.data("nodeid"), 934 FieldId: $item.data("fieldid"), 935 Identifier: item.id 936 } 937 filterItems.push(itemParam); 938 939 renderEngine.service.PostAction("CheckAttributeVisibility", { FilterItems: filterItems, RequestFilter: fieldRequestFilter }).then(function (result) { 940 if (!!result && result.Success) { 941 for (var i = 0; i < result.Items.length; i++) { 942 var item = result.Items[i]; 943 const $itemDiv = jQuery('#' + item.Identifier); 944 $itemDiv.prevAll(".is-processed").find(".hidden.AttributeBox").removeClass("hidden"); 945 if (item.Visible) { 946 $itemDiv.replaceWith(item.RenderedData); 947 } 948 else { 949 $itemDiv.replaceWith(''); 950 } 951 952 var nextItem = $itemDiv.next(); 953 if (nextItem.length > 0 && !nextItem.hasClass("not-process")) { 954 nextItem.find("div.AttributeBox").removeClass("hidden"); 955 } 956 } 957 } 958 jQuery(attributeFilterParent).removeClass("attribute-spinner"); 959 960 itemsProcessed++; 961 962 if (itemsProcessed >= itemsToProcess) { //we're done, let's show the menu 963 attributeFilterParent.css("height", ""); 964 renderEngine.unhideProductMenu(); 965 } 966 }); 967 }); 968 } 969}; 970 971function updateFilterContentExtra(renderEngine, filterData) { 972 var secondaryFilterId = "secondary-filter-" + filterData.ClientId; 973 974 if (filterData != null && filterData.FilterResponse != null && filterData.FilterResponse.Success) { 975 if (filterData.FilterResponse.ClientId == "secondary-filter") { 976 //this must be added by us right before the field we're updating with the filter 977 jQuery("#" + secondaryFilterId).remove(); 978 979 } 980 var targetKey = filterData.FilterResponse.ClientId; 981 982 if (targetKey === null) 983 return; //nothing to do 984 985 if (targetKey.indexOf("#") < 0) { 986 targetKey = "#" + targetKey; 987 } 988 989 var targetDiv = jQuery(targetKey); 990 if (targetDiv !== undefined && targetDiv.length > 0) { 991 if (filterData.FilterResponse.Response.length > 0) { 992 //keep old height of filter if we had one already...
993 const $targetDiv = jQuery(targetDiv); 994 const oldHeight = $targetDiv.height(); 995 if ($targetDiv.children().length < 0) 996 oldHeight = 0; 997 else { 998 $targetDiv.css("height", oldHeight + "px"); 999 } 1000 $targetDiv.html(filterData.FilterResponse.Response); 1001 $targetDiv.attr("data-target-field-client-id", filterData.ClientId); 1002 loadAttributeFilterNotYetLoaded(renderEngine, targetDiv, filterData.ManufacturerId, true); 1003 1004 } else { 1005 const filterContainer = jQuery(".container-2016 has-filters"); 1006 if (filterContainer !== null && filterContainer !== undefined) { 1007 jQuery(filterContainer).addClass("no-filters"); 1008 jQuery(filterContainer).removeClass("has-filters"); 1009 renderEngine.unhideProductMenu(); 1010 } 1011 } 1012 if (!renderEngine.attributeFilterInitiated) { 1013 mcWeb.attributeFilte.init(filterData.ShowCompressedFilter); 1014 renderEngine.attributeFilterInitiated = true; 1015 } 1016 } 1017 else if (filterData.FilterResponse.ClientId == "secondary-filter") { 1018 targetDiv = jQuery("#" + filterData.ClientId).closest(".web-pub-field")[0]; 1019 jQuery(targetDiv).before("<div class=\'secondary-filter' id=\'" + secondaryFilterId + "'></div>"); 1020 jQuery("#" + secondaryFilterId).html(filterData.FilterResponse.Response); 1021 } 1022 } 1023};
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.