1/*! 2 * Copyright 2013 GoInstant Inc., a salesforce.com company 3 * See LICENSE.txt for details. 4 */ 5(function(root) { 6 /*global define,module */ 7 'use strict'; 8 var secureFilters = {}; 9 secureFilters.constructor = function secureFilters(){}; 10 11 /** 12 * @fileOverview 13 * Provides secure filtering functions to prevent a variety of injection and XSS 14 * (Cross-Site Scripting) attacks. 15 * 16 * These filters were designed to be used with EJS, but due to their 17 * simplicity, can easily be used in other contexts. 18 * 19 * See README.md for full documentation. 20 */ 21 22 var TO_CONFIGURE = ['html','js','jsAttr','uri','jsObj','css','style']; 23 24 /** 25 * Adds this module's filters to ejs. 26 * 27 * **USAGE**: 28 * 29 * ```js 30 * var secureFilters = require('secure-filters'); 31 * var ejs = secureFilters.configure(require('ejs')); 32 * ``` 33 * 34 * @param {Object} ejs the EJS package object 35 * @return {Object} the same EJS object 36 */ 37 secureFilters.configure = function(ejs) { 38 ejs.filters = ejs.filters || {}; 39 for (var i = 0; i < TO_CONFIGURE.length; i++) { 40 var filterName = TO_CONFIGURE[i]; 41 ejs.filters[filterName] = secureFilters[filterName]; 42 } 43 return ejs; 44 }; 45 46 var QUOT = /\x22/g; // " 47 var APOS = /\x27/g; // ' 48 var AST = /\*/g; 49 var TILDE = /~/g; 50 var BANG = /!/g; 51 var LPAREN = /\(/g; 52 var RPAREN = /\)/g; 53 var CDATA_CLOSE = /\]\](?:>|\\x3E|\\u003E)/gi; 54 55// Matches alphanum plus ",._-" & unicode. 56// ESAPI doesn't consider "-" safe, but we do. It's both URI and HTML safe. 57 var JS_NOT_WHITELISTED = /[^,\-\.0-9A-Z_a-z]/g; 58 59// add on '":\[]{}', which are necessary JSON metacharacters 60 var JSON_NOT_WHITELISTED = /[^\x22,\-\.0-9:A-Z\[\x5C\]_a-z{}]/g; 61 62// Control characters that get converted to spaces. 63 var HTML_CONTROL = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g; 64 65// Matches alphanum plus allowable whitespace, ",._-", and unicode. 66// NO-BREAK SPACE U+00A0 is fine since it's "whitespace". 67 var HTML_NOT_WHITELISTED = /[^\t\n\v\f\r ,\.0-9A-Z_a-z\-\u00A0-\uFFFF]/g; 68 69// Matches alphanum and UTF-16 surrogate pairs (i.e. U+10000 and higher). The 70// rest of Unicode is deliberately absent in order to prevent charset encoding 71// issues. 72 var CSS_NOT_WHITELISTED = /[^a-zA-Z0-9\uD800-\uDFFF]/g; 73 74 /** 75 * Encodes values for safe embedding in HTML tags and attributes. 76 * 77 * See html(value) in README.md for full documentation. 78 * 79 * @name html 80 * @param {any} val will be converted to a String prior to encoding 81 * @return {string} the encoded string 82 */ 83 secureFilters.html = function(val) { 84 var str = String(val); 85 str = str.replace(HTML_CONTROL, ' '); 86 return str.replace(HTML_NOT_WHITELISTED, function(match) { 87 var code = match.charCodeAt(0); 88 switch(code) { 89 // folks expect these "nice" entities: 90 case 0x22: 91 return '"'; 92 case 0x26: 93 return '&'; 94 case 0x3C: 95 return '<'; 96 case 0x3E: 97 return '>'; 98 99 default: 100 // optimize for size: 101 if (code < 100) { 102 var dec = code.toString(10); 103 return '&#'+dec+';'; 104 } else { 105 // XXX: this doesn't produce strictly valid entities for code-points 106 // requiring a UTF-16 surrogate pair. However, browsers are generally 107 // tolerant of this. Surrogate pairs are currently in the whitelist 108 // defined via HTML_NOT_WHITELISTED. 109 var hex = code.toString(16).toUpperCase(); 110 return '&#x'+hex+';'; 111 } 112 } 113 }); 114 }; 115 116 /** 117 * Backslash-encoding for a single character in JavaScript contexts. 118 * @param {string} charStr single-character string. 119 * @return {string} backslash escaped character. 120 * @private 121 */ 122 function jsSlashEncoder(charStr) { 123 var code = charStr.charCodeAt(0); 124 var hex = code.toString(16).toUpperCase(); 125 if (code < 0x80) { // ASCII 126 if (hex.length === 1) { 127 return '\\x0'+hex; 128 } else { 129 return '\\x'+hex; 130 } 131 } else { // Unicode 132 switch(hex.length) { 133 case 2: 134 return '\\u00'+hex; 135 case 3: 136 return '\\u0'+hex; 137 case 4: 138 return '\\u'+hex; 139 default: 140 // charCodeAt() JS shouldn't return code > 0xFFFF, and only four hex 141 // digits can be encoded via `\u`-encoding, so return REPLACEMENT 142 // CHARACTER U+FFFD. 143 return '\\uFFFD'; 144 } 145 } 146 147 } 148 149 /** 150 * Encodes values for safe embedding in JavaScript string contexts. 151 * 152 * See js(value) in README.md for full documentation. 153 * 154 * @name js 155 * @param {any} val will be converted to a String prior to encoding 156 * @return {string} the encoded string 157 */ 158 secureFilters.js = function(val) { 159 var str = String(val);
160 return str.replace(JS_NOT_WHITELISTED, jsSlashEncoder); 161 }; 162 163 164 /** 165 * Encodes values embedded in HTML scripting attributes. 166 * 167 * See jsAttr(value) in README.md for full documentation. 168 * 169 * @name jsAttr 170 * @param {any} val will be converted to a String prior to encoding 171 * @return {string} the encoded string 172 */ 173 secureFilters.jsAttr = function(val) { 174 return secureFilters.html(secureFilters.js(val)); 175 }; 176 177 /** 178 * Percent-encodes unsafe characters in URIs. 179 * 180 * See uri(value) in README.md for full documentation. 181 * 182 * @name uri 183 * @param {any} val will be converted to a String prior to encoding 184 * @return {string} the percent-encoded string 185 */ 186 secureFilters.uri = function(val) { 187 // encodeURIComponent() is well-standardized across browsers and it handles 188 // UTF-8 natively. It will not encode "~!*()'", so need to replace those here. 189 // encodeURIComponent also won't encode ".-_", but those are known-safe. 190 // 191 // IE does not always encode '"' to '%27': 192 // http://blog.imperva.com/2012/01/ie-bug-exposes-its-users-to-xss-attacks-.html 193 var encode = encodeURIComponent(String(val)); 194 return encode 195 .replace(BANG, '%21') 196 .replace(QUOT, '%27') 197 .replace(APOS, '%27') 198 .replace(LPAREN, '%28') 199 .replace(RPAREN, '%29') 200 .replace(AST, '%2A') 201 .replace(TILDE, '%7E'); 202 }; 203 204 /** 205 * Encodes an object as JSON, but with unsafe characters in string literals 206 * backslash-escaped. 207 * 208 * See jsObj(value) in README.md for full documentation. 209 * 210 * @name jsObj 211 * @param {any} val 212 * @return {string} the JSON- and backslash-encoded string 213 */ 214 secureFilters.jsObj = function(val) { 215 return JSON.stringify(val) 216 .replace(JSON_NOT_WHITELISTED, jsSlashEncoder) 217 // prevent breaking out of CDATA context. Escaping < below is sufficient 218 // to prevent opening a CDATA context. 219 .replace(CDATA_CLOSE, '\\x5D\\x5D\\x3E'); 220 }; 221 222 /** 223 * Encodes values for safe embedding in CSS context. 224 * 225 * See css(value) in README.md for full documentation. 226 * 227 * @name css 228 * @param {any} val 229 * @return {string} the backslash-encoded string 230 */ 231 secureFilters.css = function(val) { 232 var str = String(val); 233 return str.replace(CSS_NOT_WHITELISTED, function(match) { 234 var code = match.charCodeAt(0); 235 if (code === 0) { 236 return '\\fffd '; // REPLACEMENT CHARACTER U+FFFD 237 } else { 238 var hex = code.toString(16).toLowerCase(); 239 return '\\'+hex+' '; 240 } 241 }); 242 }; 243 244 /** 245 * Encodes values for safe embedding in HTML style attribute context. 246 * 247 * See style(value) in README.md for full documentation. 248 * 249 * @name style 250 * @param {any} val 251 * @return {string} the entity- and backslash-encoded string 252 */ 253 secureFilters.style = function(val) { 254 return secureFilters.html(secureFilters.css(val)); 255 }; 256 257 258// AMD / RequireJS 259 if (typeof define !== 'undefined' && define.amd) { 260 define([], function () { 261 return secureFilters; 262 }); 263 } 264// CommonJS / Node.js 265 else if (typeof module !== 'undefined' && module.exports) { 266 module.exports = secureFilters; 267 } 268// included directly via <script> tag 269 else { 270 root.secureFilters = secureFilters; 271 } 272 273}(this));; 274 275iportalFn.search = iportalFn.search || {}; 276angular.module('elasticSearchPages.es', []); 277$.extend(iportalFn.search, { 278 'init': (function () { 279 function init(dataName) { 280 var searchPagesModule = angular.module('elasticSearchPages.es').config(iportalFn.defaultNgConfig); 281 var loadType = { 282 "NORMAL" : 0, 283 "FILTER" : 1, 284 "PAGE_CHANGE": 2, 285 "NONE" : 3 286 }; 287 var arrType = { 288 "PREVIOUS": 0, 289 "NEXT" : 1 290 }; 291 var searchType = { 292 "IPORTAL": 0, 293 "PIA" : 1 294 } 295 296 // Remove top search box, as the search pages have their own search box 297 $('#rs-d-logobar #px_logo').removeClass('small-8 medium-8 large-9').addClass('small-12'); 298 $('#rs-d-logobar #desktop_searchbox').remove(); 299 $('#mobile_searchbox').remove(); 300 301 // Angular controller
302 searchPagesModule.controller('SearchController', ['$scope', '$http', '$location', '$sce', '$filter', function ($scope, $http, $location, $sce, $filter) { 303 var config = {}; 304 305 // Get search term from query paramter 'q' 306 function queryStringParam(paramName) { 307 var queryString = window.location.search.substring(1); 308 var vars = queryString.split('&'); 309 for (var i = 0; i < vars.length; i++) { 310 var pair = vars[i].split('='); 311 if (pair[0] == paramName) { 312 var comp = pair[1].split("+").join(" "); 313 return decodeURIComponent(comp); 314 } 315 } 316 return ""; 317 } 318 319 // Initialize controller 320 function initController() { 321 $scope.loaded = false; 322 323 if (!$scope.initialized) { 324 config = iportalData[dataName].params['config']; 325 326 $scope.facet = { 327 defaultSegment : iportalData[dataName].params['facetsegment'], 328 zonesTotalResults : 0, 329 segmentsTotalResults: 0, 330 selectedZones : {}, 331 otherSegments : [] 332 }; 333 $scope.facet.selectedZones = (iportalData[dataName].params['facetzone'] == "none") ? {} : iportalData[dataName].params['facetzone']; 334 335 $scope.totalResults = 0; 336 $scope.totalPages = 0; 337 $scope.currentpage = 1; 338 $scope.resultsFailed = false; 339 $scope.requiredfields = ''; 340 $scope.suggestion = ''; 341 $scope.failedQuery = ''; 342 $scope.query = (queryStringParam('q') != "") ? queryStringParam('q') : queryStringParam('qmob'); 343 344 $scope.results = []; 345 $scope.suggestedResults = []; 346 $scope.pages = []; 347 348 if ($scope.query) { 349 $scope.loadPage(1, loadType.NORMAL); 350 } else { 351 $scope.loaded = true; 352 } 353 354 $scope.initialized = true; 355 } 356 357 $scope.pageLoadType = loadType; 358 $scope.arrowType = arrType; 359 } 360 361 function resetFacetAndRequiredData() { 362 $scope.facet.zonesTotalResults = {}; 363 for (segment in $scope.facet.segmentsTotalResults) { 364 $scope.facet.segmentsTotalResults[segment] = 0; 365 } 366 $scope.facet.otherSegments = []; 367 $scope.requiredfields = ''; 368 } 369 370 function processResults(data, pageLoadType, srchType) { 371 $scope.results = 0; 372 $scope.suggestedResults = {}; 373 374 if (typeof data.RES !== "undefined") { 375 $scope.results = data.RES.R; 376 $scope.suggestedResults = data.RES.K; 377 } 378 $scope.suggestion = (typeof data.SPELLING == "undefined") ? "" : data.SPELLING.SUGGESTION; 379 380 if (pageLoadType != loadType.PAGE_CHANGE) { 381 $scope.totalPages = calculateTotalNumberOfPages(data, pageLoadType, srchType); 382 } 383 generatePages(); 384 385 $scope.loaded = true; 386 } 387 388 function calculateTotalNumberOfPages(data, pageLoadType, srchType) { 389 $scope.totalResults = 0; 390 391 if (srchType == searchType.IPORTAL) { 392 if (typeof data.DYN == "undefined") { 393 return 0; 394 } 395 396 if (typeof data.DYN.facetzone !== "undefined" && pageLoadType == loadType.NORMAL) { 397 $scope.facet.zonesTotalResults = data.DYN.facetzone; 398 } 399 400 for (var index in $scope.facet.zonesTotalResults) { 401 if ($scope.facet.selectedZones["none"]) { 402 $scope.totalResults += parseInt($scope.facet.zonesTotalResults[index], 10); 403 } 404 else if ($scope.facet.selectedZones[index]) { 405 $scope.totalResults += parseInt($scope.facet.zonesTotalResults[index], 10); 406 } 407 } 408 } else if (srchType == searchType.PIA && data.RES !== 'undefined') { 409 var parsed = parseInt(data.RES.M, 10); 410 $scope.totalResults = (isNaN(parsed)) ? 0 : parsed; 411 } 412 413 return Math.floor(($scope.totalResults + config.itemsPerPage - 1) / config.itemsPerPage); 414 } 415 416 function generatePages() { 417 $scope.pages = []; 418 419 if ($scope.totalPages > 0) { 420 var lastDisplayedPage = $scope.currentpage + 3; 421 var firstDisplayedPage = $scope.currentpage - 4; 422 423 if (lastDisplayedPage > $scope.totalPages) { 424 lastDisplayedPage = (lastDisplayedPage < 1) ? 1 : $scope.totalPages; 425 } 426 if (firstDisplayedPage > $scope.totalPages) { 427 firstDisplayedPage = $scope.totalPages; 428 } 429 if (firstDisplayedPage < 1) { 430 firstDisplayedPage = 1; 431 } 432 433 if ($scope.currentpage > $scope.totalPages) { 434 $scope.currentpage = $scope.totalPages; 435 } 436 if ($scope.currentpage == $scope.totalPages) { 437 $scope.lastPage = true; 438 } 439 for (i = firstDisplayedPage; i <= lastDisplayedPage; i++) { 440 var page = {}; 441 page.i = i; 442 page.a = (i == $scope.currentpage); 443 $scope.pages[$scope.pages.length] = page; 444 } 445 } 446 } 447 448 function processError() { 449 $scope.totalResults = 0; 450 $scope.failedQuery = $scope.query; 451 $scope.resultsFailed = true; 452 $scope.loaded = true; 453 } 454 455 function processZoneFilters(data) { 456 if (typeof data.DYN !== "undefined") { 457 angular.forEach(data.DYN.facetzone, function (value, key) { 458 if (!$scope.facet.selectedZones[key]) { 459 $scope.facet.selectedZones[key] = false;
460 } 461 }); 462 } 463 } 464 465 function processSegmentsAlsoOn(data) { 466 if (typeof data.DYN == "undefined") { 467 angular.forEach(config.visibleSegments, function (value, key) { 468 $scope.facet.segmentsTotalResults[key] = 0; 469 }); 470 } else if (typeof data.DYN.facetsegment !== "undefined") { 471 angular.forEach(config.visibleSegments, function (value, key) { 472 if (!data.DYN.facetsegment[key]) { 473 $scope.facet.segmentsTotalResults[key] = 0; 474 } 475 $scope.facet.segmentsTotalResults = data.DYN.facetsegment; 476 }); 477 } 478 } 479 480 function calculateBaseUrl(inmeta) { 481 var url = config.searchUrl; 482 483 url += ($scope.query.length > 0) ? '?q=' + encodeURIComponent($("<div>").text($scope.query).html()) : '?q=*'; 484 url += inmeta + '&client=' + config.client + '&proxystylesheet=' + config.proxystylesheet; 485 url += '&output=' + config.output + '&site=' + config.collection + '&lr=' + config.lr; 486 url += '&oe=' + config.oe + '&ie=' + config.ie + '&rc=' + config.rc + '&filter=' + config.filter; 487 488 return url; 489 }; 490 491 function zoneFiltersUrl() { 492 var url = calculateBaseUrl(''); 493 494 $scope.requiredfields = ''; 495 496 if ($scope.facet.defaultSegment.length > 0) { 497 $scope.requiredfields += 'facetsegment:' + $scope.facet.defaultSegment; 498 } 499 if (config.visibleZones.length != 0) { 500 var zonesQS = ($scope.requiredfields.length > 0) ? '.(' : '('; 501 var anyActiveZones = false; 502 503 angular.forEach(config.visibleZones, function (value, key) { 504 zonesQS += (anyActiveZones) ? '|facetzone:' + value.name : 'facetzone:' + value.name; 505 anyActiveZones = true; 506 }); 507 zonesQS += ')'; 508 509 $scope.requiredfields += zonesQS; 510 } 511 512 if ($scope.requiredfields.length > 0) { 513 url += '&requiredfields=' + $scope.requiredfields; 514 } 515 516 return url; 517 }; 518 519 function segmentsAlsoOnUrl() { 520 var url = calculateBaseUrl(''); 521 522 $scope.requiredfields = ''; 523 524 if (config.visibleSegments.length != 0) { 525 var segmentsQS = '('; 526 var anyActiveSegments = false; 527 528 angular.forEach(config.visibleSegments, function (value, key) { 529 segmentsQS += (anyActiveSegments) ? '|facetsegment:' + key : 'facetsegment:' + key; 530 anyActiveSegments = true; 531 }); 532 segmentsQS += ')'; 533 534 $scope.requiredfields += segmentsQS; 535 } 536 if (config.visibleZones.length != 0) { 537 var zonesQS = ($scope.requiredfields.length > 0) ? '.(' : '('; 538 var anyActiveZones = false; 539 540 angular.forEach(config.visibleZones, function (value, key) { 541 zonesQS += (anyActiveZones) ? '|facetzone:' + value.name : 'facetzone:' + value.name; 542 anyActiveZones = true; 543 }); 544 zonesQS += ')'; 545 546 $scope.requiredfields += zonesQS; 547 } 548 549 if ($scope.requiredfields.length > 0) { 550 url += '&requiredfields=' + $scope.requiredfields; 551 } 552 553 return url; 554 }; 555 556 function searchQueryUrlIportal() { 557 var url = calculateBaseUrl(''); 558 559 $scope.requiredfields = ''; 560 if ($scope.facet.defaultSegment.length > 0) { 561 $scope.requiredfields += 'facetsegment:' + $scope.facet.defaultSegment; 562 } 563 564 var anyActiveZones = false; 565 566 var zonesQS = '.('; 567 if (!jQuery.isEmptyObject($scope.facet.selectedZones)) { 568 angular.forEach($scope.facet.selectedZones, function (value, key) { 569 if (value && key !== 'none') { 570 zonesQS += (anyActiveZones) ? '|facetzone:' + key : 'facetzone:' + key; 571 anyActiveZones = true; 572 } 573 }); 574 } 575 576 if (!anyActiveZones) { 577 angular.forEach(config.visibleZones, function (value, key) { 578 if (value) { 579 zonesQS += (anyActiveZones) ? '|facetzone:' + value.name : 'facetzone:' + value.name; 580 anyActiveZones = true; 581 } 582 }); 583 } 584 zonesQS += ')'; 585 586 if (anyActiveZones) { 587 $scope.requiredfields += zonesQS; 588 } 589 if ($scope.requiredfields.length > 0) { 590 url += '&requiredfields=' + $scope.requiredfields; 591 } 592 593 url += '&num=' + config.itemsPerPage; 594 url += '&start=' + config.itemsPerPage * ($scope.currentpage - 1); 595 return url; 596 }; 597 598 function searchQueryUrlPia() { 599 var inmeta = ''; 600 var startDate = $filter('dateFormat')(document.getElementById('startDate').value); 601 var endDate = $filter('dateFormat')(document.getElementById('endDate').value); 602 603 if (startDate !== "" && endDate !== "") { 604 inmeta += '+inmeta:startDate:' + startDate + '..' + endDate; 605 inmeta += '+AND+inmeta:endDate:' + startDate + '..' + endDate 606 } else if (startDate !== "") { 607 inmeta += '+inmeta:startDate:' + startDate + '..'; 608 } else if (endDate !== "") { 609 inmeta += '+inmeta:endDate:..' + endDate; 610 } 611 612 var piaBaseUrl = calculateBaseUrl(inmeta); 613 piaBaseUrl += '&num=' + config.itemsPerPage; 614 piaBaseUrl += '&start=' + config.itemsPerPage * ($scope.currentpage - 1); 615 return piaBaseUrl; 616 } 617 618 function setupOtherSegments() { 619 var newOtherSegments = []; 620 621 angular.forEach(config.visibleSegments, function (value, key) { 622 if (key != $scope.facet.defaultSegment) { 623 newOtherSegments.push(key); 624 } 625 }); 626 627 $scope.facet.otherSegments = newOtherSegments; 628 } 629 630 $scope.changeSegment = function (segment) { 631 $scope.facet.defaultSegment = segment; 632 $scope.loadPage(1, loadType.NORMAL); 633 } 634 635 $scope.loadPage = function (page, pageLoadType) { 636 var srchType = config.searchType; 637 $scope.loaded = false;
638 $scope.currentpage = page; 639 $scope.suggestion = ''; 640 641 if (srchType == searchType.IPORTAL && pageLoadType == loadType.FILTER) { 642 $scope.removeFilter("none", pageLoadType); 643 } 644 645 var url = ''; 646 if (srchType == searchType.IPORTAL) { 647 url = searchQueryUrlIportal(); 648 } else if (srchType == searchType.PIA) { 649 url = searchQueryUrlPia(); 650 } 651 652 $http.get(url) 653 .then(function (response) { 654 processResults(response.data, pageLoadType, srchType); 655 }, function (data) { 656 processError(); 657 }); 658 659 if (srchType == searchType.IPORTAL && pageLoadType == loadType.NORMAL) { 660 resetFacetAndRequiredData(); 661 662 $http.get(zoneFiltersUrl()) 663 .then(function (response) { 664 processZoneFilters(response.data); 665 }, 666 function (response) { 667 processError(); 668 }); 669 670 if (!jQuery.isEmptyObject(config.visibleSegments)) { 671 $http.get(segmentsAlsoOnUrl()) 672 .then(function (response) { 673 processSegmentsAlsoOn(response.data); 674 } 675 , function (response) { 676 processError(); 677 }); 678 } 679 setupOtherSegments(); 680 } 681 } 682 683 $scope.removeFilter = function (zone, pageLoadType) { 684 $scope.facet.selectedZones[zone] = false; 685 686 var filterSelected = false; 687 angular.forEach($scope.facet.selectedZones, function (value, key) { 688 if (key !== 'none') { 689 filterSelected = filterSelected || value; 690 } 691 }); 692 693 $scope.facet.selectedZones['none'] = !filterSelected; 694 695 if (pageLoadType != loadType.FILTER) { 696 $scope.loadPage(1, loadType.FILTER); 697 } 698 } 699 700 $scope.reinitializeFilters = function () { 701 angular.forEach($scope.facet.selectedZones, function (value, key) { 702 newVal = (key == 'none') ? true : false; 703 $scope.facet.selectedZones[key] = newVal; 704 }); 705 706 $scope.loadPage(1, loadType.FILTER); 707 } 708 709 $scope.getZoneName = function (zone) { 710 for (index in config.visibleZones) { 711 if (config.visibleZones[index].name == zone) { 712 return config.visibleZones[index].label; 713 } 714 } 715 } 716 717 $scope.getSegmentName = function (segment) { 718 return config.visibleSegments[segment]; 719 } 720 721 $scope.getSelectedZones = function () { 722 return $filter('selected')($scope.facet.selectedZones, config.visibleZones); 723 } 724 725 $scope.generateId = function (index) { 726 return 'f1checkbox{' + (index + 1) + '}'; 727 } 728 729 $scope.getVisibleZones = function () { 730 return config.visibleZones; 731 } 732 733 $scope.displayTotalResults = function () { 734 return ($scope.totalResults == -1) ? '' : '(' + $scope.totalResults + ')'; 735 } 736 737 $scope.numOfResultsInZone = function (zone) { 738 return (!!$scope.facet.zonesTotalResults[zone]) ? '(' + $scope.facet.zonesTotalResults[zone] + ')' : '(0)'; 739 } 740 741 $scope.numOfResultsInSegment = function (segment) { 742 return (!!$scope.facet.segmentsTotalResults) ? '(' + $scope.facet.segmentsTotalResults[segment] + ')' : '(0)'; 743 } 744 745 $scope.displayNoResults = function () { 746 return $scope.totalResults == 0 && !$scope.resultsFailed; 747 } 748 749 $scope.displayFailures = function () { 750 return $scope.resultsFailed; 751 } 752 753 $scope.displayErrorBox = function () { 754 return ($scope.totalResults == 0 || $scope.resultsFailed) && $scope.loaded; 755 } 756 757 $scope.displayKeyMatchesBox = function () { 758 return !($scope.totalResults == 0 || $scope.resultsFailed) && $scope.suggestedResults.length != 0; 759 } 760 761 $scope.displayAlsoOn = function () { 762 return !jQuery.isEmptyObject($scope.facet.otherSegments); 763 } 764 765 $scope.suggestionAvailable = function () { 766 return $scope.suggestion.length > 0; 767 } 768 769 $scope.changeQuery = function (suggestion) { 770 suggestion = suggestion.replace(/(<([^>]+)>)/ig, ""); 771 $scope.query = suggestion; 772 $scope.loadPage(1, loadType.NORMAL); 773 } 774 775 $scope.getArrowClass = function (type) { 776 css_class = "arrow"; 777 778 if (($scope.currentpage < 2 && type == arrType.PREVIOUS) || ($scope.currentpage == $scope.totalPages && type == arrType.NEXT)) { 779 css_class = css_class + " unavailable"; 780 } 781 782 return css_class; 783 } 784 785 initController(); 786 }]); 787
788 searchPagesModule.filter('trust', 789 function ($sce) { 790 return function (val) { 791 return $sce.trustAsHtml(val); 792 }; 793 } 794 ); 795 796 searchPagesModule.filter('selected', 797 function () { 798 return function (input, visibleZones) { 799 var results = []; 800 801 angular.forEach(input, function (value, key) { 802 if (value && key !== 'none') { 803 results.push(key); 804 } 805 }); 806 807 return results; 808 }; 809 } 810 ); 811 812 searchPagesModule.filter('dateFormat', 813 function ($filter) { 814 return function (input) { 815 if (input == null || !input) { 816 return ""; 817 } 818 819 var _date = $filter('date')(new Date(input), 'yyyy-MM-dd'); 820 821 return _date.toUpperCase(); 822 }; 823 } 824 ); 825 826 searchPagesModule.directive('pxDatePicker', function () { 827 return { 828 restrict: 'A', 829 link : function (scope, element, attrs, ngModelCtrl) { 830 $(element).datepick({dateFormat: 'mm/dd/yyyy'}); 831 element.on('load', function () { 832 //disable default behaviour 833 inception.accordion.deactivate('.accordion'); 834 835 // init new behaviour 836 // activate: function (selector, closeOthers, toggle, linkSelector, divSelector, hiddenClassSelector, shownClassSelector) 837 inception.accordion.activate('.accordion', false, true); 838 839 $("#jsrs-filterClose").click(function () { 840 $(".jsrs-visibilityToggler").trigger('click'); 841 }); 842 }); 843 } 844 }; 845 }); 846 } 847 848 return init; 849 }()) 850});; 851 852(function() { 853 "use strict"; 854 angular 855 .module("beProximus.es", ["elasticSearchPages.es","beProximus.cpv"]); 856})(); 857; 858 859(function () { 860 'use strict'; 861 angular.module("elasticSearchPages.es").factory('elasticDeviceService', ["$sce", 862 function ($sce) { 863 var devicesService = {}; 864 devicesService.isDevice = isDevice; 865 devicesService.transformToDevice = transformToDevice; 866 devicesService.transformToNonDevice = transformToNonDevice; 867 devicesService.devices = 0; 868 869 function isDevice(element) { 870 return element._source && element._source.device_model && element._source.device_brand && 871 element._source.device_imgurl && element._source.device_price; 872 } 873 874 /*function isSamePrize(element) { 875 var prize1 = parseInt(element._source.device_ref_price); 876 var prize2 = parseInt(element._source.device_price); 877 878 return prize1 === prize2; 879 }*/ 880 881 function isSamePrize(element) { // if same prize we must not display the prize like a promotion 882 883 var prize1 = element._source.device_ref_price.replace('.', ''); //prize can contain . or , that's why we extract them from the prize 884 prize1 = prize1.replace(',', ''); 885 var prize2 = element._source.device_price.replace('.', ''); 886 prize2 = prize2.replace(',', ''); 887 888 return prize1 === prize2; 889 } 890 891 function transformToDevice(element, language) { 892 var result = {}; 893 894 var normalPriceVar = false; 895 var jointOfferPriceVar = false; 896 var refPriceVar = false; 897 var displayPriceUnitVar = 0; 898 var displayPriceDecimalVar = 0; 899 900 if (element._source.device_joint_offer_price) { 901 jointOfferPriceVar = true; 902 displayPriceUnitVar = getPriceUnit(element._source.device_joint_offer_price); 903 displayPriceDecimalVar = getPriceDecimal(element._source.device_joint_offer_price, language); 904 } else if ((element._source.device_ref_price) && (!isSamePrize(element))) { 905 refPriceVar = true; 906 displayPriceUnitVar = getPriceUnit(element._source.device_price); 907 displayPriceDecimalVar = getPriceDecimal(element._source.device_price, language); 908 } else { 909 normalPriceVar = true; 910 displayPriceUnitVar = getPriceUnit(element._source.device_price); 911 displayPriceDecimalVar = getPriceDecimal(element._source.device_price, language) 912 } 913 914 result = { 915 isDevice: true, 916 isNormalPrice: normalPriceVar, 917 isJointOfferPrice: jointOfferPriceVar, 918 isRefPrice: refPriceVar, 919 label: $sce.trustAsHtml(removeProximusString(element.T)), 920 linkHref: element._id, 921 mpcuuid: element._source.device_mpcuuid, 922 deviceImg: element._source.device_imgurl, 923 deviceModel: element._source.device_model, 924 deviceBrand: element._source.device_brand, 925 deviceRefPrice: element._source.device_ref_price, 926 originalPriceUnit: getPriceUnit(element._source.device_price), 927 originalPriceDecimal: getPriceDecimal(element._source.device_price, language), 928 displayPriceUnit: displayPriceUnitVar, 929 displayPriceDecimal: displayPriceDecimalVar, 930 description: element._source.description, 931 productId: element._source.device_mpcuuid, 932 colours: transformColours(element._source.colours), 933 inventoryNumber: element._source.inventory_number, 934 stockCheck: element._source.stockcheck == "true", 935 bvEnabled: element._source.bv_enabled == "true", 936 promoPatch: element._source.promo_patch, 937 promoText: element._source.promo_text, 938 promoCondition: element._source.promo_condition, 939 productPatch: element._source.product_patch, 940 stockStatus: element._source.stock_status, 941 orangeStockLimit: element._source.orange_stock_limit 942 }; 943 944 return result; 945 } 946 947 function transformToNonDevice(element) { 948 return { 949 isDevice: false, 950 label: $sce.trustAsHtml(removeProximusString(element._source.title)), 951 linkHref: element._id 952 }; 953 } 954 955 function transformColours(coloursMetadata) { 956 try { 957 return JSON.parse(coloursMetadata); 958 } catch (err) { 959 return []; 960 } 961 } 962 963 function getPriceUnit(price) { 964 if (!price) return ""; 965 if (price.toString().indexOf(".") > -1) 966 return price.toString().split(".")[0]; 967 return price.toString().split(",")[0]; 968 } 969 970 function getPriceDecimal(price, language) { 971 if (!price) return ""; 972 if (price.toString().indexOf(".") > -1 && price.toString().split(".")[1]) 973 return ((language == "fr" || language == "nl") ? "," : ".") + price.toString().split(".")[1]; 974 if (price.toString().indexOf(",") > -1 && price.toString().split(",")[1]) 975 return "," + price.toString().split(",")[1]; 976 return ""; 977 } 978 979 function removeProximusString(label) { 980 if (!label) return ""; 981 return label.replace(" | Proximus", ""); 982 } 983 984 return devicesService; 985 986 }]) 987 })();; 988 989function SearchHistory(segment, language) { 990 this.storageKey = segment; 991 this.language = language; 992 this.capacity = suggestionProperties.searchHistoryCapacity; 993 this.separator = ","; 994 this.localStorageSegment = getLocalStorage(); 995 this.localStorageLanguage = this.localStorageSegment ? this.localStorageSegment[language] : ""; 996 this.localHistory = this.localStorageLanguage ? this.localStorageLanguage.split(this.separator) : []; 997 function getLocalStorage(){ 998 try { 999 return JSON.parse(localStorage.getItem(segment)); 1000 } catch (err) { 1001 //Suppress Error: Local storage does not work on certain browsers in private mode 1002 return ""; 1003 } 1004 } 1005} 1006SearchHistory.prototype.addItem = function (item) { 1007 1008 if (this.localHistory.indexOf(item) != -1) { 1009 // remove existing item so it will not appear twice on the list, adding it again will move it to the top 1010 removeItemFromArray(item, this.localHistory); 1011 } 1012 while (this.localHistory.length >= this.capacity && this.capacity != 0) { 1013 //remove items from the end over the capacity 1014 this.localHistory.pop(); 1015 } 1016 1017 //add item to the top 1018 this.localHistory.unshift(item); 1019 if (this.localStorageSegment == null) { 1020 //Create object if nothing in cache 1021 this.localStorageSegment = {}; 1022 } 1023 this.localStorageSegment[this.language] = this.localHistory.join(this.separator); 1024 1025 try { 1026 //save in storage 1027 localStorage.setItem(this.storageKey, JSON.stringify(this.localStorageSegment)); 1028 } catch (err) { 1029 //Suppress Error: Local storage does not work on certain browsers in private mode 1030 } 1031 1032 function removeItemFromArray(item, array) { 1033 for (var i = array.length - 1; i >= 0; i--) { 1034 if (array[i] === item) { 1035 array.splice(i, 1); 1036 } 1037 } 1038 } 1039} 1040 1041SearchHistory.prototype.getHistory = function () { 1042 //if history capacity changed in meantime - return only new number of items 1043 return this.localHistory.slice(0,this.capacity); 1044} 1045; 1046 1047iportalFn.suggestions = iportalFn.suggestions || {}; 1048$.extend(iportalFn.suggestions, { 1049 'init': (function() { 1050 1051 function getExistingOrCreateModule(name) { 1052 try { 1053 return angular.module(name); 1054 } catch (err) { 1055 return angular.module(name, []); 1056 } 1057 } 1058 1059 getExistingOrCreateModule('elasticSearchPages.es').controller('ElasticSuggestionsController', ['$scope', function($scope) {}]) 1060 .directive('elasticSuggestions', ['$http', '$rootScope', 'AnalyticsService', 'searchHistoryService', function($http, $rootScope, AnalyticsService, searchHistoryService) { 1061 $rootScope.throttleTimeMilliSeconds = suggestionProperties.throttleTimeMilliSeconds; 1062 return { 1063 scope: false, 1064 restrict: 'A', 1065 link: function($scope, element, attrs) { 1066 if (inception && inception.searchSlideOut && inception.searchSlideOut.bindEvents) { 1067 inception.searchSlideOut.bindEvents() 1068 } 1069 var selectedIndex; 1070 $scope.fetchZonesDatas = []; 1071 1072 $scope.fetchZonesData = function() { 1073 var i = 0, 1074 len = $scope.fetchZonesDatas.length; 1075 1076 if ($scope.query.length >= 3) { 1077 for (; i < len; i += 1) { 1078 $scope.fetchZonesDatas[i](); 1079 } 1080 } else 1081 $scope.clearZonesData(); 1082 }; 1083 1084 $scope.showHistorySuggestions = function() { 1085 if (!$scope.query) { 1086 $scope.suggestionList = searchHistoryService.getHistory($scope.query); 1087 $scope.searchHistoryTextShown = $scope.suggestionList.length !== 0; 1088 } else 1089 $scope.searchHistoryTextShown = false;
1090 }; 1091 1092 $scope.hideHistorySuggestions = function() { 1093 $scope.searchHistoryTextShown = false; 1094 }; 1095 1096 $scope.getSuggestions = function() { 1097 if (typeof $scope.query !== "undefined" && $scope.query.length >= suggestionProperties.minChars) { 1098 callElasticForSuggestions($scope.query); 1099 } else { 1100 $scope.suggestionList = []; 1101 } 1102 }; 1103 1104 $scope.model = {}; 1105 1106 $scope.hideSuggestion = function(propertyName) { 1107 if (!!propertyName) { 1108 $scope.model[propertyName] = false; 1109 } 1110 }; 1111 1112 $scope.showSuggestion = function(propertyName) { 1113 if (!!propertyName) { 1114 $scope.model[propertyName] = true; 1115 } 1116 }; 1117 1118 $scope.suggestionsShown = function(propertyName) { 1119 if (!propertyName) { 1120 return !$.isEmptyObject($scope.suggestionList); 1121 } 1122 return !$.isEmptyObject($scope.suggestionList) && !!$scope.model[propertyName]; 1123 }; 1124 1125 $scope.suggestionsAreaShown = $scope.suggestionsShown; 1126 1127 var callElasticForSuggestions = function(query) { 1128 if (suggestionProperties.segment === "ebu") 1129 var context = "companies"; 1130 else if (suggestionProperties.segment == "large") 1131 var context = "large"; 1132 else 1133 var context = "private"; 1134 1135 $http.get(suggestionProperties.baseUrl + suggestionProperties.language, { 1136 params: { 1137 q: query, 1138 context: context, 1139 num: suggestionProperties.maxResults 1140 } 1141 }).then(function(response) { 1142 $scope.suggestionList = response.data.suggest.suggest[0].options.map(function(element) { 1143 var typed = response.data.suggest.suggest[0].text; 1144 var suggestedWord = element.text; 1145 var suggestedPart = suggestedWord.indexOf(typed) !== -1 ? suggestedWord.replace(typed, "") : ""; 1146 1147 return { 1148 typed: typed, 1149 suggestedPart: suggestedPart, 1150 suggestedWord: suggestedWord 1151 } 1152 }); 1153 }) 1154 }; 1155 1156 $scope.handleKeyboardArrows = function($event) { 1157 if ($scope.suggestionsShown()) { 1158 if ($event.keyCode === 38) { 1159 //up 1160 if (angular.isNumber(selectedIndex)) { 1161 selectedIndex = ($scope.suggestionList.length + selectedIndex - 1) % ($scope.suggestionList.length); 1162 } else { 1163 selectedIndex = $scope.suggestionList.length - 1; 1164 } 1165 $scope.query = $scope.suggestionList[selectedIndex].suggestedWord; 1166 } else if ($event.keyCode === 40) { 1167 //down 1168 if (angular.isNumber(selectedIndex)) { 1169 selectedIndex = (selectedIndex + 1) % ($scope.suggestionList.length); 1170 } else { 1171 selectedIndex = 0; 1172 } 1173 $scope.query = $scope.suggestionList[selectedIndex].suggestedWord; 1174 } 1175 } 1176 }; 1177 1178 $scope.select = function(item) { 1179 $scope.query = item.suggestedWord; 1180 }; 1181 1182 $scope.clearSuggestions = function() { 1183 $scope.suggestionList = []; 1184 }; 1185 1186 $scope.headerSearch = function(url, filterZone) { 1187 if (!$scope.query2 && !$scope.query) return; 1188 if ($scope.query2) { 1189 window.location.assign(url + '?q=' + encodeURIComponent($scope.query2) + (filterZone ? '&filterZone=' + filterZone : '')); 1190 } else if ($scope.query) { 1191 window.location.assign(url + '?q=' + encodeURIComponent($scope.query) + (filterZone ? '&filterZone=' + filterZone : '')); 1192 } 1193 }; 1194
1195 $scope.searchAnalysisFreeText = function(eventLocation) { 1196 var utag_data = getBasicUtag(); 1197 utag_data.event_searchtermorigin = 'free'; 1198 utag_data.event_location = eventLocation; 1199 AnalyticsService.reportEvent(utag_data); 1200 }; 1201 1202 $scope.searchAnalysisHistoryText = function(eventLocation) { 1203 var utag_data = getBasicUtag(); 1204 utag_data.event_location = eventLocation; 1205 if ($scope.searchHistoryTextShown) { 1206 utag_data.event_searchtermorigin = 'history'; 1207 } else { 1208 utag_data.event_searchtermorigin = 'suggestion'; 1209 } 1210 AnalyticsService.reportEvent(utag_data); 1211 }; 1212 1213 $scope.searchAnalysis = function(eventLocation) { 1214 if (angular.isNumber(selectedIndex)) {
1215 $scope.searchAnalysisHistoryText(eventLocation); 1216 } else { 1217 $scope.searchAnalysisFreeText(eventLocation); 1218 } 1219 }; 1220 1221 $scope.triggerSearchFromButton = function(searchBar, searchResultPage, filterZone) { 1222 if (document.getElementById("searchBoxRoot").className.indexOf("expanded") !== -1) { 1223 $scope.searchAnalysis(searchBar); 1224 $scope.headerSearch(searchResultPage, filterZone); 1225 } 1226 }; 1227 1228 function getBasicUtag() { 1229 var utag_data = {}; 1230 utag_data.event = 'search'; 1231 utag_data.event_searchterm = $scope.query; 1232 return utag_data; 1233 } 1234 } 1235 }; 1236 }]) 1237 }) 1238}); 1239 1240iportalFn.searchHistory = iportalFn.searchHistory || {}; 1241$.extend(iportalFn.searchHistory, { 1242 'init': (function() { 1243 angular.module('elasticSearchPages.es') 1244 .directive('searchHistory', ['$http', function($http) { 1245 var searchHistory = new SearchHistory(suggestionProperties.segment, suggestionProperties.language); 1246 return { 1247 scope: false, 1248 restrict: 'A', 1249 link: function($scope, element, attrs) { 1250 1251 $scope.getHistory = function() { 1252 if (!$scope.query && suggestionProperties.searchHistoryEnabled) { 1253 $scope.suggestionList = searchHistory.getHistory().map(function(item) { 1254 return { 1255 query: item, 1256 suggestedPart: "", 1257 name: item 1258 } 1259 }); 1260 $scope.searchHistoryTextShown = $scope.suggestionList.length !== 0; 1261 } else { 1262 $scope.searchHistoryTextShown = false; 1263 } 1264 }; 1265 1266 $scope.saveInHistory = function(query) { 1267 if (suggestionProperties.searchHistoryEnabled && query) { 1268 searchHistory.addItem(query); 1269 } 1270 }; 1271 1272 $scope.showHistoryMessage = function() { 1273 if ($scope.query) { 1274 $scope.searchHistoryTextShown = false; 1275 } 1276 } 1277 } 1278 } 1279 }]); 1280 1281 1282 angular.module('elasticSearchPages.es') 1283 .factory('searchHistoryService', function() { 1284 var searchHistory = new SearchHistory(suggestionProperties.segment, suggestionProperties.language); 1285 1286 function getHistory(query) { 1287 if (suggestionProperties.searchHistoryEnabled) { 1288 return searchHistory.getHistory().map(function(item) { 1289 return { 1290 query: item, 1291 suggestedPart: "", 1292 suggestedWord: item, 1293 name: item 1294 } 1295 }); 1296 } else 1297 return []; 1298 } 1299 1300 function saveInHistory(query) { 1301 if (suggestionProperties.searchHistoryEnabled && query) { 1302 searchHistory.addItem(query); 1303 } 1304 } 1305 1306 return { 1307 getHistory: getHistory, 1308 saveInHistory: saveInHistory 1309 } 1310 1311 }) 1312 }) 1313}); 1314 1315iportalFn.searchZones = iportalFn.searchZones || {}; 1316$.extend(iportalFn.searchZones, { 1317 'init': (function() { 1318 angular.module('elasticSearchPages.es') 1319 .directive('searchZoneEs', ['$http', '$rootScope', '$sce', '$window', "elasticDeviceService", 'AnalyticsService', 1320 function($http, $rootScope, $sce, $window, elasticDeviceService, AnalyticsService) { 1321 var suggZones = zones || {}; 1322 $rootScope.availableZonesES = suggZones; 1323 return { 1324 link: function($scope, element, attrs) { 1325 $scope.$parent.fetchZonesDatas.push(function() { 1326 if ($scope.$parent.query.length >= 3) { 1327 getKeymatchResult($scope.$parent.query); 1328 } 1329 }); 1330 1331 async function getOldVersionOfFilter() { 1332 const response = await fetch('/.rest/pxquery/v1/publicRestData/typeConceptTransSvc?path=/webapps/elastic'); 1333 const jsonResponse = await response.json(); //extract JSON from the http response 1334 if (jsonResponse && jsonResponse['webapps.elastic.newVersion'] && jsonResponse['webapps.elastic.newVersion'] === "fal
1334se") { 1335 return true; 1336 } else { 1337 return false; 1338 } 1339 } 1340 1341 async function getFilterByZone(zone) { 1342 if (!zone) { 1343 return false; 1344 } 1345 1346 var version = await getOldVersionOfFilter(); 1347 var filter; 1348 1349 // NEW VERSION 1350 if (!version) { 1351 if (zone === "help") { 1352 filter = JSON.stringify({ "AND": [ 1353 {"term": { "facetsegment": { "value": $scope.zone.segment }}}, 1354 {"term": { "facethelpmaster": { "value": true }}} 1355 ]}); 1356 } else { 1357 filter = JSON.stringify({ "AND": [ 1358 { "term": { "facetsegment": { "value": $scope.zone.segment }}}, 1359 { "term": { "facetzone": { "value": zone }}}, 1360 { "term": { "facethelpmaster": { "value": true }}} 1361 ]}); 1362 } 1363 } 1364 // OLD VERSION 1365 else { 1366 if (zone === "help") { 1367 filter = JSON.stringify({ "AND": [ 1368 { "term": { "facetsegment": $scope.zone.segment }}, 1369 { "term": { "facethelpmaster": true }} 1370 ]}); 1371 } else { 1372 filter = JSON.stringify({ "AND": [ 1373 { "term": { "facetsegment": $scope.zone.segment }}, 1374 { "term": { "facetzone": zone }}, 1375 { "term": { "facethelpmaster": true }} 1376 ]}); 1377 } 1378 } 1379 1380 return filter; 1381 } 1382 1383 async function getKeymatchResult(query) { 1384 var filter = await getFilterByZone($scope.zone.zone); 1385 1386 $http.get(searchZonesProperties.baseUrl + suggestionProperties.language, { 1387 params: { 1388 q: query ? query : '*', 1389 filter: filter, 1390 num: $scope.zone.maxResults, 1391 start: 0, 1392 keymatchContext: $scope.zone.segment 1393 } 1394 }).then(function(response) { 1395 var keymatchRes = [], 1396 keymatchSuggestion = []; 1397 1398 if (response.data.keymatches.hits.length > 0) { 1399 keymatchSuggestion = response.data.keymatches.hits[0]._source.object['keymatch-result'][0]; 1400 } 1401 1402 angular.forEach(response.data.hits.hits, function(element) { 1403 if (!element._source.title.startsWith("| Proximus")) 1404 keymatchRes.push(element); 1405 }); 1406 1407 if ($scope.$parent.query && $scope.$parent.query.length >= suggestionProperties.minChars) { 1408 angular.forEach($scope.$parent.availableZonesES, function(zone) { 1409 if (zone.zone !== $scope.zone.zone) { 1410 return; 1411 } 1412 1413 zone.results = []; 1414 1415 if (!!keymatchSuggestion) { 1416 1417 if (keymatchSuggestion.facetzone === zone.zone) { 1418 zone.results.push({ 1419 isDevice: false, 1420 label: ke
1420ymatchSuggestion.title, 1421 linkHref: keymatchSuggestion.id 1422 }); 1423 } 1424 } 1425 1426 if (!!keymatchRes) { 1427 for (var i = 0; i < keymatchRes.length; i++) { 1428 if (keymatchRes[i]._source['facetzone'] === undefined) { 1429 break; 1430 } 1431 if (keymatchRes[i]._source['facetzone'] === zone.zone) { 1432 if (elasticDeviceService.isDevice(keymatchRes[i])) { 1433 zone.results.push(elasticDeviceService.transformToDevice(keymatchRes[i])); 1434 } else { 1435 zone.results.push(elasticDeviceService.transformToNonDevice(keymatchRes[i])); 1436 } 1437 } 1438 } 1439 } 1440 }); 1441 } 1442 }); 1443 } 1444 1445 $scope.$parent.clearZonesData = function() { 1446 angular.forEach($rootScope.availableZonesES, function(zone) { 1447 zone.results = []; 1448 }); 1449 }; 1450 1451 $scope.zoneShown = function(zone) { 1452 return !$.isEmptyObject(zone.results); 1453 }; 1454 1455 $scope.goToPage = function(link) {
1456 $scope.searchAnalysisProposedItem(); 1457 $window.location.href = link; 1458 }; 1459 1460 $scope.searchAnalysisProposedItem = function() { 1461 var utag_data = getBasicUtag(); 1462 utag_data.event_searchtermorigin = 'proposed'; 1463 AnalyticsService.reportEvent(utag_data); 1464 }; 1465 1466 function getBasicUtag() { 1467 var utag_data = {}; 1468 utag_data.event = 'search'; 1469 utag_data.event_location = 'searchbar'; 1470 utag_data.event_searchterm = $scope.query; 1471 return utag_data; 1472 } 1473 1474 $scope.$parent.suggestionsAreaShown = function() { 1475 if (!$.isEmptyObject($scope.$parent.suggestionList)) { 1476 return true; 1477 } else { 1478 for (var i = 0; i < $rootScope.availableZonesES.length; i++) { 1479 if (!$.isEmptyObject($rootScope.availableZonesES[i].results)) { 1480 return true; 1481 } 1482 } 1483 return false; 1484 } 1485 } 1486 }, 1487 templateUrl: '/searchESZoneTemplate.html', 1488 replace: true 1489 } 1490 } 1491 ]) 1492 }) 1493}); 1494 1495iportalFn.suggestions.init(); 1496iportalFn.searchHistory.init(); 1497iportalFn.searchZones.init();; 1498 1499(function () { 1500 'use strict'; 1501 1502 /** 1503 * @ngdoc directive 1504 * @name beProximus.es.elemReady.directive:elemReady 1505 * @restrict 'A' 1506 * @description 1507 * # elemReady 1508 * Execute only after content has loaded 1509 * 1510 * @example 1511 * Usage: 1512 * <div data-elem-ready></div> 1513 * 1514 */ 1515 1516 angular 1517 .module('beProximus.es') 1518 .directive('elemReady', elemReady); 1519 1520 elemReady.$inject = ['$parse', '$timeout']; 1521 1522 function elemReady($parse, $timeout) { 1523 var directive = { 1524 restrict: 'A', 1525 link: function ($scope, elem, attrs) { 1526 elem.ready(function () { 1527 $timeout(function () { 1528 $scope.$apply(function () { 1529 var func = $parse(attrs.elemReady); 1530 func($scope); 1531 }) 1532 }); 1533 }) 1534 } 1535 }; 1536 return directive; 1537 } 1538})(); 1539; 1540 1541(function () { 1542 'use strict'; 1543 1544 /** 1545 * @ngdoc directive 1546 * @name beProximus.es.filter:gsa 1547 * @restrict 'A' 1548 * @description 1549 * # gsa 1550 * Handful of filters used on the searchpages: 1551 * truncate, 1552 * trust, 1553 * selected, 1554 * dateFormat, 1555 * htmlToPlaintext, 1556 * removeProximusTag 1557 */ 1558 1559 angular 1560 .module('beProximus.es') 1561 .filter('truncate', [function() { 1562 return function (input, chars, breakOnWord) { 1563 if (isNaN(chars)) return input; 1564 if (chars <= 0) return ''; 1565 if (input && input.length > chars) { 1566 input = input.substring(0, chars); 1567 if (!breakOnWord) { 1568 var lastspace = input.lastIndexOf(' '); 1569 if (lastspace !== -1) { 1570 input = input.substr(0, lastspace); 1571 } 1572 } else { 1573 while (input.charAt(input.length - 1) === ' ') { 1574 input = input.substr(0, input.length - 1); 1575 } 1576 } 1577 return input + '…'; 1578 } 1579 return input; 1580 } 1581 }]); 1582
1583 ////////////////////////////// 1584 1585 angular 1586 .module('beProximus.es') 1587 .filter('trust', ['$sce', function($sce) { 1588 return function(val) { 1589 return $sce.trustAsHtml(val); 1590 } 1591 }]); 1592 1593 ////////////////////////////// 1594 1595 angular 1596 .module('beProximus.es') 1597 .filter('selected', [function () { 1598 return function (input, visibleZones) { 1599 var results = []; 1600 angular.forEach(input, function (value, key) { 1601 if (value && key !== 'none') { 1602 results.push(key); 1603 } 1604 }); 1605 return results; 1606 }; 1607 }]); 1608 1609 ////////////////////////////// 1610 1611 angular 1612 .module('beProximus.es') 1613 .filter('dateFormat', ['$filter', function($filter) { 1614 return function (input) { 1615 if (input == null || !input) { 1616 return ""; 1617 } 1618 1619 var _date = $filter('date')(new Date(input), 'yyyy-MM-dd'); 1620 1621 return _date.toUpperCase(); 1622 } 1623 }]); 1624 1625 ////////////////////////////// 1626 1627 angular 1628 .module('beProximus.es') 1629 .filter('htmlToPlaintext', [function () { 1630 return function (text) { 1631 return text ? _.unescape(String(text).replace(/<[^>]+>/gm, '')) : ''; 1632 } 1633 }]); 1634 1635 ////////////////////////////// 1636 1637 angular 1638 .module('beProximus.es') 1639 .filter('removeProximusTag', [function () { 1640 return function (text) { 1641 text = text ? String(text).replace(" | Proximus", '') : ''; 1642 text = text ? String(text).replace("? <b>...</b>", '?') : ''; 1643 text = text ? String(text).replace("<b>...</b>",'') : ''; 1644 if(text.indexOf('| Proximus')!=-1) { 1645 text = text.substring(0,text.indexOf('| Proximus')); 1646 1647 } 1648 return text; 1649 } 1650 }]); 1651 1652})(); 1653; 1654 1655(function () { 1656 'use strict'; 1657 1658 /** 1659 * @ngdoc service 1660 * @name 1661 * @description 1662 * 1663 */ 1664 1665 angular 1666 .module('beProximus.es') 1667 .factory('GsaResultsService', GsaResultsService); 1668 1669 GsaResultsService.$inject = []; 1670 1671 function GsaResultsService() { 1672 1673 var service = { 1674 getTotalResults: getTotalResults, 1675 processOtherSegmentResults: processOtherSegmentResults, 1676 processKeymatchPagesResults: processKeymatchPagesResults, 1677 processKeymatchVideoPagesResults: processKeymatchVideoPagesResults, 1678 calculateTotalPages: calculateTotalPages, 1679 generatePages: generatePages 1680 1681 }; 1682 return service; 1683
1684 /////////////////////////////// 1685 1686 function getTotalResults(data, requiredfields, currentSegment) { 1687 if (typeof data.DYN === "undefined" || typeof data.DYN.facetsegment === "undefined") 1688 return 0; 1689 1690 if (!requiredfields) 1691 return parseInt(data.RES.M); 1692 1693 return parseInt(data.DYN.facetsegment[currentSegment], 10); 1694 } 1695 1696 function processOtherSegmentResults(data, config) { 1697 if (typeof data.RES !== "undefined") { 1698 var array = $.map(data.RES.R, function (value, index) { 1699 return [value]; 1700 }); 1701 array = array.slice(0, config.maxOtherSegmentResults); 1702 return JSON.parse(JSON.stringify(array)); 1703 } 1704 return 0; 1705 } 1706 1707 function processKeymatchPagesResults(data) { 1708 var keymatchPageMetadata = ''; 1709 1710 var metadata = new Object(); 1711 metadata.videos = new Array(); 1712 metadata.banners = new Array(); 1713 metadata.empty = true; 1714 1715 if (typeof data.RES !== "undefined" && typeof data.RES.R[0] !== "undefined") { 1716 if (typeof data.RES.R[0].MT !== "undefined") { 1717 var mt = data.RES.R[0].MT; 1718 metadata.keyword = mt["keymatch-term"]; 1719 1720 var ids = getMetadataIds(mt); 1721 for (var i = 0; i < ids.length; i++) { 1722 var splitted = ids[i].split("|"); 1723 var obj = new Object(); 1724 1725 if (splitted[0] == "video") { 1726 var id = mt["keymatch-video-id|" + splitted[1]]; 1727 var autoplay = mt["keymatch-video-autoplay|" + splitted[1]]; 1728 obj["link"] = "http://www.youtube.com/embed/" + id + "?autoplay=" + autoplay; 1729 obj["title"] = mt["keymatch-video-title|" + splitted[1]]; 1730 obj["thumbnail"] = mt["keymatch-video-thumbnail|" + splitted[1]]; 1731 metadata.videos.push(obj); 1732 metadata.empty = false; 1733 } 1734 if (splitted[0] == "banner") { 1735 obj["img"] = mt["keymatch-banner-img|" + splitted[1]]; 1736 obj["link"] = mt["keymatch-banner-link|" + splitted[1]]; 1737 metadata.banners.push(obj); 1738 metadata.empty = false; 1739 } 1740 } 1741 } 1742 } 1743 1744 keymatchPageMetadata = JSON.parse(JSON.stringify(metadata)); 1745 return keymatchPageMetadata; 1746 } 1747 1748 function processKeymatchVideoPagesResults(data) { 1749 var keymatchPageMetadata = ''; 1750 1751 var metadata = new Object(); 1752 metadata.videos = new Array(); 1753 metadata.empty = true; 1754 var limit = 3; 1755 1756 if (typeof data.RES !== "undefined" && typeof data.RES.R[0] !== "undefined") { 1757 if (typeof data.RES.R[0].MT !== "undefined") { 1758 for (var index in data.RES.R) { 1759 var mt = data.RES.R[index].MT; 1760 metadata.keyword = mt["keymatch-term"]; 1761 1762 var ids = getVideoMetadataIds(mt); 1763 for (var id in ids) { 1764 var obj = new Object(); 1765 1766 obj["link"] = data.RES.R[index].U+"?videoId="+mt["video-id|" + id]; 1767 obj["title"] = mt["video-title|" + id]; 1768 obj["videoId"] = mt["video-id|" + id]; 1769 obj["thumbnail"] = mt["video-thumnail|" + id]; 1770 1771 if(metadata.videos.length < limit) { 1772 metadata.videos.push(obj); 1773 } 1774 metadata.empty = false; 1775 1776 } 1777 } 1778 } 1779 } 1780 1781 keymatchPageMetadata = JSON.parse(JSON.stringify(metadata)); 1782 return keymatchPageMetadata; 1783 } 1784 1785 function getMetadataIds(mt) { 1786 var ids = new Array(); 1787 1788 for (var property in mt) { 1789 if (mt.hasOwnProperty(property)) { 1790 var typeId = ''; 1791 1792 if (property.indexOf("keymatch-") == -1 || property === "keymatch-term") { 1793 continue; 1794 } else { 1795 var splitted = property.split("|"); 1796 1797 if (typeof(splitted[1]) == "undefined") { 1798 continue; 1799 } 1800 1801 typeId = splitted[0].split("-")[1] + "|" + splitted[1]; 1802 (ids.indexOf(typeId) == -1) ? ids.push(typeId) : null; 1803 } 1804 } 1805 } 1806 1807 return ids; 1808 } 1809 1810 function getVideoMetadataIds(mt) { 1811 var ids = new Array(); 1812 1813 for (var property in mt) { 1814 if (mt.hasOwnProperty(property)) { 1815 1816 if (property.indexOf("video-keywords|") == -1) { 1817 continue; 1818 } else { 1819 var splitted = property.split("|"); 1820 1821 if (typeof(splitted[1]) == "undefined") { 1822 continue; 1823 } 1824 1825 ids.push(splitted[1]); 1826 } 1827 } 1828 } 1829 1830 return ids; 1831 } 1832 1833 function calculateTotalPages(data, config, facet) { 1834 var lastPage = data.RES.EN % 10 != 0; 1835 var resultsForPagination = 0; 1836 1837 if (typeof data.DYN.facetzone !== "undefined") { 1838 if (lastPage) { 1839 resultsForPagination = parseInt(data.RES.EN, 10); 1840 } else { 1841 if (facet.selectedZone === "all") { 1842 resultsForPagination = parseInt(data.DYN.facetsegment[facet.currentSegment], 10); 1843 } else { 1844 resultsForPagination = parseInt(facet.zoneResults[facet.selectedZone], 10); 1845 } 1846 } 1847 } 1848 1849 return Math.floor((resultsForPagination + config.itemsPerPage - 1) / config.itemsPerPage); 1850 } 1851 1852 function generatePages(totalPages, currentPage) { 1853 var pages = []; 1854 1855 if (totalPages > 0) { 1856 var lastDisplayedPage = currentPage + 3; 1857 var firstDisplayedPage = currentPage - 4; 1858 1859 if (lastDisplayedPage > totalPages) { 1860 lastDisplayedPage = (lastDisplayedPage < 1) ? 1 : totalPages; 1861 } 1862 if (firstDisplayedPage > totalPages) { 1863 firstDisplayedPage = totalPages; 1864 } 1865 if (firstDisplayedPage < 1) { 1866 firstDisplayedPage = 1; 1867 } 1868 1869 for (var i = firstDisplayedPage; i <= lastDisplayedPage; i++) { 1870 var page = {}; 1871 page.i = i; 1872 page.a = (i == currentPage); 1873 pages[pages.length] = page; 1874 } 1875 } 1876 return pages; 1877 } 1878 1879 1880 } 1881})(); 1882; 1883 1884(function () { 1885 'use strict'; 1886 1887 /** 1888 * @ngdoc service 1889 * @name
1890 * @description 1891 * 1892 */ 1893 1894 angular 1895 .module('beProximus.es') 1896 .factory('GsaUrlBuilder', GsaUrlBuilder); 1897 1898 GsaUrlBuilder.$inject = []; 1899 1900 function GsaUrlBuilder() { 1901 1902 var service = { 1903 searchQueryAllZones: searchQueryAllZones, 1904 searchQuerySelectedZone: searchQuerySelectedZone, 1905 searchQueryOtherSegment: searchQueryOtherSegment, 1906 calculateBaseUrlForKeymatchPageSearch: calculateBaseUrlForKeymatchPageSearch, 1907 calculateBaseUrlForKeymatchVideosSearch: calculateBaseUrlForKeymatchVideosSearch 1908 }; 1909 return service; 1910 1911 /////////////////////////////// 1912 1913 function searchQueryAllZones(scope, config, staticQuery) { 1914 var url = calculateBaseUrl(config, config.collection, staticQuery); 1915 1916 if (scope.requiredfields.length > 0) 1917 url += '&requiredfields=' + scope.requiredfields; 1918 1919 url += '&num=' + config.itemsPerPage; 1920 url += '&start=' + config.itemsPerPage * (scope.currentPage - 1); 1921 return url + '&getfields=*'; 1922 } 1923 1924 function searchQuerySelectedZone(scope, config, staticQuery) { 1925 var url = calculateBaseUrl(config, config.collection, staticQuery); 1926 1927 var hasSelectedZone = false; 1928 var selectedZone = '.('; 1929 if (scope.facet.selectedZone.length > 0) { 1930 selectedZone += 'facetzone:' + scope.facet.selectedZone; 1931 hasSelectedZone = true; 1932 } 1933 selectedZone += ')'; 1934 1935 if (hasSelectedZone) { 1936 scope.requiredfields += selectedZone; 1937 } 1938 if (scope.requiredfields.length > 0) { 1939 url += '&requiredfields=' + '(' + scope.requiredfields + "|" + scope.requiredfieldsPDF + ")"; 1940 } 1941 1942 url += '&num=' + config.itemsPerPage; 1943 url += '&start=' + config.itemsPerPage * (scope.currentPage - 1); 1944 return url + '&getfields=*'; 1945 } 1946 1947 function searchQueryOtherSegment(scope, config, collection, staticQuery) { 1948 var url = calculateBaseUrl(config, collection, staticQuery); 1949 1950 if (scope.requiredfields.length > 0) { 1951 url += '&requiredfields=' + scope.requiredfields; 1952 } 1953 1954 url += '&num=' + config.itemsPerPage; 1955 return url + '&getfields=*'; 1956 } 1957 1958 function calculateBaseUrl(config, collection, staticQuery) { 1959 var url = config.searchUrl; 1960 1961 url += (staticQuery.length > 0) ? '?q=' + encodeURIComponent(_.unescape(staticQuery)) : '?q=*'; 1962 url += '&client=' + config.client + '&proxystylesheet=' + config.proxystylesheet; 1963 url += '&output=' + config.output + '&site=' + collection + '&lr=' + config.lr; 1964 url += '&oe=' + config.oe + '&ie=' + config.ie + '&rc=' + config.rc + '&filter=' + config.filter; 1965 1966 return url; 1967 } 1968 1969 function calculateBaseUrlForKeymatchPageSearch(config) { 1970 var url = config.searchUrl; 1971 1972 url += '?q=' + '&site=' + config.keymatchCollection + '&client=' + config.client + '&proxystylesheet=' + config.proxystylesheet; 1973 1974 return url; 1975 } 1976 1977 function calculateBaseUrlForKeymatchVideosSearch(config) { 1978 var url = config.searchUrl; 1979 1980 url += '?q=' + '&site=' + config.collection + '&client=' + config.client + '&proxystylesheet=' + config.proxystylesheet; 1981 1982 return url; 1983 } 1984 } 1985})(); 1986; 1987 1988(function () { 1989 'use strict'; 1990 1991 /** 1992 * @ngdoc service 1993 * @name 1994 * @description 1995 * # 1996 */ 1997 1998 angular 1999 .module('beProximus.es') 2000 .factory('GsaUtility', GsaUtility); 2001 2002 GsaUtility.$inject = []; 2003 2004 function GsaUtility() { 2005 2006 var service = { 2007 getUrlParam: getUrlParam, 2008 cleanGsaUrl: cleanGsaUrl, 2009 getKeymatchDescription: getKeymatchDescription, 2010 getTaxRegime: getTaxRegime, 2011 getPostRegime: getPostRegime, 2012 getPreRegime: getPreRegime, 2013 getFullNormalPromotedPrice: getFullNormalPromotedPrice, 2014 getKeymatchZone: getKeymatchZone 2015 }; 2016 return service; 2017
2018 /////////////////////////////// 2019 2020 function getUrlParam(paramName) { 2021 var queryString = window.location.search.substring(1); 2022 var vars = queryString.split('&'); 2023 for (var i = 0; i < vars.length; i++) { 2024 var pair = vars[i].split('='); 2025 if (pair[0] == paramName) { 2026 var comp = pair[1].split("+").join(" "); 2027 return decodeURIComponent(comp); 2028 } 2029 } 2030 return ""; 2031 } 2032 2033 function cleanGsaUrl(result) { 2034 var sourceURL = result.GL; 2035 var rtn = sourceURL.split("?")[0], 2036 param, 2037 params_arr = [], 2038 queryString = (sourceURL.indexOf("?") !== -1) ? sourceURL.split("?")[1] : ""; 2039 if (queryString !== "") { 2040 params_arr = queryString.split("&"); 2041 for (var i = params_arr.length - 1; i >= 0; i -= 1) { 2042 param = params_arr[i].split("=")[0]; 2043 if (param === "gsaZ" || param == "gsaD") { 2044 params_arr.splice(i, 1); 2045 } 2046 } 2047 if (params_arr.length !== 0) { 2048 rtn = rtn + "?" + params_arr.join("&"); 2049 } 2050 } 2051 return rtn; 2052 } 2053 2054 function getKeymatchDescription(result) { 2055 var params = result.GL.split('&'); 2056 for (var i in params) { 2057 if (params[i].indexOf("gsaD") > -1) { 2058 return params[i].split('=')[1].replace(/\+/g, " "); 2059 } 2060 } 2061 return ''; 2062 } 2063 2064 function getTaxRegime(result) { 2065 if (typeof result.MT.product_price !== "undefined") { 2066 var priceVars = result.MT.product_price.split("-"); 2067 return priceVars[3].trim(); 2068 } 2069 return ""; 2070 } 2071 2072 function getPostRegime(result) { 2073 if (typeof result.MT.product_price !== "undefined") { 2074 var priceVars = result.MT.product_price.split("-"); 2075 return priceVars[2].trim(); 2076 } 2077 return ""; 2078 } 2079 2080 function getPreRegime(result) { 2081 if (typeof result.MT.product_price !== "undefined") { 2082 var priceVars = result.MT.product_price.split("-"); 2083 return priceVars[0].trim(); 2084 } 2085 return ""; 2086 } 2087 2088 function getFullNormalPromotedPrice (result) { 2089 if (typeof result.MT.product_price !== "undefined") { 2090 var priceVars = result.MT.product_price.split("-"); 2091 return priceVars[1].trim(); 2092 } 2093 return ""; 2094 } 2095 2096 function getKeymatchZone(result) { 2097 var params = result.GL.split('&'); 2098 for (var i in params) { 2099 if (params[i].indexOf("gsaZ") > -1) { 2100 return params[i].split('=')[1]; 2101 } 2102 } 2103 return ''; 2104 } 2105 2106 } 2107})(); 2108; 2109 2110(function () { 2111 'use strict'; 2112 angular.module("elasticSearchPages.es").factory('bazaarVoiceService', ["$sce", 2113 function ($sce) { 2114 var bazaarVoiceService = {}; 2115 bazaarVoiceService.callBazaarVoice = callBazaarVoice; 2116 2117 2118 function callBazaarVoice(productIds, prefix) { 2119 inception.deferredLoadScript(iportalData.bvUrl, function() { 2120 $BV.ui('rr', 'inline_ratings', { 2121 productIds: productIds, 2122 containerPrefix: prefix 2123 }); 2124 }); 2125 } 2126 2127 return bazaarVoiceService; 2128 }]) 2129})();; 2130 2131var iportalFn = iportalFn || {}; 2132iportalFn.searchBox = iportalFn.searchBox || {}; 2133 2134$.extend(iportalFn.searchBox, { 2135 'init': (function () { 2136 function init(dataName, segment, segmentTitle, 2137 placeholderTopMessage, placeholderResultsForMessage, placeholderNoResultsMessage) { 2138 2139 $('#rs-header-logobar #desktop_searchbox').hide(); 2140 $('#rs-header-logobar .jsrs-header-search-small-toggle').hide(); 2141 2142 angular 2143 .module('beProximus.es') 2144 .config(iportalFn.defaultNgConfig) 2145 .controller('SearchBoxController', SearchBoxController).directive('productDisplay', function() { 2146 return { 2147 restrict: 'A', 2148 require: '?ngModel', 2149 scope: {}, 2150 link: function (scope, element, attrs, ngModel) { 2151 scope.$evalAsync( 2152 function() { 2153 $('*[style]').attr('style','');
2154 inceptionEqualizer.equalize(); 2155 } 2156 ); 2157 }}; 2158 }); 2159 2160 SearchBoxController.$inject = ['$scope', '$http', '$window', '$compile', '$ocLazyLoad', "elasticDeviceService", "bazaarVoiceService", 'GsaUtility', 'GsaUrlBuilder', 'GsaResultsService']; 2161 2162 function SearchBoxController($scope, $http, $window, $compile, $ocLazyLoad, elasticDeviceService, bazaarVoiceService, gsaUtility, gsaUrlBuilder, gsaResultsService) { 2163 2164 var config = {}; 2165 var staticQuery = ''; 2166 var numberOfDevicesThreshold = 3; 2167 2168 var keymatchAdded = false; 2169 var queryCorrected = false; 2170 2171 function initController() { 2172 $scope.arrowType = { 2173 "PREVIOUS": 0, 2174 "NEXT": 1 2175 }; 2176 2177 $scope.loadType = { 2178 "QUERY_CHANGE": 0, 2179 "FILTER_CHANGE": 1, 2180 "PAGE_CHANGE": 2 2181 }; 2182 2183 $scope.loaded = false; 2184 config = iportalData[dataName].params['config']; 2185 2186 var facetSegment = ''; 2187 if (segment === 'cbu') { 2188 facetSegment = 'private'; 2189 } else if (segment === 'ebu') { 2190 facetSegment = 'companies'; 2191 } else if (segment === 'large') { 2192 facetSegment = 'large'; 2193 } 2194 2195 $scope.facet = { 2196 currentSegment: facetSegment, 2197 selectedZone: (iportalData[dataName].params['facetzone'] == "none") ? {} : iportalData[dataName].params['facetzone'], 2198 zoneResults: [] 2199 }; 2200 2201 $scope.totalResults = 0; 2202 $scope.totalPages = 0; 2203 $scope.currentPage = 1; 2204 $scope.requiredfields = ''; 2205 $scope.requiredfieldsPDF = 'gsaentity_mimeType'; 2206 $scope.suggestion = ''; 2207 $scope.oldQuery = ''; 2208 $scope.executedQuery = ''; 2209 2210 $scope.query = gsaUtility.getUrlParam('q'); 2211 $scope.query = _.unescape(secureFilters.html($scope.query)); 2212 staticQuery = $scope.query; 2213 2214 $scope.results = []; 2215 $scope.keymatchResults = []; 2216 $scope.specialDisplayResult = 0; 2217 $scope.pages = []; 2218 $scope.otherSegmentResults = []; 2219 2220 $scope.showSearchPageSuggestions = true; 2221 $scope.devices = []; 2222 $scope.displayShopLocator = false; 2223 2224 setSearchRequestFilter(); 2225 2226 if (staticQuery) { 2227 $scope.loadQuery($scope.currentPage, $scope.loadType.QUERY_CHANGE); 2228 } else { 2229 $scope.loaded = true; 2230 } 2231 } 2232 2233 $scope.submit = function(){ 2234 queryCorrected = false; 2235 $scope.loadQuery(1, $scope.loadType.QUERY_CHANGE); 2236 $scope.executedQuery = $scope.query; 2237 $scope.getKeymatchVideos(); 2238 $scope.getOtherSegmentResults(); 2239 $scope.getKeymatchPagesResults(); 2240 } 2241 2242 $scope.loadQuery = function (page, loadType) { 2243 $scope.loaded = false; 2244 $scope.currentPage = page; 2245 $scope.suggestion = ''; 2246 2247 if (loadType === $scope.loadType.QUERY_CHANGE) { 2248 staticQuery = _.escape($scope.query); 2249 $scope.executedQuery = staticQuery; 2250 queryInitialization(loadType); 2251 } else { 2252 queryOnFilter(loadType); 2253 } 2254 2255 setHtmlMessages(); 2256 $scope.showSearchPageSuggestions = false;
2257 $window.scrollTo(0, 0); 2258 }; 2259 2260 function queryInitialization(loadType) { 2261 var url = searchQueryAllZones(); 2262 2263 $http.get(url) 2264 .then(function (response) { 2265 calculateTotalResults(response.data); 2266 queryOnFilter(loadType); 2267 }, function (error) { 2268 processError(); 2269 }); 2270 } 2271 2272 function queryOnFilter(loadType) { 2273 var url = ''; 2274 if ($scope.facet.selectedZone == "all") { 2275 url = searchQueryAllZones(); 2276 } else { 2277 url = searchQuerySelectedZone(); 2278 } 2279 2280 $http.get(url) 2281 .then(function (response) { 2282 processResults(response.data, loadType); 2283 updateFilters(); 2284 $scope.saveInHistory(); 2285 }, function (error) { 2286 processError(); 2287 } 2288 ); 2289 } 2290 2291 $scope.getOtherSegmentResults = function () { 2292 var url = searchQueryOtherSegment(); 2293 $http.get(url) 2294 .then(function (response) { 2295 $scope.otherSegmentResults = gsaResultsService.processOtherSegmentResults(response.data, config); 2296 }, function (error) { 2297 processError(); 2298 }); 2299 }; 2300 2301 $scope.getKeymatchPagesResults = function () { 2302 var url = searchQueryKeymatchPages(); 2303 $http.get(url) 2304 .then(function (response) { 2305 $scope.keymatchPageMetadata = gsaResultsService.processKeymatchPagesResults(response.data); 2306 }, function (error) { 2307 processError(); 2308 } 2309 ); 2310 }; 2311 2312 $scope.getKeymatchVideos = function () { 2313 var url = searchQueryKeymatchVideos(); 2314 $http.get(url) 2315 .then(function (response) { 2316 $scope.keymatchPageVideosMetadata = gsaResultsService.processKeymatchVideoPagesResults(response.data); 2317 }, function (error) { 2318 processError(); 2319 } 2320 ); 2321 }; 2322 2323 $scope.changeQuery = function (suggestion) { 2324 $scope.query = suggestion.replace(/(<([^>]+)>)/ig, ""); 2325 $scope.loadQuery($scope.currentPage, $scope.loadType.QUERY_CHANGE); 2326 $scope.getOtherSegmentResults(); 2327 }; 2328 2329 function handleSpecialDevicesDisplay() { 2330 if ($scope.devicesDisplayEnabled) { 2331 var devices = getDeviceResults($scope.results); 2332 if (devices.length >= numberOfDevicesThreshold) { 2333 $scope.results = _.difference($scope.results, devices); 2334 $scope.devices = devices.map(elasticDeviceService.transformToDevice); 2335 } 2336 $scope.$evalAsync(function () { 2337 handleBazaarVoiceRatings($scope.displaySpecialDisplay() ? $scope.results.concat([$scope.specialDisplayResult]) : $scope.results, $scope.devices); 2338 }); 2339 } 2340 } 2341 2342 function handleShopLocator() { 2343 if(!$scope.facet.selectedZone || $scope.facet.selectedZone=='all') { 2344 angular.forEach($scope.shopLocatorTriggerWords, function (value) { 2345 var shopTriggerWordPresent = false; 2346 var text = $scope.query.trim(); 2347 if (text.indexOf(value) != -1 && !$scope.displayShopLocator) { 2348 text = text.replace(value, "").trim(); 2349 shopTriggerWordPresent = true; 2350 } 2351 if (shopTriggerWordPresent) { 2352 askForLocation(text, showShopLocator, displayIfPoslocatorLinkIsFirstResultOrHide) 2353 } else { 2354 displayIfPoslocatorLinkIsFirstResultOrHide(); 2355 } 2356 }) 2357 } 2358 } 2359 2360 function handleBazaarVoiceRatings(results, deviceResults) {
2361 var bazaarVoiceProductIds = {} 2362 for (var i = 0; i < results.length; i++) { 2363 var result = results[i]; 2364 if (($scope.isGsmDevice(result) && result.MT.eshopid && !!result.MT.bv_enabled)) { 2365 bazaarVoiceProductIds[result.MT.eshopid] = {url: result.U}; 2366 } 2367 } 2368 for (var i = 0; i < deviceResults.length; i++) { 2369 var device = deviceResults[i]; 2370 if (device.productId && device.bvEnabled) { 2371 bazaarVoiceProductIds[device.productId] = {url: device.linkHref}; 2372 } 2373 } 2374 2375 if(!_.isEmpty(bazaarVoiceProductIds)) { 2376 bazaarVoiceService.callBazaarVoice(bazaarVoiceProductIds, "BVRRInlineRating"); 2377 } 2378 } 2379 2380 function processResults(data, loadType) { 2381 $scope.results = 0; 2382 $scope.keymatchResults = {}; 2383 $scope.preview = 0; 2384 $scope.devices = []; 2385 $scope.displayShopLocator = false; 2386 2387 if (typeof data.RES !== "undefined") { 2388 $scope.results = data.RES.R; 2389 } 2390 2391 if (typeof data.PREVIEW !== "undefined") { 2392 $scope.preview = data.PREVIEW; 2393 } 2394 2395 $scope.suggestion = (typeof data.SPELLING == "undefined") ? "" : data.SPELLING.SUGGESTION; 2396 if ($scope.suggestion.length > 0 && $scope.results == 0) { 2397 $scope.oldQuery = $scope.query; 2398 queryCorrected = true; 2399 $scope.changeQuery($scope.suggestion); 2400 return; 2401 } else if (!queryCorrected) { 2402 $scope.oldQuery = ''; 2403 } 2404 2405 if (typeof data.RES.K !== "undefined") { 2406 $scope.keymatchResults = data.RES.K; 2407 processKeymatchResults(); 2408 } 2409 2410 handlePagination(data); 2411 handleSpecialDevicesDisplay(); 2412 handleShopLocator(); 2413 $scope.loaded = true; 2414 } 2415 2416 function getDeviceResults(results) { 2417 return results.filter(function (elem, index) { 2418 return elasticDeviceService.isDevice(elem); 2419 }).slice(0, numberOfDevicesThreshold); 2420 } 2421 2422 function updateFilters() { 2423 if (keymatchAdded) { 2424 $scope.totalResults = $scope.totalResults + 1; 2425 angular.forEach(config.visibleZones, function (value, key) { 2426 for (var i in $scope.keymatchResults) { 2427 if (value.name === gsaUtility.getKeymatchZone($scope.keymatchResults[i])) { 2428 if (typeof $scope.facet.zoneResults[value.name] == 'undefined') { 2429 $scope.facet.zoneResults[value.name] = 1; 2430 } else { 2431 $scope.facet.zoneResults[value.name] = parseInt($scope.facet.zoneResults[value.name]) + 1; 2432 } 2433 } 2434 } 2435 }); 2436 } 2437 } 2438 2439 function showShopLocator(location) { 2440 $ocLazyLoad.load({ 2441 name: "posLocator", 2442 files: ["https://www.proximus.be/dam/cdn/apps/poslocator/widget/posLocator.min.js"], 2443 serie: true, 2444 rerun: true, 2445 reconfig: true 2446 }).then(function () { 2447 var el, elToAppend; 2448 elToAppend = $compile('<pos-loc-widget rslib-settings-language="'+ $scope.language +'" rslib-settings-segment="' + $scope.segment +'" location="'+ location+'" id="posLocator"></pos-loc-widget>')( $scope ); 2449 el = angular.element('#posLocator'); 2450 el.html(''); 2451 el.append(elToAppend); 2452 $scope.displayShopLocator = true; 2453 }, function (e) { 2454 console.log(e); 2455 }) 2456 } 2457 2458 function askForLocation(locationString, isAddressInBelgiumCallback, failureCallback) { 2459 var geocoder = new google.maps.Geocoder(); 2460 geocoder.geocode( { 'address': locationString, region: "BE"}, function(results, status) { 2461 if (isAddress(status) && isInBelgium(results)) { 2462 isAddressInBelgiumCallback(locationString); 2463 } else { 2464 failureCallback(); 2465 } 2466 }); 2467 } 2468 2469 function hideShopLocator() { 2470 $scope.displayShopLocator = false;
2471 } 2472 2473 function displayIfPoslocatorLinkIsFirstResultOrHide(){ 2474 var results = $scope.results; 2475 if (!!results[0] && (!!results[0].U && results[0].U.toLowerCase().indexOf("poslocator") > 0) || (!!results[0] && (!!results[0].GL && results[0].GL.toLowerCase().indexOf("poslocator") > 0))) { 2476 showShopLocator(''); 2477 }else{ 2478 hideShopLocator(); 2479 } 2480 } 2481 2482 function isAddress(status){ 2483 return status === google.maps.GeocoderStatus.OK; 2484 } 2485 2486 function isInBelgium(results) { 2487 for (var i = 0; i < results.length; i++) { 2488 var country = _.find(results[i].address_components, function (ac) { 2489 return ac.types[0] == 'country' 2490 }) 2491 if (country && country.short_name == 'BE') { 2492 return true; 2493 } 2494 } 2495 return false; 2496 } 2497 2498 2499 function callBazaarVoice(productIds, prefix){ 2500 inception.deferredLoadScript(iportalData.bvUrl, function() { 2501 $BV.ui( 'rr', 'inline_ratings', { 2502 productIds : productIds, 2503 containerPrefix : prefix 2504 }); 2505 }); 2506 } 2507 2508 function processKeymatchResults() { 2509 keymatchAdded = false; 2510 for (var i in $scope.keymatchResults) { 2511 for (var j in $scope.results) { 2512 if (!keymatchAdded && $scope.cleanGsaUrl($scope.keymatchResults[i]) == $scope.results[j].U) { 2513 var addToTop = $.extend({}, $scope.results.splice(j, 1)); 2514 $scope.results.unshift(addToTop['0']); 2515 keymatchAdded = true; 2516 } 2517 } 2518 } 2519 2520 if (!keymatchAdded) { 2521 var tempKeymatch = $scope.keymatchResults[0]; 2522 if (tempKeymatch) { 2523 $scope.results.unshift(tempKeymatch); 2524 keymatchAdded = true; 2525 } 2526 } 2527 2528 $scope.specialDisplayResult = 0; 2529 var firstElement = $scope.results[0]; 2530 if (typeof firstElement !== "undefined" && ($scope.isGsmDevice(firstElement) || $scope.isPromotedPage(firstElement))) { 2531 $scope.specialDisplayResult = firstElement; 2532 $scope.results.shift(); 2533 } 2534 } 2535 2536 function calculateTotalResults(data) { 2537 $scope.totalResults = gsaResultsService.getTotalResults(data, $scope.requiredfields, $scope.facet.currentSegment); 2538 $scope.facet.zoneResults = data.DYN.facetzone; 2539 } 2540 2541 function handlePagination(data) { 2542 $scope.totalPages = gsaResultsService.calculateTotalPages(data, config, $scope.facet); 2543 if (data.RES.EN % 10 != 0) 2544 $scope.currentPage = $scope.totalPages; 2545 $scope.pages = gsaResultsService.generatePages($scope.totalPages, $scope.currentPage); 2546 } 2547 2548 function searchQueryAllZones() { 2549 $scope.requiredfields = ''; 2550 if ($scope.facet.currentSegment.length > 0) { 2551 $scope.requiredfields += '(' + 'facetsegment:' + $scope.facet.currentSegment + "|" + $scope.requiredfieldsPDF + ")"; 2552 } 2553 return gsaUrlBuilder.searchQueryAllZones($scope, config, staticQuery); 2554 } 2555 2556 function searchQuerySelectedZone() { 2557 $scope.requiredfields = ''; 2558 if ($scope.facet.currentSegment.length > 0) 2559 $scope.requiredfields += 'facetsegment:' + $scope.facet.currentSegment; 2560 2561 return gsaUrlBuilder.searchQuerySelectedZone($scope, config, staticQuery); 2562 } 2563 2564 function searchQueryOtherSegment() { 2565 $scope.requiredfields = ''; 2566 if (config.otherSegment.length > 0) { 2567 $scope.requiredfields += '(' + 'facetsegment:' + config.otherSegment + "|" + $scope.requiredfieldsPDF + ")"; 2568 } 2569 return gsaUrlBuilder.searchQueryOtherSegment($scope, config, 2570 config.collection.replace(segment, config.otherSegment), staticQuery); 2571 } 2572 2573 function searchQueryKeymatchPages() { 2574 var url = gsaUrlBuilder.calculateBaseUrlForKeymatchPageSearch(config); 2575 var term = encodeURIComponent($("<div>").text(staticQuery).html()); 2576 2577 $scope.requiredfields = ''; 2578 if ($scope.facet.currentSegment.length > 0) { 2579 $scope.requiredfields += 'keymatch-term:' + term + '.facetsegment:' + $scope.facet.currentSegment; 2580 } 2581 2582 if ($scope.requiredfields.length > 0) { 2583 url += '&requiredfields=' + $scope.requiredfields; 2584 } 2585 2586 return url + '&getfields=*'; 2587 } 2588 2589 function searchQueryKeymatchVideos() { 2590 var url = gsaUrlBuilder.calculateBaseUrlForKeymatchVideosSearch(config); 2591 var term = encodeURIComponent($("<div>").text(staticQuery).html()); 2592 2593 $scope.requiredfields = ''; 2594 if ($scope.facet.currentSegment.length > 0) { 2595 $scope.requiredfields += 'keymatch-term:' + term + '.facetsegment:' + $scope.facet.currentSegment; 2596 } 2597 2598 if ($scope.requiredfields.length > 0) { 2599 url += '&requiredfields=' + $scope.requiredfields; 2600 } 2601 2602 return url + '&getfields=*'; 2603 } 2604 2605 function processError() { 2606 $scope.totalResults = 0; 2607 $scope.loaded = true; 2608 } 2609 2610 var containsZone = function (zone) { 2611 for (index in config.visibleZones) { 2612 if (config.visibleZones[index].name == zone) 2613 return true; 2614 } 2615 return false;
2616 }; 2617 2618 var setSearchRequestFilter = function () { 2619 if (containsZone(gsaUtility.getUrlParam('filterZone'))) 2620 $scope.setSearchFilter(gsaUtility.getUrlParam('filterZone')); 2621 }; 2622 2623 $scope.selectedFilter = function (zoneName) { 2624 if ($scope.facet.selectedZone === zoneName) return "rs-selected"; 2625 return ""; 2626 }; 2627 2628 $scope.setSearchFilter = function (zoneName) { 2629 $scope.facet.selectedZone = zoneName; 2630 }; 2631 2632 $scope.clickSearchFilter = function (zoneName) { 2633 if (staticQuery) { 2634 $scope.setSearchFilter(zoneName); 2635 $scope.loadQuery(1, $scope.loadType.FILTER_CHANGE); 2636 } 2637 }; 2638 2639 $scope.getVisibleZones = function () { 2640 return config.visibleZones; 2641 }; 2642 2643 $scope.numOfResultsInZone = function (zone) { 2644 if (zone === 'all') return ''; 2645 return ($scope.facet.zoneResults && $scope.facet.zoneResults[zone]) ? '(' + $scope.facet.zoneResults[zone] + ')' : '(0)'; 2646 }; 2647 2648 $scope.displayNoResults = function () { 2649 return $scope.totalResults == 0 && $scope.keymatchResults.length == 0; 2650 }; 2651 2652 $scope.displayGsaVideos = function () { 2653 return $scope.keymatchPageVideosMetadata.videos.length == 0; 2654 }; 2655 2656 $scope.setTopMessage = function () { 2657 return placeholderTopMessage.replace("{{query}}", "<span class=\"rs-txt-pp1\">\"" + staticQuery + "\"</span>").replace("{{segment}}", "<span class=\"rs-txt-pp1\">" + segmentTitle + "</span>"); 2658 }; 2659
2660 $scope.setNoResultsMessage = function () { 2661 return placeholderNoResultsMessage.replace("{{query}}", "<strong>\"" + staticQuery + "\"</strong>").replace("{{facetSegment}}", "<strong>" + segmentTitle + "</strong>"); 2662 }; 2663 2664 $scope.setResultsForMessage = function () { 2665 return placeholderResultsForMessage.replace("{{query}}", "<strong>\"" + staticQuery + "\"</strong>").replace("{{oldQuery}}", "<strong>\"" + $scope.oldQuery + "\"</strong>"); 2666 }; 2667 2668 $scope.displayOtherSegmentResultsTitle = function (otherSegmentResultsMessage, otherSegment) { 2669 return otherSegmentResultsMessage.replace("{{otherSegment}}", otherSegment); 2670 }; 2671 2672 $scope.hasActualPrice = function (result) { 2673 if (result._source.device_price && !result._source.device_ref_price && !result._source.device_joint_offer_price) { 2674 return true; 2675 } 2676 }; 2677 2678 $scope.hasPriceStrikeThrough = function (result) { 2679 if (result._source.device_price && result._source.device_ref_price && !result._source.device_joint_offer_price) { 2680 return true; 2681 } 2682 }; 2683 2684 $scope.hasPriceJointOffer = function (result) { 2685 if (result._source.device_price && result._source.device_joint_offer_price) { 2686 return true; 2687 } 2688 }; 2689 2690 $scope.displayJointOfferPrice = function (jointOfferPrice, result) { 2691 return jointOfferPrice.replace("{{price}}", "<strong class=\"rs-txt-pp1\">€" + result._source.device_joint_offer_price + "</strong>"); 2692 }; 2693 2694 $scope.displayJointRecomendedOfferPrice = function (result) { 2695 return result._source.device_joint_offer_price; 2696 }; 2697 2698 $scope.displayDevicePrice = function (result) { 2699 return (typeof result._source.device_price !== "undefined" ? result._source.device_price : ""); 2700 }; 2701 2702 $scope.displayReferencePrice = function (result) { 2703 return (typeof result._source.device_ref_price !== "undefined" ? result._source.device_ref_price : ""); 2704 }; 2705 2706 $scope.displayAlsoOn = function () { 2707 return !jQuery.isEmptyObject($scope.facet.otherSegments); 2708 }; 2709 2710 $scope.suggestionAvailable = function () { 2711 return $scope.suggestion.length > 0; 2712 }; 2713 2714 $scope.correctionAvailable = function () { 2715 return $scope.oldQuery.length > 0; 2716 }; 2717 2718 $scope.otherSegmentResultsUnavailable = function () { 2719 return $scope.otherSegmentResults == 0; 2720 }; 2721 2722 $scope.keymatchPageMetadataUnavailable = function () { 2723 return (typeof $scope.keymatchPageMetadata == "undefined") || $scope.keymatchPageMetadata.empty == true; 2724 }; 2725 2726 $scope.keymatchPageVideosMetadataUnavailable = function () { 2727 return (typeof $scope.keymatchPageVideosMetadata == "undefined") || $scope.keymatchPageVideosMetadata.empty == true; 2728 }; 2729 2730 2731 $scope.getArrowClass = function (type) { 2732 var css_class = "arrow"; 2733 2734 if (($scope.currentPage < 2 && type == $scope.arrowType.PREVIOUS) || ($scope.currentPage == $scope.totalPages && type == $scope.arrowType.NEXT)) { 2735 css_class = css_class + " unavailable"; 2736 } 2737 2738 return css_class; 2739 }; 2740 2741 $scope.displaySpecialDisplay = function () { 2742 return $scope.specialDisplayResult != 0; 2743 }; 2744 2745 $scope.isKeymatch = function (result) { 2746 return typeof result.GD !== "undefined"; 2747 }; 2748 2749 $scope.isPdfResultReady = function (result) { 2750 return !!((result.MIME == "application/pdf") && canBeDisplayed(result.U, $scope.preview)); 2751 }; 2752 2753 $scope.displayDevices = function(){ 2754 return $scope.loaded && $scope.devicesDisplayEnabled && $scope.devices.length >= numberOfDevicesThreshold; 2755 }; 2756 2757 function canBeDisplayed(url, preview) { 2758 var uri = encodeURIComponent(url); 2759 for (var i in preview) { 2760 if ((uri == preview[i].url) && (preview[i].state == "READY")) { 2761 return true; 2762 } 2763 } 2764 return false;
2765 } 2766 2767 $scope.previewUrl = function (result) { 2768 return "https://proximus.be/GSA" + getSession(result) + "img?page=0&size=" + getPdfSize(result); 2769 }; 2770 2771 function getSession(result) { 2772 var uri = encodeURIComponent(result.U); 2773 2774 for (var i in $scope.preview) { 2775 if ((uri == $scope.preview[i].url) && ($scope.preview[i].state == "READY")) { 2776 return $scope.preview[i].resourceURI; 2777 } 2778 } 2779 return ""; 2780 } 2781 2782 function getPdfSize(result) { 2783 var uri = encodeURIComponent(result.U); 2784 2785 for (var i in $scope.preview) { 2786 if ((uri == $scope.preview[i].url) && ($scope.preview[i].state == "READY")) { 2787 return $scope.preview[i].pageThumbnailWidth; 2788 } 2789 } 2790 return "160"; 2791 2792 } 2793 2794 $scope.showForCurrentZone = function (result) { 2795 return ($scope.facet.selectedZone == gsaUtility.getKeymatchZone(result) || $scope.facet.selectedZone == "all"); 2796 }; 2797 2798 $scope.getResultDescription = function (result) { 2799 return ((typeof result.MT !== "undefined") && (typeof result.MT.description !== "undefined") ? result.MT.description : result.S); 2800 }; 2801 2802 $scope.getMetaImage = function (result) { 2803 if ($scope.isGsmDevice(result)) { 2804 return ((typeof result.MT !== "undefined") && (typeof result.MT.device_imgurl !== "undefined") ? result.MT.device_imgurl : ""); 2805 } else { 2806 return ((typeof result.MT !== "undefined") && (typeof result.MT.product_image !== "undefined") ? result.MT.product_image : ""); 2807 } 2808 }; 2809 2810 $scope.getPreRegime = function (result) { 2811 return gsaUtility.getPreRegime(result); 2812 }; 2813 2814 $scope.getFullNormalPromotedPrice = function (result) { 2815 return gsaUtility.getFullNormalPromotedPrice(result); 2816 }; 2817 2818 $scope.getPostRegime = function (result) { 2819 return gsaUtility.getPostRegime(result); 2820 }; 2821 2822 $scope.getTaxRegime = function (result) { 2823 return gsaUtility.getTaxRegime(result); 2824 }; 2825 2826 $scope.getKeymatchDescription = function (result) { 2827 return gsaUtility.getKeymatchDescription(result); 2828 }; 2829 2830 $scope.cleanGsaUrl = function (result) { 2831 return gsaUtility.cleanGsaUrl(result); 2832 }; 2833 2834 $scope.showPrice = function (result) { 2835 return typeof result.MT.device_price !== "undefined"; 2836 }; 2837 2838 $scope.isGsmDevice = function (result) { 2839 return (typeof result.MT !== "undefined") && (typeof result.MT.device_model !== "undefined") && (typeof result.MT.device_price !== "undefined"); 2840 }; 2841 2842 $scope.isPromotedPage = function (result) { 2843 return (typeof result.MT !== "undefined") && (result.MT.gsa_promoted_page === "true"); 2844 }; 2845 2846 $scope.hasProductPrice = function(result) { 2847 return (typeof result.MT !== "undefined") && (typeof result.MT.product_price !== "undefined"); 2848 }; 2849 2850 $scope.showSuggestions = function() { 2851 $scope.showSearchPageSuggestions = true; 2852 }; 2853 2854 $scope.hideSuggestions = function() { 2855 $scope.showSearchPageSuggestions = false; 2856 }; 2857 2858 $scope.searchPageSuggestionsShown = function() { 2859 return !!($scope.suggestionsShown() && $scope.showSearchPageSuggestions); 2860 }; 2861 2862 function setHtmlMessages() { 2863 $scope.topMessage = $scope.setTopMessage(); 2864 $scope.resultsForMessage = $scope.setResultsForMessage();
2865 $scope.noResultsMessage = $scope.setNoResultsMessage(); 2866 } 2867 2868 initController(); 2869 } 2870 } 2871 2872 return init; 2873 }()) 2874});; 2875 2876(function () { 2877 'use strict'; 2878 2879 angular 2880 .module('beProximus.es') 2881 .controller('esSearchContainerController', esSearchContainerController); 2882 2883 esSearchContainerController.$inject = ['$scope', '$window', '$compile', 'ElasticConstants', 'elasticCallService', 'elasticImageService', 'elasticSearchAnalysisService', 'elasticDeviceService', 'searchHistoryService', '$location']; 2884 2885 function esSearchContainerController($scope, $window, $compile, elasticConstants, elasticCallService, elasticImageService, elasticSearchAnalysisService, elasticDeviceService, searchHistoryService, $location) { 2886 var vm = this; 2887 2888 vm.executedQuery = ""; 2889 vm.esFilter = 'filter'; 2890 vm.currentPage = 1; 2891 vm.totalPages = 1; 2892 vm.pages = []; 2893 vm.zones = elasticConstants.facetZones; 2894 vm.selectedZone = setSelectedZone(); 2895 vm.suggestion = ""; 2896 vm.correctedSearch = ""; 2897 vm.noResultsSearch = ""; 2898 vm.TotalZone = 0; 2899 vm.TotalForum = 0; 2900 vm.secondCall = 0; 2901 vm.oldQuery = ""; 2902 2903 activate(); 2904
2905 //////////////////////////////////////////////////////////////////////////////////////// 2906 2907 function currentLocation() { 2908 return ($location.search().hasOwnProperty('q')) ? $location.search()['q'] : false; 2909 } 2910 2911 function activate() { 2912 vm.query = currentLocation() ? currentLocation() : $("<div/>").html(_.unescape(secureFilters.html(elasticCallService.getUrlParam('q')))).text(); 2913 vm.executedQuery = vm.query; 2914 $scope.query = vm.query; 2915 //$scope.saveInHistory(vm.query); 2916 searchHistoryService.saveInHistory(vm.query); 2917 2918 newSearch(); 2919 } 2920 2921 vm.submit = function (query) { 2922 vm.executedQuery = vm.query = $("<div/>").html(_.unescape(secureFilters.html(query))).text(); 2923 vm.suggestion = ""; 2924 vm.correctedSearch = ""; 2925 2926 //$scope.saveInHistory(vm.query); 2927 searchHistoryService.saveInHistory(vm.query); 2928 $scope.$broadcast('GSA_INPUT_SUBMIT', { 2929 query: vm.query, 2930 zone: vm.selectedZone, 2931 results: vm.results 2932 }); 2933 2934 //Added this search because was not possible to modify current query passed in URL 2935 //Now new query will be added in URL after # 2936 //Ex: iportal/en/id_search-private/personal/spp/srp-pers.html?q=samsung#?q=iphone 2937 $location.search('q', vm.query); 2938 }; 2939 2940 //This function watches for URL parameters changes 2941 $scope.$watch(function () { 2942 return location.hash; 2943 }, function (value) { 2944 if (value) { 2945 activate(); 2946 } 2947 }); 2948 2949 function newSearch() { 2950 vm.loaded = false; 2951 vm.currentPage = 1; 2952 2953 $scope.$broadcast('GSA_NEW_QUERY'); 2954 $window.scrollTo(0, 0); 2955 2956 if (!vm.query) { 2957 handleEmpty(); 2958 return; 2959 } 2960 2961 elasticCallService.getCountsPerZone(vm.query, vm.selectedZone).then(function (response) { 2962 var counters = response.data.aggregations['sterms#facetzone-aggregation-counter']['buckets']; 2963 //vm.TotalZone = 0; 2964 2965 angular.forEach(vm.zones, function (zone) { 2966 if (zone.name != 'forum') { 2967 zone.number = 0; 2968 } 2969 2970 angular.forEach(counters, function (counter) { 2971 if (zone.name == counter.key) { 2972 zone.number = counter.doc_count; 2973 } 2974 }); 2975 }); 2976 }); 2977 2978 if (hasForumSearch()) { 2979 elasticCallService.getForumResults(vm.query, vm.currentPage).then(function (response) { 2980 setForumFilter(response.data); 2981 vm.TotalForum = response.data.statistics.count; 2982 }, function (error) { 2983 setForumFilter(); 2984 }); 2985 } 2986 2987 if (vm.selectedZone.name == 'forum') { 2988 elasticCallService.getForumResults(vm.query, vm.currentPage).then(function (response) { 2989 handleResponseForum(response.data); 2990 }, function (error) { 2991 setForumFilter(); 2992 }); 2993 2994 } else { 2995 if (vm.selectedZone.name == 'all') { 2996 elasticCallService.getNormalResults(vm.query, vm.currentPage, vm.selectedZone).then(function (response) { 2997 handleResponseFilter(response); 2998 elasticCallService.ingestKeyword(vm.query).then(function (response) { 2999 }, function (error) { 3000 }); 3001 }, function () { 3002 handleEmpty(); 3003 }); 3004 } 3005 else { 3006 elasticCallService.getZoneResults(vm.query, vm.currentPage, vm.selectedZone).then(function (response) { 3007 handleResponseNoFilter(response); 3008 }, function () { 3009 handleEmpty(); 3010 }); 3011 } 3012 } 3013 } 3014 3015 function hasForumSearch() { 3016 var hasForumSearch = false;
3017 angular.forEach(vm.zones, function (zone) { 3018 if (zone.name == 'forum') { 3019 hasForumSearch = true; 3020 } 3021 }); 3022 return hasForumSearch; 3023 } 3024 3025 function contSearch() { 3026 vm.loaded = false; 3027 3028 $scope.$broadcast('GSA_NEW_QUERY'); 3029 $window.scrollTo(0, 0); 3030 3031 if (!vm.executedQuery) { 3032 handleEmpty(); 3033 return; 3034 } 3035 3036 elasticCallService.getCountsPerZone(vm.query, vm.selectedZone).then(function (response) { 3037 var counters = response.data.aggregations['sterms#facetzone-aggregation-counter']['buckets']; 3038 3039 angular.forEach(vm.zones, function (zone) { 3040 if (zone.name != 'forum') { 3041 zone.number = 0; 3042 } 3043 angular.forEach(counters, function (counter) { 3044 if (zone.name == counter.key) { 3045 zone.number = counter.doc_count; 3046 } 3047 }); 3048 }); 3049 }); 3050 3051 if (hasForumSearch()) { 3052 elasticCallService.getForumResults(vm.query, vm.currentPage).then(function (response) { 3053 setForumFilter(response.data); 3054 }, function (error) { 3055 setForumFilter(); 3056 }); 3057 } 3058 3059 if (vm.selectedZone.name == 'forum') { 3060 elasticCallService.getForumResults(vm.query, vm.currentPage).then(function (response) { 3061 handleResponseForum(response.data); 3062 }, function () { 3063 setForumFilter(); 3064 handleEmptyNoClear(); 3065 }); 3066 } else { 3067 if (vm.selectedZone.name == 'all') { 3068 elasticCallService.getNormalResults(vm.executedQuery, vm.currentPage, vm.selectedZone).then(function (response) { 3069 handleResponseFilter(response); 3070 elasticCallService.ingestKeyword(vm.query).then(function (response) { 3071 }, function (error) { 3072 }); 3073 }, function () { 3074 handleEmpty(); 3075 }); 3076 } else { 3077 elasticCallService.getZoneResults(vm.executedQuery, vm.currentPage, vm.selectedZone).then(function (response) { 3078 handleResponseNoFilter(response); 3079 }, function () { 3080 handleEmpty(); 3081 }); 3082 } 3083 } 3084 } 3085
3086 //////////////////////////////////////////////////////////////////////////////////////// 3087 3088 vm.changeQuery = function (query) { 3089 vm.query = query; 3090 vm.submit(query); 3091 }; 3092 3093 vm.switchPage = function (page) { 3094 vm.currentPage = page; 3095 elasticSearchAnalysisService.searchAnalysisForPaging(page); 3096 contSearch(); 3097 }; 3098 3099 vm.switchToNextPage = function (page) { 3100 vm.currentPage = page + 1; 3101 elasticSearchAnalysisService.searchAnalysisForNextPageClicked(page); 3102 contSearch(); 3103 }; 3104 3105 vm.switchToPreviousPage = function (page) { 3106 vm.currentPage = page - 1; 3107 elasticSearchAnalysisService.searchAnalysisForPreviousPageClicked(page); 3108 contSearch(); 3109 }; 3110 3111 vm.clickFilter = function (clickedZone) { 3112 vm.currentPage = 1; 3113 vm.results = []; 3114 vm.selectedZone = clickedZone; 3115 angular.forEach(vm.zones, function (zone) { 3116 zone.class = (vm.selectedZone.name == zone.name) ? "rs-selected" : ""; 3117 }); 3118 contSearch(); 3119 elasticSearchAnalysisService.searchAnalysisForFilter(vm.query, vm.selectedZone.number, vm.selectedZone.name); 3120 }; 3121 3122 vm.getResultZone = function (result) { 3123 var resultZone = {}; 3124 angular.forEach(vm.zones, function (zone) { 3125 if (result._source.facetzone == zone.name) 3126 resultZone = zone; 3127 }); 3128 return resultZone; 3129 }; 3130 3131 vm.getImageLink = function (result) { 3132 return elasticImageService.getTypeImage(vm.executedQuery, result, vm.getResultZone(result), vm.preview); 3133 }; 3134 3135 vm.getImageHref = function (result) { 3136 return elasticImageService.getTypeHref(vm.executedQuery, result); 3137 }; 3138 3139 vm.showEllipsis = function () { 3140 if (!vm.pages || !vm.totalPages) return false; 3141 return (vm.totalPages > 6 && vm.totalPages - vm.currentPage > 3); 3142 }; 3143 3144 vm.transformToDevice = function (result) { 3145 return elasticDeviceService.transformToDevice(result, elasticConstants.language); 3146 }; 3147 3148 vm.resultType = function (result) { 3149 if (result.threadid) 3150 return 'forum'; 3151 return elasticImageService.getType(vm.executedQuery, result); 3152 }; 3153 3154 vm.searchUnfiltered = function (query) { 3155 vm.executedQuery = vm.query = _.unescape(secureFilters.html(query)); 3156 vm.suggestion = vm.correctedSearch = ""; 3157 vm.currentPage = 1; 3158 //$scope.saveInHistory(); 3159 searchHistoryService.saveInHistory(); 3160 $scope.$broadcast('GSA_INPUT_SUBMIT', { 3161 query: vm.query, 3162 zone: vm.selectedZone, 3163 results: vm.results 3164 }); 3165 3166 vm.loaded = false; 3167 $scope.$broadcast('GSA_NEW_QUERY'); 3168 $window.scrollTo(0, 0); 3169 if (!vm.executedQuery) { 3170 handleEmpty(); 3171 return; 3172 } 3173 3174 vm.gsaFilter = 0; 3175 elasticCallService.getUnfilteredZoneResults(vm.executedQuery, vm.currentPage, vm.selectedZone.name, vm.gsaFilter).then(function (response) { 3176 handleResponseNoFilter(response); 3177 }, function (error) { 3178 handleEmpty(); 3179 }); 3180 }; 3181 3182 vm.transformForumResult = function (result) { 3183 return elasticCallService.transformForumResult(vm.forum, result); 3184 }; 3185 3186 vm.transformProductHeaderResult = function (result) { 3187 return elasticCallService.transformProductHeaderResult(result); 3188 }; 3189 3190 vm.sendClickToAnalyse = function (selectedResult) { 3191 elasticSearchAnalysisService.searchAnalysisOnSimpleLinkClick(selectedResult, vm.resultType(selectedResult)); 3192 }; 3193
3194 //////////////////////////////////////////////////////////////////////////////////////// 3195 3196 function handleResponseFilter(response) { 3197 if (handleSuggestion(response.data)) return; 3198 3199 vm.TotalZone = response.data.hits.total; 3200 vm.TotalZone += vm.TotalForum; 3201 3202 if (response.data.hits.hits == 0 || !response.data.hits.hits) { 3203 handleEmpty(); 3204 return; 3205 } 3206 3207 vm.totalResults = response.data.hits.total ? response.data.hits.total : 0; 3208 vm.results = response.data.hits.hits; 3209 3210 handlePagination(response.data, vm.TotalZone); 3211 3212 $scope.$broadcast('GSA_RESULTS_RECEIVED', { 3213 query: vm.query, 3214 zone: vm.selectedZone, 3215 results: vm.results, 3216 data: response.data 3217 }); 3218 3219 $scope.$broadcast('ELASTIC_KM_RECEIVED', { 3220 zone: vm.selectedZone, 3221 results: vm.results, 3222 data: response.data 3223 }); 3224 3225 $scope.$broadcast('ELASTIC_BANNER_RECEIVED', { 3226 query: vm.query, 3227 results: vm.results, 3228 response: response 3229 }); 3230 3231 vm.loaded = true; 3232 displayFilterMessage(); 3233 elasticSearchAnalysisService.searchAnalysisOnSearchLoad(vm.query, countResults()); 3234 } 3235 3236 function handleResponseNoFilter(response) { 3237 if (handleSuggestion(response.data)) return; 3238 3239 if ((response.data.hits.hits.length == 0 || !response.data.hits) && !response.data.keymatches.hits.length > 0) { 3240 handleEmptyNoClear(); 3241 return; 3242 } 3243 3244 vm.TotalZone = vm.totalResults = response.data.hits.total; 3245 vm.results = response.data.hits.hits; 3246 handlePagination(response.data, vm.TotalZone); 3247 3248 $scope.$broadcast('GSA_RESULTS_RECEIVED', { 3249 query: vm.query, 3250 zone: vm.selectedZone, 3251 results: vm.results, 3252 data: response.data 3253 }); 3254 3255 $scope.$broadcast('ELASTIC_KM_RECEIVED', { 3256 zone: vm.selectedZone, 3257 results: vm.results, 3258 data: response.data 3259 }); 3260 3261 vm.loaded = true; 3262 displayFilterMessage(); 3263 } 3264 3265 function handleResponseForum(data) { 3266 if (data.results.length == 0) { 3267 handleEmptyNoClear(); 3268 return; 3269 } 3270 3271 vm.results = data.results; 3272 vm.totalResults = data.statistics.count; 3273 vm.totalPages = Math.floor((data.statistics.count + elasticConstants.itemsPerPage - 1) / elasticConstants.itemsPerPage); 3274 vm.currentPage = (data.results.length % elasticConstants.itemsPerPage != 0) ? vm.totalPages : vm.currentPage; 3275 vm.pages = elasticCallService.generatePages(vm.totalPages, vm.currentPage, vm.showEllipsis()); 3276 vm.forum = data.forumUrl; 3277 vm.loaded = true; 3278 3279 $scope.$broadcast('GSA_RESULTS_RECEIVED', { 3280 query: vm.query, 3281 zone: vm.selectedZone, 3282 results: vm.results, 3283 data: response.data 3284 3285 }); 3286 } 3287 3288 function handleEmpty() { 3289 clear(); 3290 3291 $scope.$broadcast('GSA_RESULTS_RECEIVED', { 3292 query: vm.query, 3293 zone: vm.selectedZone, 3294 results: vm.results 3295 }); 3296 3297 vm.noResultsSearch = elasticConstants 3298 .noResultsMessage 3299 .replace("{{query}}", '"' + vm.query + '"'); 3300 vm.loaded = true; 3301 3302 elasticSearchAnalysisService.searchAnalysisOnSearchLoad(vm.query, countResults()); 3303 } 3304 3305 function handleEmptyNoClear() { 3306 vm.results = []; 3307 3308 $scope.$broadcast('GSA_RESULTS_RECEIVED', { 3309 query: vm.query, 3310 zone: vm.selectedZone, 3311 results: vm.results 3312 }); 3313 vm.noResultsSearch = elasticConstants 3314 .noResultsMessage 3315 .replace("{{query}}", '"' + vm.query + '"'); 3316 3317 vm.loaded = true; 3318 } 3319 3320 function handleSuggestion(data) { 3321 vm.suggestion = data['suggest']['auto-correct-suggester'][0]['options'][0] ? 3322 data['suggest']['auto-correct-suggester'][0]['options'][0]['text'] : false;
3323 3324 if (!vm.suggestion) { 3325 vm.loaded = false; 3326 vm.suggestion = false; 3327 return false; 3328 } 3329 3330 if (vm.suggestion) { 3331 if (data.hits.total > 0) { 3332 vm.loaded = true; 3333 return false; 3334 } else { 3335 vm.oldQuery = vm.query; 3336 vm.query = vm.suggestion; 3337 vm.executedQuery = vm.query; 3338 var haveResults = false; 3339 if (vm.selectedZone.name == 'all') { 3340 elasticCallService.getNormalResults(vm.executedQuery, vm.currentPage, vm.selectedZone).then(function (response) { 3341 haveResults = response.data.hits.total > 0; 3342 if (haveResults) { 3343 if (hasForumSearch()) { 3344 elasticCallService.getForumResults(vm.executedQuery, vm.currentPage).then(function (response) { 3345 setForumFilter(response.data); 3346 }, function (error) { 3347 setForumFilter(); 3348 }); 3349 } 3350 elasticCallService.getCountsPerZone(vm.executedQuery, vm.selectedZone).then(function (response) { 3351 var counters = response.data.aggregations['sterms#facetzone-aggregation-counter']['buckets']; 3352 3353 angular.forEach(vm.zones, function (zone) { 3354 if (zone.name != 'forum') { 3355 zone.number = 0; 3356 } 3357 angular.forEach(counters, function (counter) { 3358 if (zone.name == counter.key) { 3359 zone.number = counter.doc_count; 3360 } 3361 }); 3362 }); 3363 }); 3364 vm.correctedSearch = elasticConstants 3365 .spellingMessage 3366 .replace("{{query}}", "<strong>\"" + vm.suggestion + "\"</strong>") 3367 .replace("{{oldQuery}}", "<strong>\"" + vm.oldQuery + "\"</strong>"); 3368 handleResponseFilter(response); 3369 vm.loaded = true; 3370 return false; 3371 } else { 3372 vm.noResultsSearch = elasticConstants 3373 .noResultsMessage 3374 .replace("{{query}}", '"' + vm.oldQuery + '"'); 3375 vm.loaded = true; 3376 vm.suggestion = ""; 3377 vm.query = vm.executedQuery = $scope.query = vm.oldQuery; 3378 return false; 3379 } 3380 }, function () { 3381 handleEmpty(); 3382 }); 3383 } else { 3384 elasticCallService.getZoneResults(vm.executedQuery, vm.currentPage, vm.selectedZone).then(function (response) { 3385 haveResults = response.data.hits.total > 0; 3386 if (haveResults) { 3387 if (hasForumSearch()) { 3388 elasticCallService.getForumResults(vm.executedQuery, vm.currentPage).then(function (response) { 3389 setForumFilter(response.data); 3390 }, function (error) { 3391 setForumFilter(); 3392 }); 3393 } 3394 elasticCallService.getCountsPerZone(vm.executedQuery, vm.selectedZone).then(function (response) { 3395 var counters = response.data.aggregations['sterms#facetzone-aggregation-counter']['buckets']; 3396 3397 angular.forEach(vm.zones, function (zone) { 3398 if (zone.name != 'forum') { 3399 zone.number = 0; 3400 } 3401 angular.forEach(counters, function (counter) { 3402 if (zone.name == counter.key) { 3403 zone.number = counter.doc_count; 3404 } 3405 }); 3406 }); 3407 }); 3408 vm.correctedSearch = elasticConstants 3409 .spellingMessage 3410 .replace("{{query}}", "<strong>\"" + vm.suggestion + "\"</strong>") 3411 .replace("{{oldQuery}}", "<strong>\"" + vm.oldQuery + "\"</strong>"); 3412 handleResponseNoFilter(response); 3413 vm.loaded = true; 3414 return false;
3415 } else { 3416 vm.noResultsSearch = elasticConstants 3417 .noResultsMessage 3418 .replace("{{query}}", '"' + vm.oldQuery + '"'); 3419 vm.loaded = true; 3420 vm.suggestion = ""; 3421 vm.query = vm.executedQuery = $scope.query = vm.oldQuery; 3422 return false; 3423 } 3424 }, function () { 3425 handleEmpty(); 3426 }); 3427 } 3428 } 3429 } 3430 } 3431 3432 function handlePagination(data, TotalZone) { 3433 vm.totalPages = elasticCallService.calculateTotalPages(data, vm.selectedZone.name, TotalZone); 3434 vm.currentPage = ((vm.currentPage * 10) % elasticConstants.itemsPerPage != 0) ? vm.totalPages : vm.currentPage; 3435 vm.pages = elasticCallService.generatePages(vm.totalPages, vm.currentPage, vm.showEllipsis()); 3436 } 3437 3438 function setFilters(data) { 3439 angular.forEach(vm.zones, function (zone) { 3440 zone.class = (vm.selectedZone.name == zone.name) ? "rs-selected" : ""; 3441 if (data.DYN.facetzone) { 3442 if (zone.name == 'all') { 3443 zone.number = 0; 3444 } else if (zone.name != 'forum') { 3445 zone.number = data.DYN.facetzone[zone.name] ? data.DYN.facetzone[zone.name] : 0; 3446 } 3447 } else { 3448 clearNoForum(); 3449 } 3450 }); 3451 } 3452 3453 function setForumFilter(data) { 3454 $scope.$broadcast('GSA_FORUM_RESULTS', { 3455 query: vm.query, 3456 results: data 3457 }); 3458 3459 angular.forEach(vm.zones, function (zone) { 3460 if (zone.name == 'forum') { 3461 if (!data || !data.statistics || !data.statistics.count) { 3462 zone.number = 0; 3463 } else { 3464 zone.number = data.statistics.count; 3465 } 3466 } 3467 }); 3468 } 3469 3470 function setSelectedZone() { 3471 if (!vm.zones) return; 3472 3473 var filter = elasticCallService.getUrlParam("filterZone"); 3474 3475 if (filter) { 3476 var zone = vm.zones.filter(function (z) { 3477 return filter == z.name; 3478 })[0]; 3479 if (!zone) { 3480 zone = vm.zones.filter(function (z) { 3481 return elasticConstants.defaultZone == z.name; 3482 })[0]; 3483 } 3484 if (!zone) return; 3485 zone.class = "rs-selected"; 3486 return zone; 3487 } else { 3488 var zone = vm.zones.filter(function (z) { 3489 return elasticConstants.defaultZone == z.name; 3490 })[0]; 3491 if (!zone) return; 3492 zone.class = "rs-selected"; 3493 return zone; 3494 } 3495 } 3496 3497 function clear() { 3498 vm.results = []; 3499 angular.forEach(vm.zones, function (zone) { 3500 zone.number = 0; 3501 }); 3502 } 3503 3504 function clearNoForum() { 3505 vm.results = []; 3506 angular.forEach(vm.zones, function (zone) { 3507 if (zone.name != 'forum') { 3508 zone.number = 0; 3509 } 3510 }); 3511 } 3512 3513 function countResults() { 3514 var resultsCount = 0; 3515 angular.forEach(vm.zones, function (zone) { 3516 if (zone.name != 'forum') { 3517 resultsCount += parseInt(zone.number, 10); 3518 } 3519 }); 3520 return resultsCount; 3521 } 3522 3523 function displayFilterMessage() { 3524 vm.displayFilterMessage = false; 3525 setTimeout(function () { 3526 var actualResults = vm.results.length + elasticDeviceService.devices;
3527 if (vm.gsaFilter !== 0 && vm.selectedZone.name != 'all' && vm.selectedZone.name != 'forum' //If filter isn't already on and zone doesnt match 'all' or 'forum' 3528 && actualResults % elasticConstants.itemsPerPage != 0 //&& we're on the last page 3529 && (vm.totalResults != ((vm.totalPages - 1) * elasticConstants.itemsPerPage) + actualResults //&& total results is different from actual amount of results 3530 || actualResults == 1)) { //|| bordercase 3531 3532 var filterMessage = elasticConstants.filterMessage.replace(/<a href="">/g, 3533 "<a href='' data-ng-click='gsaSc.searchUnfiltered(query)'>"); 3534 var el, elToAppend; 3535 elToAppend = $compile('<span>' + filterMessage + '</span>')($scope); 3536 el = angular.element('#gsaFilterMessage'); 3537 el.html(''); 3538 el.append(elToAppend); 3539 vm.displayFilterMessage = true; 3540 } 3541 }, 300); 3542 } 3543 } 3544})();; 3545 3546(function () { 3547 'use strict'; 3548 3549 angular 3550 .module('beProximus.es') 3551 .controller('elasticBannerSearchController', elasticBannerSearchController); 3552 3553 elasticBannerSearchController.$inject = ['$scope','elasticCallService', 'elasticSearchAnalysisService']; 3554 3555 function elasticBannerSearchController($scope, elasticCallService, elasticSearchAnalysisService) { 3556 3557 $scope.keymatchPageMetadata = []; 3558 $scope.showComponent = false; 3559 3560 $scope.$on('ELASTIC_BANNER_RECEIVED', function(event, args) { 3561 var response = args.response; 3562 3563 if(args.response.data.keymatches.total > 0) 3564 handleResponseFilter(response); 3565 else 3566 handleEmpty(); 3567 }); 3568 3569 function handleResponseFilter(response){ 3570 var data = response.data; 3571 var keymatchPageMetadata = ''; 3572 3573 var metadata = new Object(); 3574 metadata.banners = new Array(); 3575 metadata.empty = true; 3576 3577 if (typeof data.keymatches !== "undefined" && typeof data.keymatches.hits[0] !== "undefined") { 3578 if (typeof data.keymatches.hits[0]._source !== "undefined") { 3579 var sourceObject = data.keymatches.hits[0]._source; 3580 metadata.keyword = sourceObject["keyword"]; 3581 3582 for( var banner in sourceObject["object"]["keymatch-banner"] ) { 3583 var obj = new Object(); 3584 3585 obj["img"] = sourceObject["object"]["keymatch-banner"][banner]['img']; 3586 obj["link"] = sourceObject["object"]["keymatch-banner"][banner]['link']; 3587 3588 metadata.banners.push(obj); 3589 metadata.empty = false; 3590 } 3591 3592 /*var ids = getMetadataIds(mt); 3593 for (var i = 0; i < ids.length; i++) { 3594 var splitted = ids[i].split("|"); 3595 var obj = new Object(); 3596 3597 if (splitted[0] == "banner") { 3598 obj["img"] = mt["keymatch-banner-img|" + splitted[1]]; 3599 obj["link"] = mt["keymatch-banner-link|" + splitted[1]]; 3600 metadata.banners.push(obj); 3601 metadata.empty = false; 3602 } 3603 }*/ 3604 } 3605 } 3606 3607 $scope.keymatchPageMetadata = JSON.parse(JSON.stringify(metadata)); 3608 3609 if(metadata.banners.length > 0){ 3610 $scope.showComponent = true; 3611 } 3612 } 3613 3614 function handleEmpty(){ 3615 $scope.keymatchPageMetadata = []; 3616 $scope.showComponent = false; 3617 } 3618 3619 function getMetadataIds(mt) { 3620 var ids = new Array(); 3621 3622 for (var property in mt) { 3623 if (mt.hasOwnProperty(property)) { 3624 var typeId = ''; 3625 3626 if (property.indexOf("keymatch-") == -1 || property === "keymatch-term") { 3627 continue; 3628 } else { 3629 var splitted = property.split("|"); 3630 3631 if (typeof(splitted[1]) == "undefined") { 3632 continue; 3633 } 3634 3635 typeId = splitted[0].split("-")[1] + "|" + splitted[1]; 3636 (ids.indexOf(typeId) == -1) ? ids.push(typeId) : null; 3637 } 3638 } 3639 } 3640 3641 return ids; 3642 } 3643 3644 $scope.bannerClicked = function (banner) {
3645 elasticSearchAnalysisService.searchAnalysisForBannerClicked(banner); 3646 } 3647 } 3648})();; 3649 3650(function () { 3651 'use strict'; 3652 3653 angular 3654 .module('beProximus.es') 3655 .controller('elasticKeymatchResultController', elasticKeymatchResultController); 3656 3657 elasticKeymatchResultController.$inject = ['$scope', '$timeout', '$http', 'elasticCallService']; 3658 3659 function elasticKeymatchResultController($scope, $timeout, $http, elasticCallService) { 3660 var vm = this; 3661 3662 $scope.$on('GSA_RESULTS_RECEIVED', function (event, args) { 3663 vm.zone = args.zone; 3664 vm.results = []; 3665 vm.zones = {}; 3666 3667 getKeymatchResult(args.data); 3668 }); 3669 3670 $scope.$on('ELASTIC_KM_RECEIVED', function (event, args) { 3671 vm.zone = args.zone; 3672 vm.results = []; 3673 vm.zones = {}; 3674 3675 getKeymatchResult(args.data); 3676 }); 3677 3678 $scope.$on('GSA_NEW_QUERY', function (event, args) { 3679 vm.results = []; 3680 vm.zones = {}; 3681 vm.zone = {}; 3682 }); 3683 3684 function getKeymatchResult(data) { 3685 var results = []; 3686 var zones = {}; 3687 3688 if ((data) && (data.keymatches.hits.length > 0)) { 3689 angular.forEach(data.keymatches.hits, function (keymatchHit) { 3690 angular.forEach(data.keymatches.hits[0]._source.object["keymatch-result"], function (keymatchRes) { 3691 var facetzone = keymatchRes.facetzone; 3692 zones[facetzone] = zones[facetzone] || {number: 0}; 3693 zones[facetzone].number = zones[facetzone].number + 1; 3694 3695 if (vm.zone.name == 'all' || vm.zone.name == keymatchRes.facetzone) { 3696 var result = {}; 3697 3698 result._source = {}; 3699 result._id = keymatchRes.id; 3700 result._source.gsa_promoted_page = keymatchRes.recommended.toString() 3701 result._source.description = keymatchRes.description; 3702 result._source.social_network_image = keymatchRes.social_network_image; 3703 result._source.facetzone = keymatchRes.facetzone; 3704 result._source.title = keymatchRes.title; 3705 results.push(result); 3706 } 3707 }); 3708 }); 3709 } 3710 3711 console.log(results); 3712 3713 vm.results = results; 3714 vm.zones = zones; 3715 } 3716 } 3717})();; 3718 3719(function () { 3720 'use strict'; 3721 3722 angular 3723 .module('beProximus.es') 3724 .controller('elasticOtherSegmentSearchController', elasticOtherSegmentSearchController); 3725 3726 elasticOtherSegmentSearchController.$inject = ['$scope', 'elasticOtherSegmentConst', 'elasticCallService', 'elasticSearchAnalysisService']; 3727 3728 function elasticOtherSegmentSearchController($scope, elasticOtherSegmentConst, elasticCallService, elasticSearchAnalysisService) { 3729 $scope.otherSegmentResults = []; 3730 $scope.page = 1; 3731 $scope.title = ""; 3732 $scope.segment = "test"; 3733 $scope.maxOtherSegmentResults = 5; 3734 $scope.showComponent = false; 3735 $scope.otherQueryStr=""; 3736 activate(); 3737
3738 ///////////////////// 3739 3740 $scope.clickOtherSegmentLink = function(){ 3741 elasticSearchAnalysisService.searchAnalysisForOtherSegmentResults($scope.segment, $scope.$parent.gsaSc.selectedZone.name) 3742 } 3743 3744 function activate() { 3745 if(elasticOtherSegmentConst.otherSegmentResultsTitle){ 3746 $scope.title=elasticOtherSegmentConst.otherSegmentResultsTitle.replace("{{otherSegment}}", elasticOtherSegmentConst.otherSegmentName); 3747 } 3748 3749 $scope.otherQueryStr = "q="+$scope.query; 3750 3751 if(elasticCallService.getUrlParam('selectedZone')){ 3752 $scope.otherQueryStr += "&selectedZone="+_.unescape(secureFilters.html(elasticCallService.getUrlParam('selectedZone'))); 3753 } 3754 3755 $scope.segment = elasticOtherSegmentConst.otherSegment; 3756 $scope.maxOtherSegmentResults = elasticOtherSegmentConst.maxOtherSegmentResults; 3757 3758 newSearch(); 3759 } 3760 3761 $scope.$on('GSA_INPUT_SUBMIT', function(event, args) { 3762 $scope.query = $scope.$parent.query; 3763 $scope.otherQueryStr = "q="+$scope.query; 3764 3765 if($scope.$parent.gsaSc.selectedZone){ 3766 $scope.otherQueryStr+="&selectedZone="+$scope.$parent.gsaSc.selectedZone.name; 3767 } 3768 3769 newSearch(); 3770 }); 3771 3772 function newSearch() { 3773 if (!$scope.query) { 3774 handleEmpty(); 3775 3776 return; 3777 } 3778 3779 elasticCallService.getOtherSegmentResults($scope.query, $scope.page, $scope.segment).then(function (response) { 3780 handleResponseFilter(response); 3781 }, function (error) { 3782 handleEmpty(); 3783 }); 3784 } 3785 3786 function handleEmpty(){ 3787 $scope.otherSegmentResults = []; 3788 $scope.showComponent = false; 3789 } 3790 3791 function startsWithTag(title) { 3792 return title.indexOf("| Proximus") == 0; 3793 } 3794 3795 function handleResponseFilter(response) { 3796 var results = response.data.hits.hits; 3797 3798 if(results !== "undefined") { 3799 $scope.otherSegmentResults = []; 3800 3801 angular.forEach(results, function (result) { 3802 if(!startsWithTag(result._source.title)) { 3803 $scope.otherSegmentResults.push({ 3804 title: result._source.title, 3805 link: result._id 3806 }); 3807 } 3808 }); 3809 3810 $scope.otherSegmentResults = $scope.otherSegmentResults.slice(0, $scope.maxOtherSegmentResults); 3811 3812 if($scope.otherSegmentResults.length == 0) { 3813 handleEmpty(); 3814 } 3815 else { 3816 $scope.showComponent = true; 3817 } 3818 } 3819 else { 3820 handleEmpty(); 3821 } 3822 } 3823 } 3824})();; 3825 3826(function () { 3827 'use strict'; 3828 3829 var ctl = angular 3830 .module('beProximus.es') 3831 .controller('elasticDeviceDisplayController', elasticDeviceDisplayController); 3832 3833 elasticDeviceDisplayController.$inject = ['$scope', '$timeout', 'ElasticConstants', 'elasticDeviceService', 'bazaarVoiceService', 'elasticSearchAnalysisService', 'RelatedColorService']; 3834 3835 ctl.directive('elemReadyy', ['$timeout', function ($timeout) { 3836 return function ($scope, element, attrs) { 3837 $timeout(function () { 3838 element.ready(function () { 3839 $scope.$apply(function () { 3840 inception.rsTooltip(); 3841 inception.clickable('.jsrs-clickable'); 3842 }) 3843 }); 3844 }, 300, false); 3845 }; 3846 }]); 3847 3848 function elasticDeviceDisplayController($scope, $timeout, elasticConstants, elasticDeviceService, bazaarV
3848oiceService, elasticSearchAnalysisService, relatedColorService) { 3849 var vm = this; 3850 var devicesColorsSorted = false; //byDefaultColorsAreNotSorted 3851 var numberOfDevicesThreshold = 3; 3852 3853 ///////////////////// 3854 3855 $scope.deviceClicked = function (item) { 3856 elasticSearchAnalysisService.searchAnalysisForDeviceClicked(item, $scope.$parent.gsaSc.selectedZone.name); 3857 } 3858 3859 $scope.$on('GSA_RESULTS_RECEIVED', function (event, args) { 3860 handleSpecialDevicesDisplay(); 3861 }); 3862 3863 vm.displayDevices = function () { 3864 return $scope.$parent.gsaSc.loaded && vm.devicesDisplayEnabled && vm.devices && vm.devices.length >= numberOfDevicesThreshold && devicesColorsSorted ; 3865 }; 3866 3867 vm.getJointOfferHref = function (mpcuuid) { 3868 return elasticConstants.configureSmartphoneHref.replace("{{mpcuuid}}", mpcuuid ? mpcuuid : ""); 3869 }; 3870 3871 //////////////////// 3872 3873 function getDeviceResults(results) { 3874 return results.filter(function (elem, index) { 3875 return elasticDeviceService.isDevice(elem); 3876 }).slice(0, numberOfDevicesThreshold); 3877 } 3878 3879 function sortColors(vm){ 3880 var myJson = new Object(); 3881 for(var i in vm.devices){ 3882 myJson[vm.devices[i].mpcuuid] = (vm.devices[i].colours); 3883 } 3884 3885 relatedColorService.callStockApi(myJson, null).then(function (response) { 3886 var index = 0; 3887 for(var key in response){ 3888 vm.devices[index++].colours = response[key]; 3889 } 3890 devicesColorsSorted = true; 3891 return 1; 3892 }, function (error) { 3893 console.log("ERROR in relatedColorService: " + error); 3894 return -1; 3895 }); 3896 } 3897 3898 function handleSpecialDevicesDisplay() { 3899 vm.devices = {}; 3900 if (vm.devicesDisplayEnabled) { 3901 var devices = getDeviceResults($scope.$parent.gsaSc.results); 3902 if (devices.length >= numberOfDevicesThreshold) { 3903 $scope.$parent.gsaSc.results = _.difference($scope.$parent.gsaSc.results, devices); 3904 vm.devices = devices.map(elasticDeviceService.transformToDevice); 3905 sortColors(vm); 3906 elasticDeviceService.devices = vm.devices.length; 3907 } 3908 } 3909 $scope.$evalAsync(function () { 3910 handleBazaarVoiceRatings($scope.$parent.gsaSc.results, vm.devices); 3911 }); 3912 $timeout(function () { 3913 inception.equalize(); 3914 }, 500); 3915 } 3916 3917 function handleBazaarVoiceRatings(results, deviceResults) { 3918 var bazaarVoiceProductIds = {}; 3919 3920 if (results) { 3921 for (var i = 0; i < results.length; i++) { 3922 var result = results[i]; 3923 if ((elasticDeviceService.isDevice(result) && result._source.device_mpcuuid && !!result._source.bv_enabled)) { 3924 bazaarVoiceProductIds[result._source.device_mpcuuid] = {url: result._id}; 3925 } 3926 } 3927 } 3928 if (deviceResults) { 3929 for (var i = 0; i < deviceResults.length; i++) { 3930 var device = deviceResults[i]; 3931 if (device.productId && device.bvEnabled) { 3932 bazaarVoiceProductIds[device.productId] = {url: device.linkHref}; 3933 } 3934 } 3935 } 3936 3937 if (!_.isEmpty(bazaarVoiceProductIds)) { 3938 bazaarVoiceService.callBazaarVoice(bazaarVoiceProductIds, "BVRRInlineRating"); 3939 } 3940 } 3941 } 3942})(); 3943 3944(function () { 3945 'use strict'; 3946 3947 angular 3948 .module('beProximus.es') 3949 .directive('rslibPackConfiguratorEqualize', equalize); 3950 3951 equalize.$inject = ['PackConfiguratorEqualize']; 3952 3953 function equalize(Equalizer) { 3954 return { 3955 restrict: 'A', 3956 link: link 3957 }; 3958 3959 function link(scope, element) { 3960 Equalizer.equalize(); 3961 } 3962 } 3963})(); 3964 3965(function () { 3966 'use strict'; 3967 3968 angular 3969 .module('beProximus.es') 3970 .directive('rslibGsaDeviceCarousel', equalize); 3971 3972 equalize.$inject = ['PackConfiguratorEqualize']; 3973 3974 function equalize (Equalizer) { 3975 return { 3976 restrict: 'A', 3977 link: link 3978 }; 3979 3980 function link (scope, element) {
3981 Equalizer.equalize(); 3982 } 3983 } 3984})(); 3985 3986(function() { 3987 'use strict'; 3988 3989 angular 3990 .module('beProximus.es') 3991 .factory('PackConfiguratorEqualize', equalizer); 3992 3993 equalizer.$inject=[]; 3994 3995 function equalizer () { 3996 var THRESHOLD=100; 3997 var timeoutId = null; 3998 3999 return{ 4000 equalize:equalize 4001 }; 4002 4003 function equalize () { 4004 if (timeoutId) { 4005 clearTimeout(timeoutId); 4006 } 4007 4008 timeoutId = setTimeout(doEqualize, THRESHOLD); 4009 } 4010 4011 function doEqualize () { 4012 Carousel.refresh(); 4013 //inception.equalize(); 4014 } 4015 } 4016}) (); 4017; 4018 4019(function () { 4020 'use strict'; 4021 4022 angular 4023 .module('beProximus.es') 4024 .service('elasticCallService', elasticCallService); 4025 4026 elasticCallService.$inject = ['$http', '$window', 'ElasticConstants']; 4027 4028 function elasticCallService($http, $window, elasticConstants) { 4029 var service = { 4030 getCountsPerZone: getCountsPerZone, 4031 getNormalResults: getNormalResults, 4032 getZoneResults: getZoneResults, 4033 getUnfilteredZoneResults: getUnfilteredZoneResults, 4034 getForumResults: getForumResults, 4035 getOtherSegmentResults: getOtherSegmentResults, 4036 orderResults: orderResults, 4037 calculateTotalPages: calculateTotalPages, 4038 generatePages: generatePages, 4039 getUrlParam: getUrlParam, 4040 transformForumResult: transformForumResult, 4041 transformProductHeaderResult: transformProductHeaderResult, 4042 getForumIcon: getForumIcon, 4043 ingestKeyword: ingestKeyword 4044 }; 4045 4046 return service; 4047 4048 /** 4049 * Get the aggregation of all the filter zones. 4050 * @param query : Search term. 4051 * @param zone : Object such as the following : 4052 * { 4053 * $$hashKey: "object:24", 4054 * class: "", 4055 * label: "Results from the whole website " 4056 * name: "all" 4057 * number: 0 4058 * target: "GSA" 4059 * } 4060 * @returns {*} 4061 */ 4062 async function getCountsPerZone(query, zone) { 4063 let version = await getOldVersionOfFilter(); 4064 if (!version) { 4065 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'private'; 4066 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4067 var filter; 4068 4069 // On EBU, there are 4 zones (3 below + "All") 4070 if(segment === "large") { 4071 filter = JSON.stringify({ "AND": [ 4072 { "term": { "facetsegment": { "value": segment }}}, 4073 { 4074 "OR": [ 4075 { "term": { "facetzone": { "value": "discover" }}}, 4076 { "term": { "facetzone": { "value": "solutions" }}}, 4077 { "term": { "facethelpmaster": { "value": true }}} 4078 ] 4079 } 4080 ]}); 4081 } 4082 // While in RES/SE (CBU), there are 5 zones (4 below + "All") 4083 else { 4084 filter = JSON.stringify({ "AND": [ 4085 { "term": { "facetsegment": { "value": segment }}}, 4086 { 4087 "OR": [ 4088 { "term": { "facetzone": { "value": "productsservices" }}}, 4089 { "term": { "facetzone": { "value": "discover" }}}, 4090 { "term": { "facetzone": { "value": "myproximus" }}}, 4091 { "term": { "facethelpmaster": { "value": true }}} 4092 ] 4093 } 4094 ]}); 4095 } 4096 4097 return $http.get(elasticConstants.searchUrl + language, { 4098 params: { 4099 q: query ? query : '*', 4100 filter: filter, 4101 aggregationFields: "facetzone,facetsegment", 4102 start: 0, 4103 num: 0 4104 } 4105 }); 4106 } else { 4107 4108 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'private'; 4109 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4110 var filter; 4111 4112 // On EBU, there are 4 zones (3 below + "All") 4113 if(segment === "large") { 4114 filter = JSON.stringify({ "AND": [ 4115 { "term": { "facetsegment": segment }}, 4116 { 4117 "OR": [ 4118 { "term": { "facetzone": "discover" }}, 4119 { "term": { "facetzone": "solutions" }}, 4120 { "term": { "facethelpmaster": true }} 4121 ] 4122 } 4123 ]}); 4124 } 4125 // While in RES/SE (CBU), there are 5 zones (4 below + "All") 4126 else { 4127 filter = JSON.stringify({ "AND": [ 4128 { "term": { "facetsegment": segment }}, 4129 { 4130 "OR": [ 4131 { "term": { "facetzone": "productsservices" }}, 4132 { "term": { "facetzone": "discover" }}, 4133 { "term": { "facetzone": "myproximus" }}, 4134 { "term": { "facethelpmaster": true }} 4135 ] 4136 } 4137 ]}); 4138 } 4139 4140 return $http.get(elasticConstants.searchUrl + language, { 4141 params: { 4142 q: query ? query : '*', 4143 filter: filter, 4144 aggregationFields: "facetzone,facetsegment", 4145 start: 0, 4146 num: 0 4147 } 4148 }); 4149 4150 4151 } 4152 } 4153 4154 /** 4155 * Get results for all zones 4156 * @param query : Search term 4157 * @param page : Number of search page (if we have >10 results, a second page is created) 4158 * @param zone : Object. See above function for an example. 4159 * @returns {*} 4160 */ 4161 async function getNormalResults(query, page, zone) { 4162 let version = await getOldVersionOfFilter(); 4163 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'private'; 4164 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4165 var filter; 4166 4167 if (!version){ 4168 // On EBU, we are only using 3 (+1, for All) zones. 4169 if(segment === "large") { 4170 filter = JSON.stringify({ "AND": [ 4171 { "term": { "facetsegment": { "value": segment }}}, 4172 { 4173 "OR": [ 4174 { "term": { "facetzone": { "value": "discover" }}}, 4175 { "term": { "facetzone": { "value": "solutions" }}}, 4176 { "term": { "facethelpmaster": { "value": true }}} 4177 ] 4178 } 4179 ]}); 4180 } 4181 // ...while in RES/SE, there are 5 (+2, for All & Forum) zones. 4182 else { 4183 filter = JSON.stringify({ "AND": [ 4184 { "term": { "facetsegment": { "value": segment }}}, 4185 { 4186 "OR": [ 4187 { "term": { "facetzone": { "value": "productsservices" }}}, 4188 { "term": { "facetzone": { "value": "discover" }}}, 4189 { "term": { "facetzone": { "value": "myproximus" }}}, 4190 { "term": { "facethelpmaster": { "value": true }}} 4191 ] 4192 } 4193 ]}); 4194 } 4195 4196 return $http.get(elasticConstants.searchUrl + language, { 4197 params: { 4198 q: query ? query : '*', 4199 filter: filter, 4200 keymatchContext: segment, 4201 start: elasticConstants.itemsPerPage * (page - 1), 4202 num: elasticConstants.itemsPerPage 4203 } 4204 }); 4205 } else { 4206 // On EBU, we are only using 3 (+1, for All) zones. 4207 if(segment === "large") { 4208 filter = JSON.stringify({ "AND": [ 4209 { "term": { "facetsegment": segment }}, 4210 { 4211 "OR": [ 4212 { "term": { "facetzone": "discover" }}, 4213 { "term": { "facetzone": "solutions" }}, 4214 { "term": { "facethelpmaster": true }} 4215 ] 4216 } 4217 ]}); 4218 } 4219 // ...while in RES/SE, there are 5 (+2, for All & Forum) zones. 4220 else { 4221 filter = JSON.stringify({ "AND": [ 4222 { "term": { "facetsegment": segment }}, 4223 { 4224 "OR": [ 4225 { "term": { "facetzone": "productsservices" }}, 4226 { "term": { "facetzone": "discover" }}, 4227 { "term": { "facetzone": "myproximus" }}, 4228 { "term": { "facethelpmaster": true }} 4229 ] 4230 } 4231 ]}); 4232 } 4233 4234 return $http.get(elasticConstants.searchUrl + language, { 4235 params: { 4236 q: query ? query : '*', 4237 filter: filter, 4238 keymatchContext: segment, 4239 start: elasticConstants.itemsPerPage * (page - 1), 4240 num: elasticConstants.itemsPerPage 4241 } 4242 }); 4243 } 4244 } 4245 4246 /** 4247 * Get results from a specific zone (but Forum) 4248 * @param query : Search term. 4249 * @param page : Number of search page (if we have >10 results, a second page is created) 4250 * @param zone : Object. See above function for an example. 4251 * @returns {*} 4252 */ 4253 async function getZoneResults(query, page, zone) { 4254 let version = await getOldVersionOfFilter(); 4255 if (!version){ 4256 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'private'; 4257 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4258 var index = 'pxms-' + language; 4259 var filter; 4260 4261 // In the case the filter zone is "help", we need to avoid getting duplicates.
4262 // That is why we are replacing facetzone: help by facethelpmaster: true. 4263 // This latter tag has been espescially created to get only the FAQ Master page. 4264 if(zone.name === "help") { 4265 filter = JSON.stringify({ "AND": [ 4266 { "term": { "facetsegment": { "value": segment }}}, 4267 { "term": { "facethelpmaster": { "value": true }}} 4268 ]}); 4269 } 4270 else { 4271 filter = JSON.stringify({ 4272 "AND": [ 4273 {"term": {"facetsegment": {"value": segment}}}, 4274 {"term": {"facetzone": {"value": zone.name}}} 4275 ] 4276 }); 4277 } 4278 4279 return $http.get(elasticConstants.searchUrl + language, { 4280 params: { 4281 q: query ? query : '*', 4282 filter: filter, 4283 num: elasticConstants.itemsPerPage, 4284 start: elasticConstants.itemsPerPage * (page - 1), 4285 keymatchContext: segment 4286 } 4287 }); 4288 } else { 4289 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'private'; 4290 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4291 var index = 'pxms-' + language; 4292 var filter; 4293 4294 // In the case the filter zone is "help", we need to avoid getting duplicates. 4295 // That is why we are replacing facetzone: help by facethelpmaster: true. 4296 // This latter tag has been espescially created to get only the FAQ Master page. 4297 if(zone.name === "help") { 4298 filter = JSON.stringify({ "AND": [ 4299 { "term": { "facetsegment": segment }}, 4300 { "term": { "facethelpmaster": true }} 4301 ]}); 4302 } 4303 else { 4304 filter = JSON.stringify({ 4305 "AND": [ 4306 {"term": {"facetsegment": segment }}, 4307 {"term": {"facetzone": zone.name}} 4308 ] 4309 }); 4310 } 4311 4312 return $http.get(elasticConstants.searchUrl + language, { 4313 params: { 4314 q: query ? query : '*', 4315 filter: filter, 4316 num: elasticConstants.itemsPerPage, 4317 start: elasticConstants.itemsPerPage * (page - 1), 4318 keymatchContext: segment 4319 } 4320 }); 4321 } 4322 } 4323 4324 function getUnfilteredZoneResults(query, page, zone, filter) { 4325 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'private'; 4326 var requiredFields = '(facetsegment:' + segment + '.(facetzone:' + zone + ')|gsaentity_mimeType)'; 4327 4328 return getNormalResults(query, page, elasticConstants.collection, requiredFields, filter); 4329 } 4330 4331 /** 4332 * Get Forum results. 4333 * @param query : Search term. 4334 * @param page : Number of search page (if we have >10 results, a second page is created) 4335 * @param pageSize 4336 * @returns {*} 4337 */ 4338 function getForumResults(query, page, pageSize ) { 4339 return $http.get('https://www.proximus.be/api/forum', { 4340 params: { 4341 query: query ? query : '*', 4342 language: elasticConstants.language ? elasticConstants.language : 'en', 4343 type: 'threadList', 4344 pageSize: pageSize ? pageSize : elasticConstants.itemsPerPage, 4345 page: page 4346 } 4347 }); 4348 } 4349 4350 /** 4351 * Get 'Other segment' box results (located in the result page, in the right side) 4352 * In the case, we are in RES, we show SE results. 4353 * In the case of SE, we show RES. 4354 * In the case of EBU, we show SE. 4355 * @param query 4356 * @param page 4357 * @param segment 4358 * @returns {*} 4359 */ 4360 async function getOtherSegmentResults(query, page, segment) { 4361 let version = await getOldVersionOfFilter(); 4362 if (!version){ 4363 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4364 var filter = JSON.stringify({ "AND" : [ 4365 { "term": { "facetsegment": { "value": segment }}}, 4366 { 4367 "OR": [ 4368 { "term": { "facetzone": { "value": "productsservices" }}}, 4369 { "term": { "facetzone": { "value": "discover" }}}, 4370 { "term": { "facetzone": { "value": "myproximus" }}}, 4371 { "term": { "facethelpmaster": { "value": true }}} 4372 ]}] 4373 }); 4374 4375 return $http.get(elasticConstants.searchUrl + language, { 4376 params: { 4377 q: query ? query : '*', 4378 filter: filter, 4379 start: elasticConstants.itemsPerPage * (page - 1), 4380 num: elasticConstants.itemsPerPage 4381 } 4382 }); 4383 } else { 4384 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4385 var filter = JSON.stringify({ "AND" : [ 4386 { "term": { "facetsegment": segment }}, 4387 { 4388 "OR": [ 4389 { "term": { "facetzone": "productsservices" }}, 4390 { "term": { "facetzone": "discover" }}, 4391 { "term": { "facetzone": "myproximus" }}, 4392 { "term": { "facethelpmaster": true }} 4393 ]}] 4394 }); 4395 4396 return $http.get(elasticConstants.searchUrl + language, { 4397 params: { 4398 q: query ? query : '*', 4399 filter: filter, 4400 start: elasticConstants.itemsPerPage * (page - 1), 4401 num: elasticConstants.itemsPerPage 4402 } 4403 }); 4404 } 4405 } 4406 4407 async function getOldVersionOfFilter() { 4408 const response = await fetch('/.rest/pxquery/v1/publicRestData/typeConceptTransSvc?path=/webapps/elastic'); 4409 const jsonResponse = await response.json(); //extract JSON from the http response 4410 4411 if (jsonResponse && jsonResponse['webapps.elastic.newVersion'] && jsonResponse['webapps.elastic.newVersion'] === "fal
4411se") { 4412 return true; 4413 } else { 4414 return false; 4415 } 4416 } 4417 4418 function ingestKeyword(keyword) { 4419 var old = ""; 4420 4421 if(old !== keyword) { 4422 var language = elasticConstants.language ? elasticConstants.language : 'en'; 4423 var segment = elasticConstants.facetSegment ? elasticConstants.facetSegment : 'all'; 4424 } 4425 4426 old = keyword; 4427 4428 return $http.post(suggestionProperties.baseUrl + language + "?q=" + keyword + "&contexts=" + segment) 4429 } 4430 4431 function getRequiredFieldsZones() { 4432 var requiredFields = ''; 4433 for (var i in elasticConstants.facetZones) { 4434 var zone = elasticConstants.facetZones[i]; 4435 if (zone.name !== 'help' && zone.name !== 'forum' && zone.name !== 'all') { 4436 requiredFields += 'facetzone:' + zone.name + '|'; 4437 } 4438 } 4439 var segment = elasticConstants.facetSegment; 4440 if(segment !== 'large') { 4441 requiredFields += 'facethelpmaster:true'; 4442 } else { 4443 requiredFields += 'facetzone:help'; 4444 } 4445 return requiredFields; 4446 } 4447 4448 function orderResults(results, zones) { 4449 var ordered = []; 4450 var resultsCopy = results.slice(0); 4451 4452 for (var z in zones) { 4453 var zoneResults = []; 4454 var zoneResultsRecommended = []; 4455 for (var r in results) { 4456 if (results[r].MT.facetzone === zones[z].name) { 4457 if (results[r].MT.gsa_promoted_page === 'true') { 4458 zoneResultsRecommended.push(results[r]); 4459 } else { 4460 zoneResults.push(results[r]); 4461 } 4462 resultsCopy.splice(resultsCopy.indexOf(results[r]), 1); 4463 } 4464 } 4465 ordered.push.apply(ordered, zoneResultsRecommended); 4466 ordered.push.apply(ordered, zoneResults); 4467 } 4468 4469 ordered.push.apply(ordered, resultsCopy); 4470 4471 return ordered; 4472 } 4473 4474 function calculateTotalPages(data, zone, TotalZone) { 4475 var lastPage = TotalZone % elasticConstants.itemsPerPage !== 0; 4476 var resultsForPagination = 0; 4477 4478 resultsForPagination = (zone === "all") ? parseInt(TotalZone) : parseInt(data.hits.total); 4479 4480 return Math.floor((resultsForPagination + elasticConstants.itemsPerPage - 1) / elasticConstants.itemsPerPage); 4481 } 4482 4483 function generatePages(totalPages, currentPage, showEllipsis) { 4484 var pages = []; 4485 4486 if (totalPages > 0) { 4487 var lastPage = 0; 4488 var firstPage = 0; 4489 4490 if (totalPages === currentPage) { 4491 firstPage = ((totalPages - 5) < 1) ? 1 : totalPages - 5; 4492 lastPage = totalPages; 4493 } else if (showEllipsis) { 4494 if (currentPage < 4) { 4495 firstPage = 1; 4496 lastPage = 4; 4497 } else { 4498 firstPage = currentPage - 2; 4499 lastPage = currentPage + 1; 4500 } 4501 } else { 4502 firstPage = ((totalPages - 5) < 1) ? 1 : totalPages - 5; 4503 lastPage = totalPages; 4504 } 4505 4506 for (var i = firstPage; i <= lastPage; i++) { 4507 pages.push(i); 4508 } 4509 } 4510 return pages; 4511 } 4512 4513 function getUrlParam(paramName) { 4514 var queryString = $window.location.search.substring(1); 4515 var vars = queryString.split('&'); 4516 for (var i = 0; i < vars.length; i++) { 4517 var pair = vars[i].split('='); 4518 if (pair[0] === paramName) { 4519 var comp = pair[1].split("+").join(" "); 4520 return decodeURIComponent(comp); 4521 } 4522 } 4523 return ""; 4524 } 4525 4526 function transformForumResult(forum, result) { 4527 result.threadHref = forum + "/fid-" + result.forumid + "/tid-" + result.threadid; 4528 result.forumHref = forum + "/fid-" + result.forumid; 4529 result.forumIcon = getForumIcon(result); 4530 result.avatar = getAvatar(forum, result); 4531 result.userHref = forum + "/members/" + result.postusername + "-" + result.postuserid; 4532 result.lastposterHref = forum + "/members/" + result.lastposter + "-" + result.lastposterid; 4533 result.commentsHref = result.threadHref + "#comments"; 4534 4535 return result; 4536 } 4537 4538 function getForumIcon(result) { 4539 var forumIcon = ""; 4540 angular.forEach(elasticConstants.forumIcons, function (icon) { 4541 if (result.forumid === icon.id) 4542 forumIcon = icon.icon; 4543 }); 4544 return forumIcon ? forumIcon : elasticConstants.defaultForumIcon; 4545 } 4546 4547 function getAvatar(forum, result){ 4548 if(result && result.avatar){ 4549 if(result.avatar.indexOf("http") === 0){ 4550 return result.avatar; 4551 }else{ 4552 return forum+result.avatar; 4553 } 4554 } 4555 return ""; 4556 } 4557 4558 function transformProductHeaderResult(result) { 4559 result.preRegime = result._source.product_price.split("-")[0].trim(); 4560 result.postRegime = result._source.product_price.split("-")[2].trim(); 4561 result.taxRegime = result._source.product_price.split("-")[3].trim(); 4562 result.displayPriceUnit = getPriceUnit(result._source.product_price.split("-")[1].trim()); 4563 result.displayPriceDecimal = getPriceDecimal(result._source.product_price.split("-")[1].trim(), elasticConstants.language); 4564 return result; 4565 } 4566 4567 function getPriceUnit(price) { 4568 if (!price) return ""; 4569 if (price.toString().indexOf(".") > -1) 4570 return price.toString().split(".")[0]; 4571 return price.toString().split(",")[0]; 4572 } 4573 4574 function getPriceDecimal(price, language) { 4575 if (!price) return ""; 4576 if (price.toString().indexOf(".") > -1 && price.toString().split(".")[1]) 4577 return ((language === "fr" || language === "nl" || language === "de") ? "." : ",") + price.toString().split(".")[1]; 4578 if (price.toString().indexOf(",") > -1 && price.toString().split(",")[1]) 4579 return "," + price.toString().split(",")[1]; 4580 return ""; 4581 } 4582 } 4583})(); 4584; 4585 4586(function () { 4587 'use strict'; 4588 4589 angular 4590 .module('beProximus.es') 4591 .service('elasticImageService', elasticImageService); 4592 4593 elasticImageService.$inject = ['ElasticConstants']; 4594 4595 function elasticImageService(elasticConstants) { 4596 4597 var GsaType = { 4598 VIDEO : "video", 4599 PRODUCT : "product", 4600 BLOG : "blog", 4601 PDF : "pdf", 4602 FAQ : "faq", 4603 ZONE : "zone", 4604 QELP : "qelp" 4605 }; 4606 4607 var service = { 4608 getTypeImage: getTypeImage, 4609 getTypeHref: getTypeHref, 4610 getType: getType 4611 }; 4612 return service; 4613
4614 ///////////////////////////////// 4615 4616 function getTypeImage(query, result, zone, preview) { 4617 if (getType(query, result) == GsaType.VIDEO) 4618 return getVideoImage(result); 4619 if (result._source["social_network_image"]) 4620 return result._source["social_network_image"]; 4621 4622 switch (getType(query, result)) { 4623 case GsaType.QELP: 4624 return getQelpImage(result, zone); 4625 case GsaType.PRODUCT: 4626 return getProductImage(result, zone); 4627 case GsaType.BLOG: 4628 return getBlogImage(result); 4629 case GsaType.PDF: 4630 return getPdfImage(result, preview); 4631 case GsaType.FAQ: 4632 return getFaqImage(result, zone); 4633 case GsaType.ZONE: 4634 return elasticConstants.imageLinks[zone.name] ? elasticConstants.imageLinks[zone.name] : ""; 4635 default: 4636 return ""; 4637 } 4638 } 4639 4640 function getTypeHref(query, result) { 4641 if (getType(query, result) == GsaType.VIDEO && result._source["video-autoplay|0"]) 4642 return result.U+"?videoId="+result._source["video-id|0"]; 4643 return result.U; 4644 } 4645 4646 function getType(query, result) { 4647 if (hasVideo(result)) 4648 return GsaType.VIDEO; 4649 if (result._source.device_model || result._source.product_price) 4650 return GsaType.PRODUCT; 4651 if (result._source.gsa_category) 4652 return GsaType.BLOG; 4653 if (result.MIME == "application/pdf") 4654 return GsaType.PDF; 4655 if (result._source.facetzone == "help" && result._source.qelp) 4656 return GsaType.QELP; 4657 if (result._source.facetzone == "help") 4658 return GsaType.FAQ; 4659 return GsaType.ZONE; 4660 } 4661 4662 function hasVideo(result) { 4663 for (var property in result._source) { 4664 if (result._source.hasOwnProperty(property)) { 4665 if (property.indexOf("video_id") != -1) 4666 return true; 4667 } 4668 } 4669 return false; 4670 } 4671 4672 function getVideoImage(result) { 4673 var thumbnail = result._source["video_thumbnail"]; 4674 var youtubeImg = result._source["video_id"] ? "http://img.youtube.com/vi/" + result._source["video_id"] + "/0.jpg" : ""; 4675 return thumbnail ? thumbnail : (youtubeImg ? youtubeImg : elasticConstants.imageLinks["video"]); 4676 } 4677 4678 function getQelpImage(result, zone) { 4679 return result._source.social_network_image ? result._source.social_network_image : elasticConstants.imageLinks["qelp"] ? elasticConstants.imageLinks["qelp"] : elasticConstants.imageLinks[zone.name]; 4680 } 4681 4682 function getProductImage(result, zone) { 4683 return result._source.product_image ? result._source.product_image : (result._source.device_imgurl ? result._source.device_imgurl : elasticConstants.imageLinks[zone.name]); 4684 } 4685 4686 function getFaqImage(result, zone) { 4687 return result._source.faq_image ? result._source.faq_image : (elasticConstants.imageLinks[zone.name] ? elasticConstants.imageLinks[zone.name] : ""); 4688 } 4689 4690 function getBlogImage(result) { 4691 return result._source.gsa_image || ""; 4692 } 4693 4694 function getPdfImage(result, preview) { 4695 var session = getSession(result, preview); 4696 var size = getPdfSize(result, preview); 4697 var preview = "https://proximus.be/GSA" + session + "img?page=0&size=" + size; 4698 return (session && size) ? preview : (elasticConstants.imageLinks["pdf"] ? elasticConstants.imageLinks["pdf"] : ""); 4699 } 4700 4701 function getSession(result, preview) { 4702 var uri = encodeURIComponent(result.U); 4703 for (var i in preview) { 4704 if ((uri == preview[i].url) && (preview[i].state == "READY")) { 4705 return preview[i].resourceURI; 4706 } 4707 } 4708 return ""; 4709 } 4710 4711 function getPdfSize(result, preview) { 4712 var uri = encodeURIComponent(result.U); 4713 for (var i in preview) { 4714 if ((uri == preview[i].url) && (preview[i].state == "READY")) { 4715 return preview[i].pageThumbnailWidth; 4716 } 4717 } 4718 return "160"; 4719 } 4720 } 4721})(); 4722 4723 4724; 4725 4726(function () { 4727 'use strict'; 4728 4729 angular 4730 .module('beProximus.es') 4731 .controller('shopLocatorController', shopLocatorController); 4732 4733 shopLocatorController.$inject = ['$scope', '$compile', '$ocLazyLoad']; 4734 4735 function shopLocatorController($scope, $compile, $ocLazyLoad) { 4736 var vm = this; 4737
4738 ///////////////////// 4739 4740 $scope.$on('GSA_RESULTS_RECEIVED', function (event, args) { 4741 setTimeout(function() { 4742 handleShopLocator(args.query, args.zone, args.results); 4743 }, 3000); 4744 }); 4745 4746 $scope.$on('GSA_NEW_QUERY', function (event, args) { 4747 hideShopLocator(); 4748 }); 4749 4750 //////////////////// 4751 4752 function handleShopLocator(query, zone, results) { 4753 if (!zone || zone.name == 'all') { 4754 var shopTriggerWordPresent = false; 4755 var text = query.trim(); 4756 angular.forEach(vm.shopLocatorTriggerWords, function (value) { 4757 if (value.length > 0) { 4758 if (text.indexOf(value) != -1) { 4759 text = text.replace(value, "").trim(); 4760 shopTriggerWordPresent = true; 4761 } 4762 } 4763 }); 4764 if (shopTriggerWordPresent) { 4765 askForLocation(text, showShopLocator, displayIfPoslocatorLinkIsFirstResultOrHide, results) 4766 } else { 4767 displayIfPoslocatorLinkIsFirstResultOrHide(results); 4768 } 4769 } else { 4770 hideShopLocator(); 4771 } 4772 } 4773 4774 function askForLocation(locationString, isAddressInBelgiumCallback, failureCallback, results) { 4775 var gsaResults = results; 4776 var geocoder = new google.maps.Geocoder(); 4777 geocoder.geocode({'address': locationString, region: "BE"}, function (results, status) { 4778 if (isAddress(status) && isInBelgium(results)) { 4779 isAddressInBelgiumCallback(locationString); 4780 } else { 4781 failureCallback(gsaResults); 4782 } 4783 }); 4784 } 4785 4786 function hideShopLocator() { 4787 vm.displayShopLocator = false; 4788 } 4789 4790 function displayIfPoslocatorLinkIsFirstResultOrHide(results) { 4791 if (!!results[0] && (!!results[0].U && results[0].U.toLowerCase().indexOf("poslocator") > 0) || (!!results[0] && (!!results[0].GL && results[0].GL.toLowerCase().indexOf("poslocator") > 0))) { 4792 showShopLocator(''); 4793 } else { 4794 hideShopLocator(); 4795 } 4796 } 4797 4798 function isAddress(status) { 4799 return status === google.maps.GeocoderStatus.OK; 4800 } 4801 4802 function isInBelgium(results) { 4803 for (var i = 0; i < results.length; i++) { 4804 var country = _.find(results[i].address_components, function (ac) { 4805 return ac.types[0] == 'country' 4806 }); 4807 if (country && country.short_name == 'BE') { 4808 return true; 4809 } 4810 } 4811 return false; 4812 } 4813 4814 function showShopLocator(location) { 4815 $ocLazyLoad.load({ 4816 name: "posLocator", 4817 files: ["https://www.proximus.be/dam/cdn/apps/poslocator/widget/posLocator.min.js"], 4818 serie: true, 4819 rerun: true, 4820 reconfig: true 4821 }).then(function () { 4822 var el, elToAppend; 4823 elToAppend = $compile('<pos-loc-widget rslib-settings-language="' + vm.language + '" rslib-settings-segment="' + vm.segment + '" location="' + location + '" id="posLocator"></pos-loc-widget>')($scope); 4824 el = angular.element('#posLocator'); 4825 el.html(''); 4826 el.append(elToAppend); 4827 vm.displayShopLocator = true; 4828 }, function (e) { 4829 console.log(e); 4830 }) 4831 } 4832 4833 } 4834})();; 4835 4836(function () { 4837 'use strict'; 4838 4839 angular 4840 .module('beProximus.es') 4841 .controller('forumSearchController', forumSearchController); 4842 4843 forumSearchController.$inject = ['$scope','elasticCallService','GsaRForumConst']; 4844 4845 function forumSearchController($scope,elasticCallService,gsaRForumConst) { 4846 4847 $scope.results = []; 4848 $scope.showComponent = false; 4849 $scope.forumUrl = null; 4850 4851 $scope.$on('GSA_FORUM_RESULTS', function(event, args) { 4852 $scope.query = args.query; 4853 newSearch(args.results); 4854 }); 4855 4856 function newSearch(response) { 4857 if ($scope.query && (typeof response !== "undefined") && response.results && response.results.length > 0) { 4858 handleResponseFilter(response); 4859 } else { 4860 handleEmpty(); 4861 } 4862 } 4863 4864 function handleEmpty(){ 4865 $scope.results = []; 4866 $scope.showComponent = false;
4867 } 4868 4869 function handleResponseFilter(response){ 4870 $scope.results= response.results; 4871 $scope.forumUrl = response.forumUrl; 4872 $scope.showComponent = $scope.results.length > 0; 4873 } 4874 4875 $scope.avatarUrl=function(thread){ 4876 if(thread && thread.avatar){ 4877 if(thread.avatar.indexOf("http")==0){ 4878 return thread.avatar; 4879 }else{ 4880 return $scope.forumUrl+"/"+thread.avatar; 4881 } 4882 } 4883 }; 4884 4885 $scope.userProfilUrl=function(thread){ 4886 return $scope.forumUrl+"/members/"+thread.postusername+"-"+thread.postuserid; 4887 }; 4888 4889 $scope.forumIdUrl=function(thread){ 4890 return $scope.forumUrl+"/fid-"+thread.forumid; 4891 }; 4892 4893 $scope.threadUrl=function(thread){ 4894 return $scope.forumUrl+"/fid-"+thread.forumid+"/tid-"+thread.threadid; 4895 }; 4896 4897 $scope.commentsUrl=function(thread){ 4898 return $scope.forumUrl+"/fid-"+thread.forumid+"/tid-"+thread.threadid+"#comments"; 4899 }; 4900 4901 $scope.forumIcon = function (thread) { 4902 return elasticCallService.getForumIcon(thread); 4903 }; 4904 4905 4906 4907 4908 4909 } 4910})();; 4911 4912/** 4913 * Created by ezukrowska on 21-Dec-16. 4914 */ 4915 4916(function () { 4917 'use strict'; 4918 4919 angular 4920 .module('beProximus.es') 4921 .service('elasticSearchAnalysisService', elasticSearchAnalysisService); 4922 4923 elasticSearchAnalysisService.$inject = ['AnalyticsService']; 4924 4925 function elasticSearchAnalysisService(AnalyticsService) { 4926 4927 var service = { 4928 searchAnalysisOnSearchLoad: searchAnalysisOnSearchLoad, 4929 searchAnalysisForFilter: searchAnalysisForFilter, 4930 searchAnalysisOnSimpleLinkClick: searchAnalysisOnSimpleLinkClick, 4931 searchAnalysisForPaging: searchAnalysisForPaging, 4932 searchAnalysisForSpecialDisplay: searchAnalysisForSpecialDisplay, 4933 searchAnalysisForNextPageClicked: searchAnalysisForNextPageClicked, 4934 searchAnalysisForPreviousPageClicked: searchAnalysisForPreviousPageClicked, 4935 searchAnalysisForOtherSegmentResults: searchAnalysisForOtherSegmentResults, 4936 searchAnalysisForDeviceClicked: searchAnalysisForDeviceClicked, 4937 searchAnalysisForBannerClicked: searchAnalysisForBannerClicked 4938 4939 }; 4940 return service; 4941 4942 function searchAnalysisOnSearchLoad(query, resultsCount) { 4943 var utag_data = {}; 4944 utag_data.event ='search'; 4945 utag_data.event_type ='result'; 4946 utag_data.event_location = 'searchresult'; 4947 utag_data.event_searchterm = query; 4948 utag_data.event_searchresults = resultsCount; 4949 logAndSendEvent(utag_data); 4950 } 4951 4952 function searchAnalysisForFilter(query, resultsCount, filter) { 4953 var utag_data = {}; 4954 utag_data.event ='filter'; 4955 utag_data.event_location = 'searchresult'; 4956 utag_data.event_searchterm = query; 4957 utag_data.event_searchresults = resultsCount; 4958 utag_data.event_searchfilter = filter; 4959 logAndSendEvent(utag_data); 4960 } 4961 4962 function searchAnalysisOnSimpleLinkClick(result, resultType) { 4963 var utag_data = buildUtagForClickingSearchResults(); 4964 if(result._source.gsa_promoted_page){ 4965 utag_data.event_detail = "recommended :"+result._source['og:title']; 4966 } 4967 else{ 4968 utag_data.event_detail = 'segment_'+result._source.facetsegment +" :"+result._source['og:title']; 4969 } 4970 utag_data.event_linktype = resultType; 4971 utag_data.event_zone = result._source.facetzone; 4972 logAndSendEvent(utag_data); 4973 } 4974 4975 function searchAnalysisForPaging(page){ 4976 var utag_data = buildUtagForClickingSearchResults(); 4977 utag_data.event_detail = 'navigate: ' + page; 4978 logAndSendEvent(utag_data); 4979 } 4980
4981 function searchAnalysisForNextPageClicked(){ 4982 var utag_data = buildUtagForClickingSearchResults(); 4983 utag_data.event_detail = 'navigate: next'; 4984 logAndSendEvent(utag_data); 4985 } 4986 4987 function searchAnalysisForPreviousPageClicked(){ 4988 var utag_data = buildUtagForClickingSearchResults(); 4989 utag_data.event_detail = 'navigate: previous'; 4990 logAndSendEvent(utag_data); 4991 } 4992 4993 function searchAnalysisForSpecialDisplay(productName){ 4994 var utag_data = buildUtagForClickingSearchResults(); 4995 utag_data.event_detail = 'products: ' + productName; 4996 logAndSendEvent(utag_data); 4997 } 4998 4999 function searchAnalysisForOtherSegmentResults(segment){ 5000 var utag_data = buildUtagForClickingSearchResults(); 5001 utag_data.event_detail = "segment_"+segment; 5002 utag_data.event_linktype = "link"; 5003 logAndSendEvent(utag_data); 5004 } 5005 5006 function buildUtagForClickingSearchResults(){ 5007 var utag_data = {}; 5008 utag_data.event = 'click'; 5009 utag_data.event_location = 'searchresults'; 5010 return utag_data; 5011 } 5012 5013 function searchAnalysisForDeviceClicked(product, zone){ 5014 var utag_data = buildUtagForClickingSearchResults(); 5015 utag_data.event_detail = 'products: ' + product.deviceModel; 5016 utag_data.event_zone = zone; 5017 utag_data.event_linktype = "product"; 5018 logAndSendEvent(utag_data); 5019 } 5020 5021 function searchAnalysisForBannerClicked(banner){ 5022 var utag_data = buildUtagForClickingSearchResults(); 5023 utag_data.event_detail = "banner: "+ banner.link; 5024 utag_data.event_linktype = "link"; 5025 logAndSendEvent(utag_data); 5026 } 5027 5028 function logAndSendEvent(utag_data){ 5029 $fn.console.log(utag_data); 5030 return AnalyticsService.reportEvent(utag_data); 5031 } 5032 5033 5034 } 5035 5036 5037})(); 5038 5039 5040; 5041
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.