/*-----------------------------*/ /* /* Cofman mapWidget v1.0 /* /* REQUIRES: /* - Pre load Google MAPS api, with the same language as mapWidget /* - jQuery (1.5) + jQuery UI (1.8) /* /*-----------------------------*/ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/) { var len = this.length; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len; for (; from < len; from++) { if (from in this && this[from] === elt) return from; } return -1; }; } (function( $ ){ // Default settings var mapWidget = {options:{}}; var settings = { 'service' : 'http://com.cofman.org/map-widget/service.php', // Cookie less domain? 'searchOverMap' : true, 'field': { 'search' : 'search', 'dist' : 'radius', 'lat' : 'latitude', 'lng' : 'longitude' }, 'bounds': { ne: { lat: 58.028460, lng: 15.229800 }, sw: { lat: 54.431700, lng: 7.855200 } }, 'center': { lat: 56.263920, lng: 9.501785 }, 'marker': false, 'types': ['geocode'], 'disallowed': new Array('route','street_address','point_of_interest','bus_station','museum','transit_station','train_station','university','cemetery','airport','administrative_area_level_2'), 'language': '', 'onClick': null }; var ajaxConf = { type : 'GET', crossDomain : true, cache : true, dataType : 'jsonp', // jsonp : 'callback', jsonpCallback : 'jsonp', complete : function(){xhr=null;} }; var xhr = null, query = '', options = new Array, geocodes = new Array; var autocompleteSources = function(request, response) { if ( request.term == 'undefined' ) { return; } if ( xhr != null ) { return; } options = $.map(options, function(item){ if ( item.label.indexOf(request.term) == 0 ) { return item; } }); if ( request.term.indexOf(query) != 0 || options.length > 5 || options.length == 0 ) { query = request.term; xhr = $.ajax( settings.service, $.extend({data:{query:request.term,language:settings.language},success:function(resp){ options = resp; response(options); return; }},ajaxConf)); } else { response(options); } var geolimit = ', DK, Europe'; mapWidget.geocoder.geocode( {'address': request.term + geolimit, 'region': 'DK' }, function(results, status) { var geoData = {item:[]}; geoData.item = $.map(results, function(item) { if ( settings.disallowed.indexOf(item.types[0]) != -1 ) { return; } if ( geocodes.indexOf(item.formatted_address) != -1 ) { return; } var addr = {}; var itemName = item.address_components[0].long_name, itemNameAdd = ''; if ( 'neighborhood' == item.types[0] ) { for (var k in item.address_components) { addr[item.address_components[k].types[0]] = item.address_components[k].long_name; } itemName += ', ' + addr['postal_code'] + ' ' + addr['administrative_area_level_2']; } else if ( 'locality' == item.types[0] ) { for (var k in item.address_components) { if ( item.address_components[k].types ) addr[item.address_components[k].types[0]] = item.address_components[k].long_name; } if ( addr['locality'] != addr['administrative_area_level_2'] && addr['postal_code'] ) { itemName += ', ' + addr['postal_code'] + ' ' + addr['administrative_area_level_2']; } } geocodes.push(item.formatted_address); var data = { name: itemName, address: item.formatted_address, type: item.types[0], lat: item.geometry.location.lat(), lng: item.geometry.location.lng(), language: settings.language }; var bounds = item.geometry.bounds ? item.geometry.bounds : item.geometry.viewport; data.bound = { 'ne_lat': bounds.getNorthEast().lat(), 'ne_lng': bounds.getNorthEast().lng(), 'sw_lat': bounds.getSouthWest().lat(), 'sw_lng': bounds.getSouthWest().lng() }; return data; }); if ( geoData.item.length > 0 ) { // Send back home.. and get new geoData.query = request.term; geoData.language = settings.language; xhr = $.ajax( settings.service, $.extend({data:geoData,success:function(resp){ query = geoData.query; options = resp; response(options); return; }},ajaxConf)); }; }); }; // Methods for mapWidget var methods = { init : function( options ) { if ( this.length != 1) { return false; } if ( !$(this).attr('id') ) { return false; } var mapCanvasId = $(this).attr('id'); $.extend(settings, options); if ( typeof settings.map == 'object' ) { $.extend(mapWidget.options, settings.map); } if ( settings.searchOverMap === true ) { var $search = $('#' + settings.field.search).hide(); var width = $(this).width() - $search.css('padding-left').replace('px','') - $search.css('padding-right').replace('px', ''); var pos = $(this).position(); $search.css({left: (pos.left+40)+'px', top: (pos.top+8)+'px', position: 'absolute', zIndex: 1000, width: (width-50)+'px' }).show(); } mapWidget.options = $.extend({ center: new google.maps.LatLng(settings.center.lat,settings.center.lng), zoom: 6, mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControl: false, streetViewControl: false },mapWidget.options); mapWidget.geocoder = new google.maps.Geocoder(); mapWidget.map = new google.maps.Map(document.getElementById(mapCanvasId), mapWidget.options) if ( options.bounds || ( !options.map && !options.center ) ) { var ne = new google.maps.LatLng(settings.bounds.ne.lat,settings.bounds.ne.lng); var sw = new google.maps.LatLng(settings.bounds.sw.lat,settings.bounds.sw.lng); mapWidget.map.fitBounds(new google.maps.LatLngBounds(sw,ne)); } var markerIcon = new google.maps.MarkerImage('http://com.cofman.org/map-widget/marker.png', new google.maps.Size(7,7), new google.maps.Point(0,0), new google.maps.Point(4,4) ); mapWidget.marker = new google.maps.Marker({ map: mapWidget.map, icon: markerIcon }); if ( options.marker === true ) { mapWidget.marker.setPosition(mapWidget.options.center); } google.maps.event.addListener(mapWidget.map, 'click', function(event) { methods.reverseGeocoder(event.latLng); mapWidget.marker.setPosition(event.latLng); }); $('#'+settings.field.search).autocomplete({ minLength: 2, //This bit uses the geocoder to fetch address values source: autocompleteSources, //This bit is executed upon selection of an address select: function(event, ui) { methods.response({ search: ui.item.label, lat: ui.item.lat, lng: ui.item.lng, dist: ui.item.dist }); var location = new google.maps.LatLng(ui.item.lat, ui.item.lng); if (ui.item.bound) { var ne = new google.maps.LatLng(ui.item.bound['ne_lat'],ui.item.bound['ne_lng']); var sw = new google.maps.LatLng(ui.item.bound['sw_lat'],ui.item.bound['sw_lng']); mapWidget.map.fitBounds(new google.maps.LatLngBounds(sw,ne)); } else { mapWidget.map.setCenter(location); } mapWidget.marker.setPosition(location); $.ajax( settings.service, $.extend({data:{id:ui.item.id,action:'select'},success:function(resp){return true;}},ajaxConf)); } }); $('.ui-autocomplete').css({width:$('#'+settings.field.search).width()+'px'}); // google.maps.event.addListener(mapWidget.marker, 'drag', methods.reverseGeoMarker); google.maps.event.addListener(mapWidget.marker, 'position_changed', methods.reverseGeoMarker); }, reverseGeoMarker : function( ) { mapWidget.geocoder.geocode({'latLng': mapWidget.marker.getPosition()}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { if (results[0]) { // TODO: Something.. } } }); }, reverseGeocoder : function( latLng ) { var data = { lat: latLng.lat(), lng: latLng.lng(), language: settings.language }; $.ajax( settings.service, $.extend({data:data,success:function(resp){ if ( resp.length == 0 ) { methods.response({ search: '', lat: latLng.lat(), lng: latLng.lng(), dist: 0 }); } methods.response(resp); if ( typeof settings['onClick'] == 'function' ) { settings['onClick'].call(); } }},ajaxConf)); }, response: function( resp ) { if ( typeof resp !== 'object' ) { return false; } for (var k in resp) { if ( $('#' + settings['field'][k]).is('input') ) { $('#' + settings['field'][k]).val(resp[k]); } else { $('#' + settings['field'][k]).html(resp[k]); } } } }; $.fn.mapWidget = function( method ) { if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.mapWidget' ); } }; })( jQuery );