Your IP : 216.73.216.182


Current Path : /var/www/html/components/com_community/assets/source/js/utils/
Upload File :
Current File : /var/www/html/components/com_community/assets/source/js/utils/location-autocomplete.js

(function( root, $, _, factory ) {

    var LocationAutocomplete = factory( root, $, _ );

    define([ 'utils/map' ], function() {
        return LocationAutocomplete;
    });

    // make jQuery plugin
    $.fn.locationAutocomplete = function() {
        return this.each(function() {
            var key = 'location-autocomplete',
                $el = $( this );
            if ( ! $el.data( key ) ) {
                $el.data( key, new LocationAutocomplete( this ));
            }
        });
    };

    // detect input on page load
    $(function() {
        $('.joms-input--location').locationAutocomplete();
    });

})( window, joms.jQuery, window._, function( window, $, _ ) {

function LocationAutocomplete( el ) {
    this.$input = $( el );

    this.$wrapper = this.$input.parent('.joms-location__wrapper');
    this.$inputDesc = this.$input.siblings('.js-desc');
    this.$inputLat = this.$input.siblings('.js-lat');
    this.$inputLng = this.$input.siblings('.js-lng');
    this.$description = this.$input.siblings('.joms-location__description');
    this.$dropdown = this.$input.siblings('.joms-location__dropdown');
    this.$loading = this.$dropdown.find('.joms-location__loading');
    this.$result = this.$dropdown.find('.joms-location__result');
    this.$header = this.$dropdown.find('.joms-location__header');
    this.$map = this.$dropdown.find('.joms-location__map');
    this.$list = this.$dropdown.find('.joms-location__list');

    this.$input.on('focus.joms-location', $.proxy( this.focus, this ));
    this.$input.on('blur.joms-location', $.proxy( this.hide, this ));
    this.$input.on('input.joms-location', $.proxy( this.search, this ));
    this.$dropdown.on('mousedown', '.joms-location__list a', $.proxy( this.select, this ));
    this.$dropdown.on('click', '.joms-location__close', $.proxy( this.hide, this ));
    this._location_cache = {};
}

LocationAutocomplete.prototype.show = function() {
    this.$dropdown.show();
};

LocationAutocomplete.prototype.hide = function() {
    this.$dropdown && this.$dropdown.hide();
};

LocationAutocomplete.prototype.focus = function() {
    this._search_success && this.show();
};

LocationAutocomplete.prototype.search = function() {
    var query = $.trim( this.$input.val() );
    this.$wrapper.css('display', 'inline-block');
    this.$description.html( this.$description.data('tips') );
    if ( query ) {
        this.$result.hide();
        this.$loading.show();
        this.$dropdown.show();
        this._search( query );
    }
    setTimeout( $.proxy(function() {
        this.$wrapper.css('display', '');
    }, this ), 0 );
};

LocationAutocomplete.prototype._search = _.debounce(function( query ) {
    this._get_autocomplete_service().done(function( service ) {
        service.getPlacePredictions({ input: query }, $.proxy(function( results, status ) {
            this.$loading.hide();
            this.$result.show();
            if ( status === 'OK' ) {
                this._format_result( results ).done( $.proxy(function( html ) {
                    this.$list.html( html );
                    this._search_success = true;
                }, this ));
            }
        }, this ));
    });
}, 1000 );

LocationAutocomplete.prototype.select = function( e ) {
    var $item = $( e.currentTarget ),
        name = $item.find('.js-name').text(),
        desc = $item.find('.js-desc').text(),
        placeId = $item.data('place-id');

    e.preventDefault();
    e.stopPropagation();

    if ( placeId ) {
        this.$input.val( name );
        this.$inputDesc.val( desc );
        this.$description.html( desc );
        this._get_location_detail( placeId ).done(function( place ) {
            var loc = place.geometry.location;
            this.$inputLat.val( loc.lat() );
            this.$inputLng.val( loc.lng() );
            this._render_map( this.$map[0], place );
        });
    }
};

LocationAutocomplete.prototype._load_library = function() {
    return $.Deferred( $.proxy(function( defer ) {
        joms.util.map( $.proxy(function() {
            defer.resolveWith( this, [ window.google ]);
        }, this ));
    }, this ));
};

LocationAutocomplete.prototype._get_autocomplete_service = function() {
    return $.Deferred( $.proxy(function( defer ) {
        if ( this._autocomplete_service ) {
            defer.resolveWith( this, [ this._autocomplete_service ]);
        } else {
            this._load_library().done(function( google ) {
                this._autocomplete_service = new google.maps.places.AutocompleteService();
                defer.resolveWith( this, [ this._autocomplete_service ]);
            });
        }
    }, this ));
};

LocationAutocomplete.prototype._get_location_service = function() {
    return $.Deferred( $.proxy(function( defer ) {
        if ( this._location_service ) {
            defer.resolveWith( this, [ this._location_service ]);
        } else {
            this._load_library().done(function( google ) {
                var div = document.createElement('div');
                document.body.appendChild( div );
                this._location_service = new google.maps.places.PlacesService( div );
                defer.resolveWith( this, [ this._location_service ]);
            });
        }
    }, this ));
};

LocationAutocomplete.prototype._get_location_detail = function( id ) { 
    return $.Deferred( $.proxy(function( defer ) { 
        if ( this._location_cache && this._location_cache[ id ] ) {
            defer.resolveWith( this, [ this._location_cache[ id ] ]);
        } else {
            this._get_location_service().done(function( service ) {
                service.getDetails({ placeId: id }, $.proxy(function( place, status ) { 
                    if ( status === 'OK' ) {
                      //  this._location_cache || (this._location_cache = {});
                        this._location_cache[ id ] = place;
                        
                        defer.resolveWith( this, [ place ]);
                    } else {
                        defer.rejectWith( this, [ status ]);
                    }
                }, this ));
            });
        }
    }, this ));
};

LocationAutocomplete.prototype._render_map = function( div, place ) {
    var location = place.geometry.location,
        viewport = place.geometry.viewport,
        map, marker;

    div = $( div ).show();
    map = div.data('joms-map');
    marker = div.data('joms-map-marker');

    if ( !map ) {
        map = new window.google.maps.Map( div[0], {
            center: location,
            zoom: 15,
            draggable: false,
            scrollwheel: false,
            disableDefaultUI: true
        });
        div.data('joms-map', map );
    }

    if ( !marker ) {
        marker = new window.google.maps.Marker({
            position: location,
            map: map,
            title: 'You are here (more or less)'
        });
        div.data('joms-map-marker', marker );
    }

    map.setCenter( location );
    marker.setPosition( location );
    if ( viewport ) {
        map.fitBounds( viewport );
    } else {
        map.setZoom( 15 );
    }
};

LocationAutocomplete.prototype._format_result = function( results ) { 
    return $.Deferred( $.proxy(function( defer ) {
        var html = [],
            defers = [],
            template;

        template = [
            '<a href="javascript:" data-place-id="{place_id}">',
            '<span class="joms-location__name js-name">{name}</span>',
            '<span class="joms-location__desc js-desc">{description}</span>',
            '</a>'
        ].join('');

        _.each( results, function( item ) {  
           // defers.push( item);
          
            defers.push( this._get_location_detail( item.place_id ) );
        }, this );
        
        $.when.apply( $, defers ).then( $.proxy(function() {
            var html = _.map( arguments, function( place ) { 
                return template
                    .replace('{place_id}', place.place_id )
                    .replace('{name}', place.name )
                    .replace('{description}', place.formatted_address || '&nbsp;' );
            });

            defer.resolveWith( this, [ html.join('') ]);
        }, this ));
    }, this ));
};

return LocationAutocomplete;

});