1'use strict'; 2 3var ngrepeatfinish = false; 4 5var vna = angular.module('vna', ['angulartics', 'angulartics.google.analytics']); 6vna.config(['$locationProvider', function($locationProvider) { 7 //$locationProvider.html5Mode(true); 8 }]); 9vna.config(['$interpolateProvider', function($interpolateProvider) { 10 $interpolateProvider.startSymbol('[['); 11 $interpolateProvider.endSymbol(']]'); 12 }]); 13vna.config(function ($analyticsProvider) { 14 $analyticsProvider.firstPageview(true); /* Records pages that don't use $state or $route */ 15 $analyticsProvider.withAutoBase(true); /* Records full path */ 16 }); 17 18vna.directive('onFinishRender', function ($timeout) { 19 return { 20 restrict: 'A', 21 link: function (scope, element, attr) { 22 //console.log('_last'); 23 if(!ngrepeatfinish){ 24 ngrepeatfinish = true; 25 setTimeout(function(){ 26 if(ngrepeatfinish){ 27 scope.$emit('ngRepeatFinished', element, attr); 28 } 29 }, 1000); 30 setTimeout(function(){ 31 if(ngrepeatfinish){ 32 ngrepeatfinish = false; 33 scope.$emit('ngRepeatFinished', element, attr); 34 } 35 }, 3000); 36 } 37 38 if (scope.$last) { 39 //console.log('last'); 40 setTimeout(function(){ 41 ngrepeatfinish = false; 42 scope.$emit('ngRepeatFinished', element, attr); 43 }); 44 } 45 } 46 }; 47 }) 48 .controller('TravelDirectoryController', TravelDirectoryController); 49 50TravelDirectoryController.$inject = ['$log', '$http', '$scope', '$filter', '$location', '$anchorScroll', '$timeout', '$window']; 51 52function TravelDirectoryController($log, $http, $scope, $filter, $location, $anchorScroll, $timeout, $window){ 53 var vm = this; 54 vm.filter = {sort: '-fields.sort'}; 55 vm.link_venues = link_venues; 56 vm.change_category = change_category; 57 vm.change_location = change_location; 58 vm.change_filter = change_filter; 59 vm.change_type = change_type; 60 vm.change_budget = change_budget; 61 vm.change_date = change_date; 62 vm.change_weekday = change_weekday; 63 vm.check_tags = check_tags; 64 vm.more = more; 65 vm.filtered = []; 66 vm.filtered_map = []; 67 vm.close = close; 68 vm.loading = true; 69 vm.showmap = showmap; 70 vm.list_url = list_url; 71 vm.sort = sort; 72 vm.date = date; 73 var LIMIT = 14; 74 vm.limit = LIMIT; 75 vm.see_and_do_location = see_and_do_location; 76 77 var slider_obj; 78 var slider_restored = false; 79 var map_restored = true; 80 activate(); 81 82 function activate(){ 83 vm.types = [{name: 'All content types', value: null}, 84 {name: 'Venue', value: 'Venue'}, 85 {name: 'Activities & Experiences', value: 'Activities & Experiences'}, 86 {name: 'Events', value: 'Event'}]; 87 88 vm.weekdays = [{name: 'All', value: null}, 89 {name: 'Open on Mondays', value: 1}, 90 {name: 'Open on Tuesdays', value: 2}, 91 {name: 'Open on Wednesdays', value: 3}, 92 {name: 'Open on Thursdays', value: 4}, 93 {name: 'Open on Fridays', value: 5}, 94 {name: 'Open on Weekends', value: -1}]; 95 96 vm.budgets = [{name: 'All', value: null}, 97 {value: 1}, 98 {value: 2}, 99 {value: 3}, 100 {value: 4}, 101 {value: 5}]; 102 103 if(event_calendar){ 104 vm.filter.type = 'Event'; 105 vm.filter.category_id = 'TEhpqPqZc2QoAiw6ksGgW'; 106 vm.event_calendar = true; 107 } 108 109 if(!restore_state()) 110 init_filter(); 111 112 $http({ 113 method: 'GET', 114 url: '/travel-directory/api/data/' 115 }).then(function success(response){ 116 //console.log(response.data); 117 if(event_calendar == null){ 118 // venue detail page 119 vm.state_map = true; 120 vm.venues = venues; 121 vm.lists = []; 122 change_filter(true); 123 staticMap(); 124 125 var search = location_search(window.location.search); 126 if(search.loc) 127 vm.filter.location_id = search.loc; 128 if(search.subl) 129 vm.filter.subLocation_id = search.subl; 130 }else{ 131 vm.venues = response.data.venues; 132 vm.lists = response.data.lists; 133 } 134 135 vm.categories = response.data.categories; 136 if(event_calendar){ 137 // remove categories except events 138 var ids = []; 139 angular.forEach(vm.categories, function(v, i){ 140 if(v.id != vm.filter.category_id) 141 ids.unshift(i); 142 }); 143 angular.forEach(ids, function(i){ 144 vm.categories.splice(i, 1); 145 }); 146 } 147 if(vm.filter.category_id || vm.filter.subCategory_id) 148 angular.forEach(vm.categories, function(v){ 149 if(v.id == vm.filter.category_id) 150 $('#category_name').val('All ' + v.name); 151 angular.forEach(v.sub, function(sub){ 152 if(sub.id == vm.filter.subCategory_id){ 153 $('#category_name').val(sub.name); 154 vm.filter.category_id = v.id; 155 } 156 }); 157 }); 158 else 159 $('#category_name').val('All categories'); 160 161 vm.locations = response.data.locations; 162 if(vm.filter.location_id || vm.filter.subLocation_id){ 163 angular.forEach(vm.locations, function(v){ 164 if(v.id == vm.filter.location_id) 165 $('#location_name').attr('value', 'All ' + v.name); 166 angular.forEach(v.sub, function(sub){ 167 if(sub.id == vm.filter.subLocation_id){ 168 $('#location_name').attr('value', sub.name); 169 vm.filter.location_id = v.id; 170 } 171 }); 172 }); 173 } 174 else{ 175 $('#location_name').val('All locations'); 176 } 177 178 change_filter(true); 179 //vm.loading = true; 180 181 if(event_calendar != null && !$location.search()['_']) 182 $location.search('_', '_').replace(); // as a flag to restore 183 }); 184 185 $scope.$on('ngRepeatFinished', function(e, element, attrs) { 186 if(attrs.onFinishRender == 'venues') 187 ngRepeatFinished(); 188 else if(attrs.onFinishRender == 'category'){ 189 init_category(); 190 $('#loc' + vm.filter.location_id).click(); 191 $('#cat' + vm.filter.category_id).click(); 192 var s = $('#sort_input').val(); 193 if(s) 194 $('#sort' + s.split(' ')[0]).addClass('skin_current'); 195 }else if(attrs.onFinishRender == 'lists'){ 196 if(slider_obj){ 197 slider_obj.destroySlider(); 198 $('.carousel_quarter_slides .bx-controls').remove(); 199 } 200 slider_obj = commonSlider2();
201 if(!slider_restored){ 202 console.log('slider_restored!') 203 var s = slider(); 204 if(s) 205 slider_obj.goToSlide(s); 206 slider_restored = true; 207 } 208 _lazyLoadBgImage($('.carousel_quarter_slides .item_image')); 209 }else if(attrs.onFinishRender == 'etc'){ 210 if(typeof(init_etc) !== 'undefined') 211 init_etc(); 212 } 213 }); 214 215 window.onbeforeunload = function(e){ 216 console.log('onbeforeunload'); 217 scroll(window.pageYOffset); 218 if(slider_obj) 219 slider(slider_obj.getCurrentSlide()); 220 }; 221 } 222 223 function restore_state(){ 224 var search = $location.search(); 225 //console.log(search); 226 if($.isEmptyObject(search)) 227 return false; 228 229 if(search['_']) 230 vm.restore_scroll = scroll(); 231 232 if(search.map) 233 map_restored = false; 234 235 if(search.w) 236 vm.filter.keyword = search.w; 237 238 if(search.cat) 239 vm.filter.category_id = search.cat; 240 241 if(search.sub) 242 vm.filter.subCategory_id = search.sub; 243 244 if(search.loc) 245 vm.filter.location_id = search.loc; 246 247 if(search.subl) 248 vm.filter.subLocation_id = search.subl; 249 250 if(search.type) 251 vm.filter.type = search.type; 252 253 if(search.budget) 254 vm.filter.budget = search.budget; 255 256 if(search.weekday) 257 vm.filter.weekday = parseInt(search.weekday); 258 259 if(search.start) 260 vm.filter.date_start = search.start; 261 262 if(search.end) 263 vm.filter.date_end = search.end; 264 265 if(search.tags){ 266 if(typeof(search.tags) == 'string') 267 search.tags = [search.tags]; 268 vm.filter.tags = search.tags; 269 } 270 271 if(search.limit) 272 vm.limit = parseInt(search.limit); 273 274 if(search.sort){ 275 $('#sort_input').val(search.sort); 276 sort(search.sort); 277 } 278 //console.log('restore_state'); 279 return true; 280 } 281 282 function init_filter(){ 283 // based on params 284 var search = location_search(window.location.search); 285 if(search.cat) 286 vm.filter.category_id = search.cat; 287 if(search.sub) 288 vm.filter.subCategory_id = search.sub; 289 } 290 291 function location_search(search){ 292 var params = {}; 293 search 294 .replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str,key,value) { 295 params[key] = value; 296 }); 297 return params; 298 } 299 300 function more(){ 301 vm.limit += 12; 302 $location.search('limit', vm.limit).replace(); 303 } 304 305 function link_venues(url, $event){ 306 if($event.target.tagName == 'A') 307 return; 308 linkTo(url); 309 } 310 311 function change_category(){ 312 if(event_calendar == false && vm.filter.category_id == 'TEhpqPqZc2QoAiw6ksGgW'){ 313 move_to_calendar({'cat': vm.filter.category_id , 314 'sub': vm.filter.subCategory_id}); 315 return; 316 } 317 318 if(vm.filter.subCategory_id) 319 $location.search('cat', null).replace(); 320 else 321 $location.search('cat', vm.filter.category_id || null).replace(); 322 $location.search('sub', vm.filter.subCategory_id || null).replace(); 323 change_filter(); 324 } 325 326 function change_type(value){ 327 vm.filter.type = value; 328 $location.search('type', vm.filter.type || null).replace(); 329 change_filter(); 330 } 331 332 function change_budget(value){ 333 vm.filter.budget = value; 334 $location.search('budget', vm.filter.budget || null).replace(); 335 change_filter(); 336 } 337 338 function change_date(){ 339 $location.search('start', vm.filter.date_start || null).replace(); 340 $location.search('end', vm.filter.date_end || null).replace(); 341 change_filter(); 342 } 343 344 function change_location(){ 345 if(vm.filter.subLocation_id) 346 $location.search('loc', null).replace(); 347 else 348 $location.search('loc', vm.filter.location_id || null).replace(); 349 $location.search('subl', vm.filter.subLocation_id || null).replace(); 350 change_filter(); 351 } 352 353 function change_weekday(value){ 354 vm.filter.weekday = value; 355 $location.search('weekday', vm.filter.weekday || null).replace(); 356 change_filter(); 357 } 358 359 function showmap(value){ 360 vm.state_map = value; 361 $location.search('map', value ? 1 : '').replace(); 362 } 363 364 function update_for_nextprev(){ 365 var d = {venues: [], 366 list: []}; 367 for(var i in vm.filtered) 368 d.venues.push(vm.filtered[i].id); 369 for(i in vm.lists_filtered) 370 for(var j in vm.lists_filtered[i]) 371 d.list.push(vm.lists_filtered[i][j].type + '/' + vm.lists_filtered[i][j].id); 372 //console.log(d); 373 sessionStorage.setItem('search', JSON.stringify(d)); 374 } 375 376 function change_filter(init){ 377 //console.log('change_filter'); 378 if(!vm.venues) 379 return; 380 381 //vm.loading = true; 382 if(vm.change_filter_timeout) 383 $timeout.cancel(vm.change_filter_timeout); 384 385 386 if(event_calendar != null) 387 $location.search('_', '__').replace(); // as a flag to show lists 388 vm.change_filter_timeout = $timeout(_change_filter, 500); 389 390 391 function _change_filter(){ 392 $location.search('w', vm.filter.keyword || null).replace(); 393 $location.search('tags', vm.filter.tags || null).replace(); 394 if(!init){ 395 vm.limit = LIMIT; 396 $location.search('limit', null); 397 } 398 399 if(vm.filter.date_start) 400 vm.filter.date_start_unix = moment(vm.filter.date_start, 'D MMMM, YYYY').unix(); 401 else 402 vm.filter.date_start_unix = null; 403 if(vm.filter.date_end) 404 vm.filter.date_end_unix = moment(vm.filter.date_end, 'D MMMM, YYYY').unix(); 405 else 406 vm.filter.date_end_unix = null; 407 408 var prev = vm.filtered.slice(0, vm.limit); 409 vm.filtered = $filter('orderBy')( 410 $filter('filter')(vm.venues, filter_venues), vm.filter.sort); 411 412 if($location.search()['_'] == '__') 413 vm.lists_filtered = lists_groupby($filter('filter')(vm.lists, filter_lists)); 414 vm.filtered_map = $filter('filter')(vm.filtered, filter_map); 415 416 if(event_calendar != null) 417 // search page 418 update_for_nextprev(); 419 420 change_filter_map(); 421 $markerData = []; 422 angular.forEach(vm.filtered_map, function(v){ 423 v.fields.id = v.id; 424 $markerData.push(v.fields); 425 }); 426 if(vm.state_map){ 427 // check map data changed 428 var current = JSON.stringify(vm.filtered_map); 429 if(vm.prev_map_data != current){ 430 $('.openmaps_lists .item_lists_inner').empty(); 431 floatMap(true); 432 vm.prev_map_data = current; 433 } 434 } 435 if(!map_restored){ 436 map_restored = true; 437 setTimeout(function(){ 438 $('.js_trigger_floatmap').click(); 439 }, 0); 440 } 441 442 vm.change_filter_timeout = null; 443 if(!list_changed()){ 444 //console.log('not list_changed'); 445 vm.loading = false;
446 } 447 448 function list_changed(){ 449 if(prev.length > vm.filtered.length) 450 return true; 451 452 for(var i in prev){ 453 if(prev[i].id != vm.filtered[i].id) 454 return true; 455 } 456 return false; 457 } 458 } 459 } 460 461 function lists_groupby(lists){ 462 var i = 0; 463 var r = []; 464 var l, l_prev = []; 465 var sort = vm.filter.sort; 466 if(sort == 'fields.name') 467 sort = 'fields.title'; 468 469 var ordered = $filter('orderBy')(lists, sort); 470 while((l = ordered.slice(i, i + 4)).length){ 471 r.push(l); 472 i += 4; 473 l_prev = l; 474 } 475 if(l_prev.length <= 0) 476 i += 4; 477 vm.lists_filtered_length = i + l_prev.length - 4; 478 return r; 479 } 480 481 function change_filter_map(){ 482 //vm.loading = true; 483 vm.filtered_map = $filter('filter')(vm.filtered, filter_map); 484 } 485 486 function filter_lists(o){ 487 if(vm.filter.keyword){ 488 if(!filter_lists_keyword(o)) 489 return false; 490 } 491 492 if(!filter_lists_subcategory(o)) 493 return false; 494 495 if(!filter_lists_location(o)) 496 return false; 497 498 if(vm.filter.tags && !filter_tags(o.venues_tags)) 499 return false; 500 return true; 501 } 502 503 function filter_lists_subcategory(v){ 504 if(vm.filter.subCategory_id){ 505 for(var i in v.venues_category_ids){ 506 if(v.venues_category_ids[i] == vm.filter.subCategory_id) 507 return true; 508 } 509 return false; 510 511 }else if(vm.filter.category_id){ 512 for(var i in v.venues_category_ids){ 513 if(v.venues_category_ids[i] == vm.filter.category_id) 514 return true; 515 } 516 return false; 517 } 518 return true; 519 } 520 521 function filter_lists_location(v){ 522 if(vm.filter.subLocation_id){ 523 for(var i in v.venues_location_ids){ 524 if(v.venues_location_ids[i] == vm.filter.subLocation_id) 525 return true; 526 } 527 return false; 528 529 }else if(vm.filter.location_id){ 530 for(var i in v.venues_location_ids){ 531 if(v.venues_location_ids[i] == vm.filter.location_id) 532 return true; 533 } 534 return false; 535 } 536 return true; 537 } 538 539 function filter_lists_keyword(o){ 540 var keyword = vm.filter.keyword.toLowerCase(); 541 if(o.fields.title.toLowerCase().indexOf(keyword) >= 0) 542 return true; 543 544 if(o.fields.tags && o.fields.tags.toLowerCase().indexOf(keyword) >= 0) 545 return true; 546 547 for(var i in o.fields.subCategory){ 548 if(o.fields.subCategory[i].name.toLowerCase().indexOf(keyword) >= 0) 549 return true; 550 } 551 552 for(i in o.venues_subCategory){ 553 if(o.venues_subCategory[i].toLowerCase().indexOf(keyword) >= 0) 554 return true; 555 } 556 557 for(i in o.venues_tags){ 558 if(o.venues_tags[i].toLowerCase().indexOf(keyword) >= 0) 559 return true; 560 } 561 562 return false; 563 } 564 565 function filter_venues(v){ 566 if(vm.filter.keyword){ 567 if(!filter_venues_keyword(v, vm.filter.keyword)) 568 return false; 569 } 570 571 if(vm.filter.subCategory_id){ 572 if(!filter_venues_subcategory(v)) 573 return false; 574 }else if(vm.filter.category_id && !filter_venues_category(v)) 575 return false; 576 577 if(vm.filter.subLocation_id){ 578 if(!filter_venues_sublocation(v)) 579 return false; 580 }else if(vm.filter.location_id && !filter_venues_location(v)) 581 return false; 582 583 if(vm.filter.sort == 'fields.eventStartDate'){ 584 if('Event' != v.fields.detailType) 585 return false; 586 }else if(vm.filter.type && vm.filter.type != v.fields.detailType) 587 return false;
588 589 if(vm.filter.budget && vm.filter.budget != v.fields.budget) 590 return false; 591 592 if(vm.filter.weekday && v.closed && v.closed.indexOf(vm.filter.weekday) >= 0) 593 return false; 594 595 if(vm.filter.tags && !filter_tags(v.fields.tags)) 596 return false; 597 598 if(vm.filter.date_start_unix && ((!v.fields.eventEndDate) || vm.filter.date_start_unix > v.fields.eventEndDate)) 599 return false; 600 601 if(vm.filter.date_end_unix && ((!v.fields.eventStartDate) || vm.filter.date_end_unix < v.fields.eventStartDate)) 602 return false; 603 return true; 604 } 605 606 function filter_venues_category(v){ 607 for(var i in v.fields.category){ 608 if(v.fields.category[i].id == vm.filter.category_id) 609 return true; 610 } 611 return false; 612 } 613 614 function filter_venues_subcategory(v){ 615 for(var i in v.fields.subCategory){ 616 if(v.fields.subCategory[i].id == vm.filter.subCategory_id) 617 return true; 618 } 619 return false; 620 } 621 622 function filter_venues_location(v){ 623 for(var i in v.fields.location){ 624 if(v.fields.location[i].id == vm.filter.location_id) 625 return true; 626 } 627 return false; 628 } 629 630 function filter_venues_sublocation(v){ 631 for(var i in v.fields.subLocation){ 632 if(v.fields.subLocation[i].id == vm.filter.subLocation_id) 633 return true; 634 } 635 return false; 636 } 637 638 function filter_tags(tags){ 639 for(var i in tags){ 640 if(vm.filter.tags.indexOf(tags[i].name || tags[i]) >= 0) 641 return true; 642 } 643 return false; 644 } 645 646 function filter_map(v){ 647 return v.fields.lat && v.fields.lng 648 && v.fields.detailType != 'Event'; 649 } 650 651 function check_tags(tag){ 652 var i = vm.filter.tags.indexOf(tag.id); 653 if(i < 0) 654 vm.filter.tags.push(tag.id); 655 else 656 vm.filter.tags.splice(i, 1); 657 658 change_filter(); 659 } 660 661 function close(){ 662 $('.skin_open').removeClass('skin_open') 663 .find('.item_filter').show(); 664 } 665 666 function ngRepeatFinished(){ 667 //console.log('ngRepeatFinished'); 668 vm.loading = false; 669 $scope.$apply(); 670 671 if(vm.restore_scroll){ 672 $(window).scrollTop(vm.restore_scroll); 673 vm.restore_scroll = false; 674 } 675 676 _lazyLoadBgImage($('.grid_venues_body .js_bg_image')); 677 678 679 $('.grid_venues_lists .item_list.skin_large .cassette_contents .item_body').autoHeight({ 680 column : 2, 681 height : 'height' 682 }); 683 $('.grid_venues_lists .item_list:not(.skin_large) .cassette_contents .item_body').autoHeight({ 684 column : 4, 685 height : 'height' 686 }); 687 } 688 689 function scroll(value){ 690 return storage('scroll', value); 691 } 692 693 function sort(name){ 694 switch(name){ 695 case 'Name (A-Z)': 696 vm.filter.sort = 'fields.name'; 697 break; 698 case 'Popularity': 699 vm.filter.sort = '-pv'; 700 break; 701 case 'Location': 702 vm.filter.sort = ['fields.location[0].sort', 'fields.subLocation[0].sort']; 703 break; 704 case 'Date': 705 vm.filter.sort = 'fields.eventStartDate'; 706 if(event_calendar == false){ 707 move_to_calendar({sort: name}); 708 return false; 709 } 710 break; 711 default: 712 name = null; 713 vm.filter.sort = '-fields.sort'; 714 } 715 716 //console.log(name); 717 $location.search('sort', name).replace(); 718 return true; 719 } 720 721 function slider(value){ 722 return storage('slider', value); 723 } 724 725 function storage(key, value){ 726 var s = sessionStorage[key]; 727 if(s) 728 s = JSON.parse(s); 729 else 730 s = {}; 731 732 if(value != undefined){ 733 s[location.pathname] = value; 734 sessionStorage.setItem(key, JSON.stringify(s)); 735 }else{ 736 return s[location.pathname]; 737 } 738 } 739 740 function date(venue){ 741 if(venue.fields.eventDatePeriod) 742 return venue.fields.eventDatePeriod; 743 if(!(venue.fields.eventStartDate || venue.fields.eventEndDate)) 744 return null; 745 746 var start = ''; 747 var end = ''; 748 if(venue.fields.eventStartDate) 749 start = moment.unix(venue.fields.eventStartDate).format('D MMM'); 750 if(venue.fields.eventEndDate) 751 end = moment.unix(venue.fields.eventEndDate).format('D MMM'); 752 if(start == end) 753 return start; 754 return start + ' - ' + end; 755 } 756 757 function list_url(type){ 758 if(type == 'list') 759 return 'lists-and-stories/list'; 760 if(type == 'story') 761 return 'lists-and-stories/story'; 762 if(type == 'destination guide') 763 return 'destinations/destination'; 764 return 'destinations/area'; 765 } 766 767 function see_and_do_location(location_id, sub_id){ 768 var search = ''; 769 if(location_id) 770 search += 'loc=' + location_id; 771 if(sub_id){ 772 if(search) 773 search += '&'; 774 search += 'subl=' + sub_id; 775 } 776 777 var hash = location.hash; 778 window.history.replaceState(null, null, '?' + search + hash); 779 location.reload(); 780 } 781 782 function move_to_calendar(param){ 783 var _search = $location.search(); 784 angular.forEach(param, function(v, k){ 785 _search[k] = v; 786 }); 787 if(_search.cat != 'TEhpqPqZc2QoAiw6ksGgW'){ 788 delete _search.cat; 789 delete _search.sub; 790 } 791 792 delete _search._; 793 var search = []; 794 angular.forEach($location.search(), function(v, k){ 795 search.push(k + '=' + v); 796 }); 797 location.href = '/event-calendar/#?' + search.join('&'); 798 } 799}
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.