• Jump To … +
    Hotel.js MapView.js ViewModel.js app.js xhrPromise.js
  • ViewModel.js

  • ¶
    var app = app || {};
    
    /**
     * ViewModel
     * @name app.ViewModel
     * @class ViewModel
     * @memberof app
     */
    app.ViewModel = function() {
    
        'use strict';
    
        var self = this;
    
        self.showTicker = ko.observable(false);
        self.hotelTweets = ko.observable('');
        self.timeout = ko.observable(false);
        self.dispMsg = ko.observable('');
        self.hotelList = ko.observableArray();
        self.filterList = ko.observableArray();
        self.filterText = ko.observable('');
        self.ratingsChecked = ko.observableArray();
        self.ratings = ko.observableArray([
            {ratingValue: 5, icon: 'aaaaa', color: 'red'},
            {ratingValue: 4, icon: 'aaaa', color: 'yellow'},
            {ratingValue: 3, icon: 'aaa', color: 'green'},
            {ratingValue: 2, icon: 'aa', color: 'purple'},
        ]);
        self.slideClass = ko.observable('hidden overlay');
        self.showDef = ko.observable(false);
        self.showName = ko.observable(true);
        self.showRating = ko.observable(false);
        self.showList = ko.observable(true);
    
        /**
         * @function app.ViewModel.getRatings
         * @memberof app.ViewModel
         * @returns {array} - List of diamond rating value, icon, and color
         */
        self.getRatings = function() {
            return self.ratings();
        };
    
        /**
         * @function app.ViewModel.nameSort
         * @memberof app.ViewModel
         * @returns {array} - Alphabetically sorted list of hotel names
         */
        self.nameSort = function(left, right) {
            return left.name == right.name ? 0 : (left.name < right.name ? -1 : 1);
        };
    
        /**
         * @function app.ViewModel.getHotels
         * @memberof app.ViewModel
         * @returns {array} - An array of objects for each hotel
         */
        self.getHotels = ko.computed(function() {
  • ¶

    Unwrap the observable to return an array

            var hotelArray = app.model.hotels();
  • ¶

    Sort the array by hotel name

            hotelArray.sort(self.nameSort);
    
            return hotelArray;
        });
    
        /**
         * @function app.ViewModel.getHotelsLength
         * @memberof app.ViewModel
         * @returns {number} - The length of the hotels array
         */
        self.getHotelsLength = ko.computed(function() {
            return app.model.hotels().length;
        });
    
        /**
         * @function app.ViewModel.getKeys
         * @memberof app.ViewModel
         * @returns {object} - Yelp API keys
         */
        self.getKeys = function() {
            return app.model.yelp;
        };
    
        /**
         * Saves the list of hotels and initializes the map.
         *
         * @function app.ViewModel.init
         * @memberof app.ViewModel
         */
        self.init = function() {
            self.hotelList(self.getHotels());
            app.mv.initMap();
        };
    
        /**
         * Slides in the filter menu and re-centers map on current marker.
         *
         * @function app.ViewModel.slideIn
         * @memberof app.ViewModel
         */
        self.slideIn = function() {
            self.slideClass('animated slideInLeft no-overlay');
            self.centerPanMap();
        };
    
        /**
         * Slides out the filter menu and re-centers map on current marker.
         *
         * @function app.ViewModel.slideOut
         * @memberof app.ViewModel
         */
        self.slideOut = function() {
            self.slideClass('animated fadeOutLeft overlay');
            self.centerPanMap();
        };
    
        /**
         * On small screens, pan the map down 120px to make room for the infoWindow.
         *
         * @function app.ViewModel.centerPanMap
         * @memberof  app.ViewModel
         */
        self.centerPanMap = function() {
            google.maps.event.trigger(app.mv.map,'resize');
            if(app.mv.currentLocation) app.mv.map.setCenter(app.mv.currentLocation);
            if(window.screen.height > 400 && window.screen.width < 415) app.mv.map.panBy(0, -120);
        };
    
        /**
         * Prevents the page from refreshing when the <ENTER> key is pressed.
         *
         * @function app.ViewModel.noEnter
         * @memberof app.ViewModel
         * @returns {boolean} - False
         */
        self.noEnter = function(data, event) {
  • ¶

    Prevent form submission

            return false;
        };
    
        /**
         * Runs when a hotel is selected in the list view.
         *
         * @function app.ViewModel.gotoHotel
         * @memberof app.ViewModel
         */
        self.gotoHotel = function(hotel) {
  • ¶

    Pan down 120px (keeps tall infoWindow from getting cutoff) Do not pan if in landscape mode

            if(window.screen.height > 400 && window.screen.width < 415) app.mv.map.panBy(0, -120);
    
            app.mv.infoWindow.close();
  • ¶

    Manually trigger the click event for the marker

            google.maps.event.trigger(hotel.marker, 'click');
        };
    
        /**
         * Toggles diamond rating checkbox, and filters hotels displayed by rating.
         *
         * @function app.ViewModel.filterRatings
         * @memberof app.ViewModel
         */
        self.filterRatings = function(data, event) {
            self.hotelDisplay();
  • ¶

    Return true to toggle checkbox

            return true;
        };
    
        /**
         * Toggles display of the Hotel Name search
         *
         * @function app.ViewModel.toggleName
         * @memberof app.ViewModel
         */
        self.toggleName = function() {
            self.showName(!self.showName());
        };
    
        /**
         * Toggles display of the Diamond Rating filter
         *
         * @function app.ViewModel.toggleRating
         * @memberof app.ViewModel
         */
        self.toggleRating = function() {
            self.showRating(!self.showRating());
        };
    
        /**
         * Toggles display of the Diamond Rating Definitions.
         *
         * @function app.ViewModel.toggleList
         * @memberof app.ViewModel
         */
        self.toggleList = function() {
            self.showList(!self.showList());
        };
    
        /**
         * Toggles display the Diamond Rating Definitions.
         *
         * @function app.ViewModel.toggleDef
         * @memberof app.ViewModel
         */
        self.toggleDef = function() {
            self.showDef(!self.showDef());
        };
    
        /**
         * Real time filtering of hotels displayed in the list and map.
         *
         * @function app.ViewModel.hotelDisplay
         * @memberof app.ViewModel
         * @returns {object} - Filtered list of hotels
         */
        self.hotelDisplay = ko.computed(function() {
            var result = -1;
            var temp = [];
            var query = self.filterText().toLowerCase();
            var rlength = self.ratingsChecked().length;
            var diamond = 0;
            var match = -1;
  • ¶

    Reset the twitter ticker

            self.showTicker(false);
  • ¶

    Copy the original hotel list array

            self.filterList(self.hotelList());
    
            if (!query && rlength <= 0) {
  • ¶

    Make all the hotel markers visible

                self.filterList().forEach(function(hotel, index) {
  • ¶

    Prevents error if marker is not set yet

                    if(hotel.marker) hotel.marker.setVisible(true);
                });
  • ¶

    Return all the hotels

                return self.filterList;
            } else {
                self.filterList().forEach(function(hotel, index) {
  • ¶

    Check if the query matches with the hotel name

                    result = hotel.name.toLowerCase().indexOf(query);
                    diamond = hotel.diamonds;
  • ¶

    Ratings check

                    if(rlength > 0)
                        match = self.ratingsChecked.indexOf(diamond);
                    else
                        match = 0;
    
                    if(result >= 0 && match >= 0) {
                        hotel.marker.setVisible(true);
                        temp.push(hotel);
                    } else {
                        hotel.marker.setVisible(false);
                        app.mv.infoWindow.close();
                    }
                }); // forEach
  • ¶

    Save the filtered hotels back to the ko observable array

                self.filterList(temp);
    
                return self.filterList;
            } // else
        }); // hotelDisplay
    
    }; // ViewModel