1//Register Spark as a namespace if has not been defined before 2if (typeof (PC) === 'undefined') { 3 PC = []; 4}; 5 6//Add Search to the Spark namespace 7PC.TypeAhead = PC.TypeAhead || {}; 8PC.WebService = PC.WebService || {}; 9PC.Cottage = PC.Cottage || {}; 10 11/********************************** 12 * Dependencies: JQuery 13 * : EasyAutoComplete v1.3.3 + 14 * 15 * Search functionality 16 * 17 **********************************/ 18PC.TypeAhead = function () { 19 var self = this; 20 21 22 /********************** 23 * @description Initalises the search lookahead 24 * @param {string} lookaheadID the lookaheadID 25 * @param {string} hidRegionID the regionID 26 * 27 ****************/ 28 self.SetupLookahead = function (lookaheadID, hidRegionID) { 29 30 31 //get auto complete options from webservice 32 var autoCompleteOptions = { 33 url: function (query) { 34 if (query !== "") { 35 return "/webservice/searchService.svc/lookAhead?query=" + query 36 } 37 }, 38 ajaxSettings: { 39 method: "GET", 40 }, 41 list: { 42 //SR: 08/02/2017 - Remove hover over on typeahead 43 //onMouseOverEvent: function () { 44 // //Set the mouse over destination into the text box / hidden field 45 // var destination = $(lookaheadID).getSelectedItemData(); 46 // searchCriteria.destinationId(destination.DestinationID); 47 // $(lookaheadID).val(destination.Destination) 48 //}, 49 onChooseEvent: function () { 50 //On choose event (enter / mouse click) set the destinationID / hidden field 51 var destination = $(lookaheadID).getSelectedItemData(); 52 $(hidRegionID).val(destination.DestinationID); 53 $(".ui-menu-item").hide(); 54 }, 55 onClickEvent: function () { 56 //On choose event (enter / mouse click) set the destinationID / hidden field 57 var destination = $(lookaheadID).getSelectedItemData(); 58 $(hidRegionID).val(destination.DestinationID); 59 $(".ui-menu-item").hide(); 60 } 61 , maxNumberOfElements: 10 62 , match: { 63 enabled: false 64 } 65 }, 66 getValue: "Destination", 67 requestDelay: 750, 68 theme: "square" 69 }; 70 71 $(lookaheadID).easyAutocomplete(autoCompleteOptions) 72 //On blur event get the selectedItem ID and place into the search criteria 73 .blur(function () { 74 var destination = $(lookaheadID).getSelectedItemData(); 75 $(hidRegionID).val(destination.DestinationID); 76 $(".ui-menu-item").hide(); 77 } 78 ); 79 80 SparkBase.General.Console.Log("PC.TypeAhead.SetupLookahead()"); 81 }; 82 83 return { 84 SetupLookahead: self.SetupLookahead, //Configure the look ahead 85 } 86}(); 87 88 89/** 90* @description Common interface to webservice features 91*/ 92PC.WebService = function () { 93 var self = this; 94 95 /********************** 96 * @description Submit a newsletter subscription to Server & Liquid Mail 97 * @param {string} email email address 98 * @param {string} forename comments 99 * @param {boolean} surname is newsletter checked 100 * @param {boolean} subscribeMarketing is other marketing checked 101 * @param {function} callbackFunction the call back function 102 */ 103 self.SubmitNewsletter = function (email, forename, surname, subscribeMarketing, iPAddress, callbackFunction) { 104 SparkBase.General.Console.Log('PC.WebService.SubmitNewsletter()'); 105 $.getJSON('/webservice/general.svc/subscribeNewsletter?emailAddress=' + email + '&forename=' + forename + '&surname=' + surname + '&subscribeMarketing=' + subscribeMarketing + '&iPAddress=' + iPAddress) 106 .success(function (data) { 107 SparkBase.General.Console.Log("Newsletter submitted"); 108 callbackFunction(data); 109 } 110 ); 111 112 }; 113 114 /** 115 * @description Submit a feedback to Server & Liquid Mail 116 * @param {string} captureMethodID where the information has been captured from 117 * @param {string} email email address 118 * @param {string} comment comments 119 * @param {boolean} chkNewsLetter is newsletter checked 120 * @param {boolean}
120 chkOtherMarketing is other marketing checked 121 * @param {function} callbackFunction the call back function 122 */ 123 self.SubmitFeedback = function (captureMethodID, email, comment, chkNewsLetter, chkOtherMarketing, callbackFunction) { 124 SparkBase.General.Console.Log('PC.WebService.SubmitFeedback()'); 125 //AS of 17/11/2016 - We need to include the capture method as we have extended for contact requests 126 $.getJSON('/webservice/general.svc/SubmitFeedback?captureMethodID=' + captureMethodID + '&emailAddress=' + email + '&comments=' + comment + '&newsletter=' + chkNewsLetter + '&allowMarketing=' + chkOtherMarketing) 127 .success(function (data) { 128 SparkBase.General.Console.Log("Feedback submitted"); 129 callbackFunction(data); 130 } 131 ); 132 133 }; 134 135 136 /** 137* @description Share a compare list with a friend 138* @param {string} nameTo where the information has been captured from 139* @param {string} emailTo address 140* @param {string} comment comments 141* @param {function} callbackFunction the call back function 142*/ 143 self.ShareCompareList = function (nameTo, emailTo, comment, callbackFunction) { 144 SparkBase.General.Console.Log('PC.WebService.ShareCompareList()'); 145 $.getJSON('/webservice/general.svc/ShareCompareList?nameTo=' + nameTo + '&emailAddress=' + emailTo + '&comments=' + comment) 146 .success(function (data) { 147 SparkBase.General.Console.Log("Compare List shared"); 148 callbackFunction(data); 149 } 150 ); 151 152 }; 153 154 /** 155 * @description Do a search for cottages 156 * @param {string} searchCriteraString search string 157 * @param {function} callBackFunction success function 158 * @param {function} errFunction function to handle any errors 159 */ 160 self.Search = function (searchCriteraString, callBackFunction, errFunction) { 161 SparkBase.General.Console.Log("Calling Search: " + searchCriteraString); 162 $.getJSON("/webservice/searchservice.svc/Search?" + searchCriteraString + "&cacheBuster=" + Math.random()) 163 .done(function (data) { 164 SparkBase.General.Console.Log("Cottage Search: Success"); 165 if (typeof callBackFunction === 'function') { 166 callBackFunction(data); 167 } 168 }) 169 .fail(function (err) { 170 SparkBase.General.Console.Log("Cottage Search: Failed"); 171 if (typeof errFunction === 'function') { 172 errFunction(err); 173 } 174 }); 175 }; 176 177 178 /** 179 * @description Do a search for cottages with an extended date ranage 180 * @param {string} searchCriteraString search string 181 * @param {function} callBackFunction success function 182 * @param {function} errFunction function to handle any errors 183 */ 184 self.GetExtendedResults = function (searchCriteraString, callBackFunction, errFunction) { 185 SparkBase.General.Console.Log("Calling GetExtendedResults: " + searchCriteraString); 186 $.getJSON("/webservice/searchservice.svc/GetExtendedResults?" + searchCriteraString + "&cacheBuster=" + Math.random()) 187 .done(function (data) { 188 SparkBase.General.Console.Log("Cottage Search Extended Results: Success"); 189 if (typeof callBackFunction === 'function') { 190 callBackFunction(data); 191 } 192 }) 193 .fail(function (err) { 194 SparkBase.General.Console.Log("Cottage Search: Failed"); 195 if (typeof errFunction === 'function') { 196 errFunction(err); 197 } 198 }); 199 }; 200 201 /** 202 * @description Do a search for special offers 203 * @param {string} searchCriteraString search string 204 * @param {number} lastMinuteOfferPeriodId the offer period id 205 * @param {function} callBackFunction success function 206 * @param {function} errFunction function to handle any errors 207 */ 208 self.SpecialOffers = function (searchCriteraString, lastMinuteOfferPeriodId, callBackFunction, errFunction) { 209 210 SparkBase.General.Console.Log("Calling Special Offers: /webservice/searchservice.svc/SpecialOffers?" + searchCriteraString + "&lastMinuteOfferPeriodId=" + lastMinuteOfferPeriodId + "&cacheBuster=" + Math.random()); 211 $.getJSON("/webservice/searchservice.svc/SpecialOffers?" + searchCriteraString + "&lastMinuteOfferPeriodId=" + lastMinuteOfferPeriodId + "&cacheBuster=" + Math.random()) 212 .done(function (data) { 213 SparkBase.General.Console.Log("Cottage Search: Success"); 214 if (typeof callBackFunction === 'function') { 215 callBackFunction(data); 216 } 217 }) 218 .fail(function (err) { 219 SparkBase.General.Console.Log("Cottage Search: Failed"); 220 if (typeof errFunction === 'function') { 221 errFunction(err); 222 } 223 }); 224 }; 225 226 /** 227 * @description Do a search for special offers 228 * @param {string} searchCriteraString search string 229 * @param {function} callBackFunction success function 230 * @param {function} errFunction function to handle any errors 231 */ 232 self.LateDeals = function (searchCriteraString, callBackFunction, errFunction) { 233 234 SparkBase.General.Console.Log("Calling Special Offers: /webservice/searchservice.svc/LateDeals?" + searchCriteraString + "&cacheBuster=" + Math.random()); 235 $.getJSON("/webservice/searchservice.svc/LateDeals?" + searchCriteraString + "&cacheBuster=" + Math.random()) 236 .done(function (data) { 237 SparkBase.General.Console.Log("Cottage Search: Success"); 238 if (typeof callBackFunction === 'function') { 239 callBackFunction(data); 240 } 241 }) 242 .fail(function (err) { 243 SparkBase.General.Console.Log("Cottage Search: Failed"); 244 if (typeof errFunction === 'function') { 245 errFunction(err); 246 } 247 }); 248 }; 249 250 /** 251 * @description toggle the cottageID favourite status in the comparelist 252 * @param {number} cottageID cottageid 253 * @param {boolean} include to include to favourites 254 * @param {function} callBackFunction - function to carry out on success 255 * @param {function} errFunction - function to carry out on an error 256 */ 257 self.ToggleFavourites = function (cottageID, include, callBackFunction, errFunction) { 258 var includeToString = include ? 'True' : 'False'; 259 var url = '/webservice/cottageService.svc/AddToShortlist?cottageId=' + cottageID + '&include=' + includeToString; 260 $.get(url) 261 .done(function () { 262 if (typeof callBackFunction === 'function') { 263 callBackFunction(); 264 }; 265 }) 266 .fail(function (err) { 267 //Log error! 268 var txt; 269 include ? txt = 'Add' : txt = 'Remove'; 270 SparkBase.General.Console.Log("Could not " + txt + " Cottage from favourites, Cottage:" + cottageID); 271 272 if (typeof errFunction === 'function') { 273 errFunction(err); 274 } 275 }); 276 }; 277 278 279 self.PushFeatures = function () { 280 if (typeof PC.PageNameID !== 'undefined') { 281 282 $.getJSON("/webservice/general.svc/LastSearchQuery?PageNameID=" + PC.PageNameID + "&Features=" + escape(SparkBase.General.URL.GetHashValue("selectedFeatures", ""))) 283 .done(function (data) { 284 SparkBase.General.Console.Log("Cottage Search: Success"); 285 if (typeof callBackFunction === 'function') { 286 callBackFunction(data); 287 } 288 }); 289 } 290 }; 291 292 293 /** 294 * @description Do a search for special offers 295 * @param {string} searchCriteraString search string 296 * @param {number}
296 vipOfferId the offer period id 297 * @param {function} callBackFunction success function 298 * @param {function} errFunction function to handle any errors 299 */ 300 self.VIPOffer = function (searchCriteraString, vipOfferId, callBackFunction, errFunction) { 301 302 SparkBase.General.Console.Log("Calling Special Offers: /webservice/searchservice.svc/VIPOffers?" + searchCriteraString + "&VIPOfferId=" + vipOfferId + "&cacheBuster=" + Math.random()); 303 $.getJSON("/webservice/searchservice.svc/VIPOffers?" + searchCriteraString + "&vipOfferId=" + vipOfferId + "&cacheBuster=" + Math.random()) 304 .done(function (data) { 305 SparkBase.General.Console.Log("Cottage Search: Success"); 306 if (typeof callBackFunction === 'function') { 307 callBackFunction(data); 308 } 309 }) 310 .fail(function (err) { 311 SparkBase.General.Console.Log("Cottage Search: Failed"); 312 if (typeof errFunction === 'function') { 313 errFunction(err); 314 } 315 }); 316 }; 317 318 self.MyFavourites = function MyFavourites(queryString, callBackFunction, errFunction) { 319 SparkBase.General.Console.Log("Calling /webservice/searchService.svc/ListCompareList?queryString=" + queryString); 320 321 $.getJSON("/webservice/searchService.svc/ListCompareList?queryString=" + queryString + "&cacheBuster=" + Math.random()) 322 .done(function (data) { 323 SparkBase.General.Console.Log("Cottage Search: Success"); 324 if (typeof callBackFunction === 'function') { 325 callBackFunction(data); 326 } 327 }) 328 .fail(function (err) { 329 SparkBase.General.Console.Log("Cottage Search: Failed"); 330 if (typeof errFunction === 'function') { 331 errFunction(err); 332 } 333 }); 334 }; 335 336 return { 337 SubmitNewsletter: self.SubmitNewsletter, /* Submit the newsletter to WebService */ 338 SubmitFeedback: self.SubmitFeedback, /* Submit the newsletter to WebService */ 339 ShareCompareList: self.ShareCompareList, /* Share Compare List via WebService */ 340 Search: self.Search, /* General purpose search */ 341 SpecialOffers: self.SpecialOffers, 342 LateDeals: self.LateDeals, 343 ToggleFavourites: self.ToggleFavourites, /* Toggle favourites webservice call */ 344 PushFeatures: self.PushFeatures, 345 GetExtendedResults: self.GetExtendedResults, /** get extended results **/ 346 VIPOffer: self.VIPOffer, /* Get the VIP Club webservice */ 347 MyFavourites: self.MyFavourites /* Get the my favourites webservice */ 348 }; 349}(); 350 351 352/** 353* @description Class for holding site wide cottage functionality 354*/ 355PC.Cottage = PC.Cottage || {}; 356PC.Cottage.Favourite = (function Favourite() { 357 var Me = this; 358 Me.listener = undefined; 359 360 /****** 361 * @description Notify Premier Cottages that a cottage has been added to favourites 362 * @param {object} hyperLinkElement the hyperlink 363 */ 364 Me.AddCottageToFavourites = function (hyperLinkElement) { 365 var cottageID = $(hyperLinkElement).data('cottageid'); 366 367 Me.SetAddedToFavourite(hyperLinkElement); 368 369 PC.WebService.ToggleFavourites(cottageID, true, 370 function Success() { 371 372 var cottageID = $(hyperLinkElement).data('cottageid'); 373 var cottageGroupID = $(hyperLinkElement).data('cottagegroupid'); 374 var cottagegroup = $(hyperLinkElement).data('cottagegroupname'); 375 376 /* track event in google */ 377 if ((typeof cottageGroupID !== 'undefined') && (typeof cottageGroupID !== 'undefined')) { 378 SparkBase.Google.Track.CompareList(cottageGroupID, cottagegroup, cottageID); 379 }; 380 }, 381 function Error() { 382 Me.RemoveFromFavourite(hyperLinkElement); 383 }); 384 }; 385 386 387 Me.SetAddedToFavourite = function (hyperLinkElement) { 388 389 var text = "Remove from favourites"; 390 391 $('[data-buttontype="favourite"]').each(function () { 392 var $element = $(this); 393 394 if ($element.hasClass('active') == false) { 395 396 $element.addClass('active'); 397 $element.find('span').text(text); 398 $element.attr('title', text); 399 } 400 }); 401 402 var $icon = $('[data-icontype="favouriteMobileIcon"]'); 403 $icon.removeClass("fa-heart-o"); 404 $icon.addClass("fa-heart"); 405 } 406 407 Me.RemoveFromFavourite = function (hyperLinkElement) { 408 409 var text = "Add to favourites"; 410 411 $('[data-buttontype="favourite"]').each(function () { 412 var $element = $(this); 413 414 if ($element.hasClass('active') == true) { 415 $element.removeClass('active'); 416 417 $element.find('span').text(text); 418 $element.attr('title', text); 419 } 420 }); 421 422 423 var $icon = $('[data-icontype="favouriteMobileIcon"]'); 424 $icon.removeClass("fa-heart"); 425 $icon.addClass("fa-heart-o"); 426 } 427 428 429 /****** 430 * @description Notify Premier Cottages that a cottage has been removed from favourites 431 * @param {string} hyperLinkElement the hyperlink 432 */ 433 Me.RemoveCottageFromFavourites = function (hyperLinkElement) { 434 var cottageID = $(hyperLinkElement).data('cottageid'); 435 436 437 Me.RemoveFromFavourite(hyperLinkElement); 438 439 PC.WebService.ToggleFavourites(cottageID, false, function Success() { 440 }, function Error() { 441 Me.SetAddedToFavourite(hyperLinkElement); 442 }); 443 }; 444 445 446 /****** 447 * @description Toggles the cottage to and from a fravouite 448 * @param {object} hyperLinkElement hyperlink 449 */ 450 Me.ToggleFavourite = function (hyperLinkElement) { 451 452 if ($(hyperLinkElement).hasClass('active')) { 453 Me.RemoveCottageFromFavourites(hyperLinkElement); 454 } else { 455 Me.AddCottageToFavourites(hyperLinkElement); 456 }; 457 }; 458 459 Me.ToggleFavouriteCottagePageMobile = function (hyperLinkElement) { 460 461 /* classes will be toggled */ 462 Me.ToggleFavourite(hyperLinkElement); 463 464 /* mobile heart */ 465 } 466 467 468 469 /****** 470 * @description called when a cottageID is added or removed from favourites 471 * @param {function} listener function(cottageID, event) 472 */ 473 Me.Addlistener = function (listener) { 474 Me.listener = listener; 475 }; 476 477 return { 478 ToggleFavourite: Me.ToggleFavourite, 479 Addlistener: Me.Addlistener, 480 ToggleFavouriteCottagePageMobile: ToggleFavouriteCottagePageMobile 481 }; 482})(); 483 484 485/** 486* @description Class for holding search citeria 487*/ 488PC.Search = function () { 489 var self = this; 490 491 /** 492 * @description Search Criteria Class 493 */ 494 self.SearchCriteria = function () { 495 /*** 496 * @description find the data-searchFields and get their values & return as an url 497 * @param {object} searchCriteria the search criteria being passed in 498 * @returns {string}
498 the search criteria as a stirng 499 */ 500 function GetSearchString(searchCriteria) { 501 var outStr = ""; 502 503 /** If we have had the search criteria passed in then use that object else generate another **/ 504 searchCriteria = searchCriteria || GetSearchCriteria(); 505 506 outStr = SearchCriteriaToURL(searchCriteria); 507 508 /** return the search citeria **/ 509 return outStr; 510 }; 511 512 /*** 513 * @description Convert the search Criteria to a url string 514 * @param {object} searchCriteria searchCriteria 515 * @return {string} search URL 516 */ 517 function SearchCriteriaToURL(searchCriteria) { 518 var outStr = ''; 519 520 if (typeof searchCriteria !== 'undefined') { 521 /** loop though the search criteria and get the values if they are declared if not leave as the default - ie blank or 0 **/ 522 for (prop in searchCriteria) { 523 524 if (prop == 'guests' || prop == 'bedrooms') { 525 var val = searchCriteria[prop]; 526 val.replace(prop + "-", ""); 527 528 if (val.toLowerCase() == 'any') { 529 val = ''; 530 } 531 outStr += "&" + prop + "=" + val; 532 533 } else if (prop == 'selectedNights') { 534 var val = searchCriteria[prop]; 535 val = val.replace("date-nights-", ""); 536 outStr += "&" + prop + "=" + val; 537 538 } else if (prop == 'datesFlexible') { 539 var val = searchCriteria[prop]; 540 541 if (val.toLowerCase() == 'true') { 542 outStr += "&" + prop + "=" + 1; 543 } else { 544 outStr += "&" + prop + "=" + 0; 545 } 546 } 547 548 else { 549 outStr += "&" + prop + "=" + searchCriteria[prop]; 550 } 551 552 553 }; 554 }; 555 556 /** remove the initial &... **/ 557 outStr = outStr.substr(1, outStr.length - 1); 558 559 return outStr; 560 }; 561 562 /** 563 * @description returns a search 564 * @returns {string} the search criteria 565 */ 566 function GetSearchCriteria() { 567 var searchCriteria = SearchCriteria(); 568 569 for (prop in searchCriteria) { 570 if (prop.toLowerCase() == 'selectedFeatures'.toLowerCase()) { 571 searchCriteria[prop] = SparkBase.General.URL.GetHashValue('selectedFeatures', ''); 572 } else { 573 var val = $('[data-searchfield="' + prop + '"]').val(); 574 575 if (typeof val !== 'undefined') { 576 577 578 val = val.replace(prop + "-", ''); 579 580 if (val.toLowerCase() == "any") { 581 val = 0; 582 } 583 584 searchCriteria[prop] = escape(val); 585 } else { 586 /** if undefined and extend results then set it to be false always **/ 587 if (prop == 'extendResults') { 588 searchCriteria[prop] = 'false'; 589 } 590 }; 591 }; 592 }; 593 594 return searchCriteria; 595 }; 596 597 598 /** 599 * @description get search criteria JSON object 600 * @returns {object} Search criteria object 601 */ 602 function SearchCriteria() { 603 return { 604 destinationId: 0, 605 destination: '', 606 dateFrom: '', 607 selectedNights: 0, 608 datesFlexible: 0, 609 collectionId: 0, 610 guests: 0, 611 bedrooms: 0, 612 selectedFeatures: '', 613 extendResults: 'false' 614 }; 615 }; 616 617 /**
618 * @description set the search fields from the URL 619 */ 620 function SetFromURL() { 621 var searchCriteria = SparkBase.General.URL.GetHashAsObject(); 622 623 for (var i = 0, len = searchCriteria.length; i < len; i++) { 624 if (searchCriteria[i].name.toLowerCase() == 'destination'.toLowerCase()) { 625 var val = unescape(searchCriteria[i].value) 626 $('[data-searchfield="' + searchCriteria[i].name + '"]').val(val); 627 } else { 628 $('[data-searchfield="' + searchCriteria[i].name + '"]').val(searchCriteria[i].value); 629 } 630 }; 631 } 632 633 634 return { 635 GetSearchCriteria: GetSearchCriteria, 636 GetSearchString: GetSearchString, 637 SearchCriteria: SearchCriteria, 638 SearchCriteriaToURL: SearchCriteriaToURL, 639 SetFromURL: SetFromURL 640 } 641 }(); 642 643 644 return { 645 SearchCriteria: self.SearchCriteria 646 } 647}() 648 649 650/** 651* @description Publisher / Subscriber for page objects 652*/ 653PC.Events = (function () { 654 var event = {}; 655 var hop = event.hasOwnProperty; 656 657 return { 658 /** 659 * @description give a list of event 660 * @returns {object} an event 661 */ 662 List: function List() { 663 return event; 664 }, 665 666 /** 667 * @description Allow object to to subscribe to an event 668 * @param {string} topic the topic the function is listening for 669 * @param {function} listener the function to be called when the topic is called 670 * @returns {object} JSON with the delete event 671 */ 672 Subscribe: function Subscribe(topic, listener) { 673 /* Create the topic's object if not yet created */ 674 if (!hop.call(event, topic)) { 675 event[topic] = []; 676 } 677 678 /* Add the listener to queue */ 679 var index = event[topic].push(listener) - 1; 680 681 /* Provide handle back for removal of topic */ 682 return { 683 Remove: function () { 684 delete event[topic][index]; 685 } 686 }; 687 }, 688 689 /** 690 * @description notifi the listeners that there has been an event 691 * @param {string} topic the name of the event being executed 692 * @param {object} info any informtion that is being published 693 */ 694 Publish: function Publish(topic, info) { 695 // SparkBase.General.Console.Log("Event.Publish Called Topic: " + topic + " :Info: " + info); 696 SparkBase.General.Console.Log("Event:" + topic); 697 /* If the topic doesn't exist, or there's no listeners in queue, just leave */ 698 if (!hop.call(event, topic)) return; 699 700 /* Cycle through event queue, fire! */ 701 event[topic].forEach(function (item) { 702 /* Only try to call it if its a function... */ 703 if (typeof item === 'function') { 704 item(info != undefined ? info : {}); 705 } 706 }); 707 } 708 }; 709})();
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.