/** * Create a Google, bing or klickTel Map. * * The Widget inserts a Google, bing or klickTel Map into the target element on which the widget is executed on. * * ### Examples * The Widget is executed on a pageelement and is called with passing the chosen options. In this example a Google Map is implemented. Zoom factor is 5, controls are shown and the map area is not draggable. * * JavaScript: * * * jQuery.ready({ * plugin: [ 'de_epages.externalcontent.ui.maps' ], * DOM: true * }, function($){ * var widget = de_epages('<div>').externalcontentUiMaps({ * type: "google", * width: 300, * height: 200, * zoom: 5, * title: "Milestones GmbH", * controls: true, * fixedView: true, * lat: 50.65531, * lng: 11.715550000000007 * }); * }); * * * @class jQuery.ui.externalcontentUiMaps * @extends jQuery.widget * * @uses de_epages * @uses jQuery.ui.widget * @uses jQuery.tmpl * @uses jQuery.uid * @uses de_epages.externalcontent.ui.rss * @since 6.15.0 */ /** * This method removes the container on which the map gadget has been appended to. * * @method destroy * @member jQuery.ui.externalcontentUiMaps * * @since 6.15.0 */ /** * @cfg {String} [type] Specifies from which provider the map should be shown. Values: 'google', 'bing', 'klicktel' */ /** * @cfg {Integer} [width] Defines the width of the map in pixels. */ /** * @cfg {Integer} [height] Defines the height of the map in pixels. */ /** * @cfg {Integer} [zoom] Defines the zoom factor of the shown place on the map. */ /** * @cfg {String} [title] Defines the title of the map widget, e.g. the name and adress of the company. */ /** * @cfg {Boolean} [controls] Specifies whether to display the control elements of the embedded map. */ /** * @cfg {Boolean} [fixedView] Prevents the map from being dragged, if false. */ /** * @cfg {Float} [lat] Specifies the latitude (geographic coordinate) of the shown place on the map. */ /** * @cfg {Float} [lng] Specifies the longitude (geographic coordinate) of the shown place on the map. */ /** * See `jQuery.ui.externalcontentUiMaps` for details. * * @param {Object} [options] A map of additional options to pass to the method. * @param {String} [type] Specifies from which provider the map should be shown. Values: 'google', 'bing', 'klicktel' * @param {Integer} [width] Defines the width of the map in pixels. * @param {Integer} [height] Defines the height of the map in pixels. * @param {Integer} [zoom] Defines the zoom factor of the shown place on the map. * @param {String} [title] Defines the title of the map widget, e.g. the name and adress of the company. * @param {Boolean} [controls] Specifies whether to display the control elements of the embedded map. * @param {Boolean} [fixedView] Prevents the map from being dragged, if false. * @param {Float} [lat] Specifies the latitude (geographic coordinate) of the shown place on the map. * @param {Float} [lng] Specifies the longitude (geographic coordinate) of the shown place on the map. * * @method externalcontentUiMaps * @member jQuery * * @since 6.15.0 */ /* * @copyright © Copyright 2006-2012, epages GmbH, All Rights Reserved. * * @module de_epages.externalcontent.ui.maps * * @revision $Revision: 1.14 $ */ /*jslint nomen: true, browser: true*/ /*global define*/ define('de_epages/externalcontent/ui/maps', [ 'jquery/ui/widget', 'ep', 'de_epages', '$dict!../dictionary', 'util/browser', 'jquery/tmpl', 'jquery/uid' ], function ($, ep, de_epages, dict) { 'use strict'; // Gagdet class name var gadgetClassName = '', // Container template id tmplContainerId = 'de_epages.externalcontent.ui.maps', // Cache of ajax deferreds by url ajaxCache = {}, callbackStack = []; // Render and cache template. $.template(tmplContainerId, '<div style="width: ${width}px; height: ${height}px;{{if type === "bing"}} position: relative;{{/if}}"></div>'); // Define widget $.widget('ui.externalcontentUiMaps', { options: { type: 'google', controls: true, fixedView: false, width: 500, height: 300, lat: 50.9287910, lng: 11.5846220, zoom: 15, title: '' }, _create: function () { var self = this, type = self.options.type, api = self.api = self[type] && self[type].render ? self[type] : self.google; // Use google as default fallback // Load API async ((api.load && api.load.call(self)) || $.Deferred().resolve()).done(function (data) { // Add ui class name self.element.addClass(gadgetClassName); // Start rendering api.render.call(self, data); }); }, // Google Map load and render API google: { // Load API and return deferred object or false load: function () { var url = 'https://www.google.com/jsapi'; // API already loaded if (window.google && window.google.load) { return; } // Request already started if (ajaxCache[url]) { return ajaxCache[url]; } // Request API return (ajaxCache[url] = ep.ajax({ url: url, dataType: 'script', cache: true })); }, // Render map using loaded api render: function () { var self = this, o = self.options; if (o.renderMapsPreview && o.renderMapsPreview===true) { window.google.load('maps', '3', { other_params: 'sensor=false', callback: function () { self.api.renderCallback(self, true); } }); } else { // If Google Maps API is already loaded if(window.google.maps) { callbackStack.push(function () { self.api.renderCallback(self, false); }); // Load Google Maps API. } else { window.google.load('maps', '3', { other_params: 'sensor=false', callback: function () { self.api.renderCallback(self, true); } }); } } }, renderCallback: function (self, executeExternalCallbacks) { var o = self.options, centerMarker, center, i; // Init *container*. self.container = $.tmpl(tmplContainerId, o).appendTo(self.element.empty()); // Init *map*. centerMarker = new window.google.maps.LatLng(o.lat, o.lng); center = o.center ? new window.google.maps.LatLng(o.center.lat, o.center.lng) : centerMarker; self.marker = new window.google.maps.Marker({ position: centerMarker }); if (o.title) { self.marker.setTitle(o.title); } self.infoWindow = new window.google.maps.InfoWindow({ content: self.getDescription('https://maps.google.com/maps?saddr=${lat},${lng}', 'https://maps.google.com/maps?daddr=${lat},${lng}'), position: center }); self.infoWindow.isOpen = false; self.map = new window.google.maps.Map(self.container[0], { disableDefaultUI: !o.controls, draggable: !o.fixedView, center: center, mapTypeId: o.mapType || 'roadmap', zoom: o.zoom }); self.marker.setMap(self.map); window.google.maps.event.addListener(self.marker, 'click', function () { // a click on the marker toggles the info window: if it is open, it // should be closed and if it is closed it should be opened. //#JSCOVERAGE_IF false //because of faked request no marker is testable if (self.infoWindow.isOpen) { self.infoWindow.close(); } else { self.infoWindow.open(self.map, this); } self.infoWindow.isOpen = !self.infoWindow.isOpen; //#JSCOVERAGE_ENDIF }); window.google.maps.event.addListener(self.map, 'click', function () { // a click on the map closes the info window. //#JSCOVERAGE_IF false //because of faked request no clicks can be tested self.infoWindow.close(); self.infoWindow.isOpen = false; //#JSCOVERAGE_ENDIF }); if (typeof o.callback === 'function') { o.callback(o.type, self.map, self.marker); } if (executeExternalCallbacks) { for (i=0; i<callbackStack.length; i++) { callbackStack[i](); } } } }, // Bing Map load and render API bing: { // Load API and return deferred object or false load: function () { var url = '//ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2' + (ep.config.requestProtocolAndServer ? '&s=1' : ''); // API already loaded if (window.VEMap) { return; } //#JSCOVERAGE_IF false // We cannot come to this code because we need a window.VEMap for testing // Request already started if (ajaxCache[url]) { return ajaxCache[url]; } // Request API return (ajaxCache[url] = ep.ajax({ url: url, dataType: 'script', cache: true })); //#JSCOVERAGE_ENDIF }, // Render map using loaded api render: function () { var self = this, o = self.options, uid = $.uid(), map, center, interval, initBingMap = function () { map.LoadMap(center, o.zoom, o.mapType || window.VEMapStyle.Road, o.fixedView ? true : false, o.mode ? window.VEMapMode[o.mode] : window.VEMapMode.Mode2D); if (!o.controls) { map.HideDashboard(); } self.marker = map.AddPushpin(center); if (o.title) { self.marker.SetDescription(self.getDescription('http://www.bing.com/maps/?rtp=pos.${lat}_${lng}', 'http://www.bing.com/maps/?rtp=~pos.${lat}_${lng}')); } if (typeof o.callback === 'function') { o.callback(o.type, self.map, self.marker); } map.ShowInfoBox(self.marker); }; // Init *container*. self.container = $.tmpl(tmplContainerId, o).attr('id', uid).appendTo(self.element.empty()); // Init *map*. map = self.map = new window.VEMap(uid); center = new window.VELatLong(o.lat, o.lng); if ($.browser.mozilla) { //#JSCOVERAGE_IF false // If firefox is detected, use a setInterval to check that the window.VEMap exists and add an additional check to wait until attachEvent exists. interval = setInterval(function () { if (typeof window.VEMap !== "undefined" && document.getElementById(uid).attachEvent !== undefined) { clearInterval(interval); initBingMap(); } }, 10); //#JSCOVERAGE_ENDIF } else { initBingMap(); } }, // Destroy rendered map destroy: function () { this.map.Dispose(); } }, // KlickTel Map load and render API klicktel: { // Load API and return deferred object or false load: function () { var klicktel = 'de_epages.externalcontent.ui.klicktel'; if (!$.template[klicktel]) { $.template(klicktel, '<iframe src="?' + 'ViewAction=ViewKlicktelMap&ChangeAction=CalculateKlicktelMap' + '&ObjectID=${ep.config.siteId}&Address=${address}&MapWidth={{if autoWidth}}auto{{else}}${width}{{/if}}&MapHeight=${height}' + '{{if contactPerson}}&ContactPerson=${contactPerson}{{/if}}{{if email}}&EMail=${email}{{/if}}&UseRoute={{if useRoute}}1{{else}}0{{/if}}' + '&LargeNavigation={{if largeNavigation}}1{{else}}0{{/if}}' + '&ShowAddress={{if showAddress}}1{{else}}0{{/if}}&LayoutLR={{if layoutLR}}1{{else}}0{{/if}}" ' + 'width=${width} height=${height} frameborder=0></iframe>'); } return; }, // Render map using loaded api render: function () { var self = this; self.container = $.tmpl('de_epages.externalcontent.ui.klicktel', self.options).appendTo(self.element.empty()); } }, destroy: function () { // Remove all traces of the widget. var self = this; // Remove gadget class name self.element.removeClass(gadgetClassName); // Call destroy of map type if (self.api.destroy) { self.api.destroy.call(self); } // Remove container if (self.container) { self.container.remove(); } self._superApply(arguments); }, getDescription: function (fromUrl, toUrl) { return this.options.title.replace(/,/g, '<br>') + '<br /> ' + dict.translate('Route') + ': <a href="' + $.tmpl(fromUrl, this.options).text() + '" target="_blank">' + dict.translate('FromHere') + '</a> | <a href="' + $.tmpl(toUrl, this.options).text() + '" target="_blank">' + dict.translate('ToHere') + '</a>'; } }); return de_epages; });