(function($) { /** * Drupal FieldGroup object. */ Drupal.FieldGroup = Drupal.FieldGroup || {}; Drupal.FieldGroup.Effects = Drupal.FieldGroup.Effects || {}; Drupal.FieldGroup.groupWithfocus = null; Drupal.FieldGroup.setGroupWithfocus = function(element) { element.css({display: 'block'}); Drupal.FieldGroup.groupWithfocus = element; } /** * Implements Drupal.FieldGroup.processHook(). */ Drupal.FieldGroup.Effects.processFieldset = { execute: function (context, settings, type) { if (type == 'form') { // Add required fields mark to any fieldsets containing required fields $('fieldset.fieldset', context).once('fieldgroup-effects', function(i) { if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) { $('legend span.fieldset-legend', $(this)).eq(0).append(' ').append($('.form-required').eq(0).clone()); } if ($('.error', $(this)).length) { $('legend span.fieldset-legend', $(this)).eq(0).addClass('error'); Drupal.FieldGroup.setGroupWithfocus($(this)); } }); } } } /** * Implements Drupal.FieldGroup.processHook(). */ Drupal.FieldGroup.Effects.processAccordion = { execute: function (context, settings, type) { $('div.field-group-accordion-wrapper', context).once('fieldgroup-effects', function () { var wrapper = $(this); wrapper.accordion({ autoHeight: false, active: '.field-group-accordion-active', collapsible: true, changestart: function(event, ui) { if ($(this).hasClass('effect-none')) { ui.options.animated = false; } else { ui.options.animated = 'slide'; } } }); if (type == 'form') { var $firstErrorItem = false; // Add required fields mark to any element containing required fields wrapper.find('div.field-group-accordion-item').each(function(i) { if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) { $('h3.ui-accordion-header a').eq(i).append(' ').append($('.form-required').eq(0).clone()); } if ($('.error', $(this)).length) { // Save first error item, for focussing it. if (!$firstErrorItem) { $firstErrorItem = $(this).parent().accordion("activate" , i); } $('h3.ui-accordion-header').eq(i).addClass('error'); } }); // Save first error item, for focussing it. if (!$firstErrorItem) { $('.ui-accordion-content-active', $firstErrorItem).css({height: 'auto', width: 'auto', display: 'block'}); } } }); } } /** * Implements Drupal.FieldGroup.processHook(). */ Drupal.FieldGroup.Effects.processHtabs = { execute: function (context, settings, type) { if (type == 'form') { // Add required fields mark to any element containing required fields $('fieldset.horizontal-tabs-pane', context).once('fieldgroup-effects', function(i) { if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) { $(this).data('horizontalTab').link.find('strong:first').after($('.form-required').eq(0).clone()).after(' '); } if ($('.error', $(this)).length) { $(this).data('horizontalTab').link.parent().addClass('error'); Drupal.FieldGroup.setGroupWithfocus($(this)); $(this).data('horizontalTab').focus(); } }); } } } /** * Implements Drupal.FieldGroup.processHook(). */ Drupal.FieldGroup.Effects.processTabs = { execute: function (context, settings, type) { if (type == 'form') { // Add required fields mark to any fieldsets containing required fields $('fieldset.vertical-tabs-pane', context).once('fieldgroup-effects', function(i) { if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) { $(this).data('verticalTab').link.find('strong:first').after($('.form-required').eq(0).clone()).after(' '); } if ($('.error', $(this)).length) { $(this).data('verticalTab').link.parent().addClass('error'); Drupal.FieldGroup.setGroupWithfocus($(this)); $(this).data('verticalTab').focus(); } }); } } } /** * Implements Drupal.FieldGroup.processHook(). * * TODO clean this up meaning check if this is really * necessary. */ Drupal.FieldGroup.Effects.processDiv = { execute: function (context, settings, type) { $('div.collapsible', context).once('fieldgroup-effects', function() { var $wrapper = $(this); // Turn the legend into a clickable link, but retain span.field-group-format-toggler // for CSS positioning. var $toggler = $('span.field-group-format-toggler:first', $wrapper); var $link = $(''); $link.prepend($toggler.contents()); // Add required field markers if needed if ($(this).is('.required-fields') && $(this).find('.form-required').length > 0) { $link.append(' ').append($('.form-required').eq(0).clone()); } $link.appendTo($toggler); // .wrapInner() does not retain bound events. $link.click(function () { var wrapper = $wrapper.get(0); // Don't animate multiple times. if (!wrapper.animating) { wrapper.animating = true; var speed = $wrapper.hasClass('speed-fast') ? 300 : 1000; if ($wrapper.hasClass('effect-none') && $wrapper.hasClass('speed-none')) { $('> .field-group-format-wrapper', wrapper).toggle(); } else if ($wrapper.hasClass('effect-blind')) { $('> .field-group-format-wrapper', wrapper).toggle('blind', {}, speed); } else { $('> .field-group-format-wrapper', wrapper).toggle(speed); } wrapper.animating = false; } $wrapper.toggleClass('collapsed'); return false; }); }); } }; /** * Behaviors. */ Drupal.behaviors.fieldGroup = { attach: function (context, settings) { settings.field_group = settings.field_group || Drupal.settings.field_group; if (settings.field_group == undefined) { return; } // Execute all of them. $.each(Drupal.FieldGroup.Effects, function (func) { // We check for a wrapper function in Drupal.field_group as // alternative for dynamic string function calls. var type = func.toLowerCase().replace("process", ""); if (settings.field_group[type] != undefined && $.isFunction(this.execute)) { this.execute(context, settings, settings.field_group[type]); } }); // Fixes css for fieldgroups under vertical tabs. $('.fieldset-wrapper .fieldset > legend').css({display: 'block'}); $('.vertical-tabs fieldset.fieldset').addClass('default-fallback'); // Add a new ID to each fieldset. $('.group-wrapper fieldset').each(function() { // Tats bad, but we have to keep the actual id to prevent layouts to break. var fieldgorupID = 'field_group-' + $(this).attr('id') + ' ' + $(this).attr('id'); $(this).attr('id', fieldgorupID); }) // Set the hash in url to remember last userselection. $('.group-wrapper ul li').each(function() { var fieldGroupNavigationListIndex = $(this).index(); $(this).children('a').click(function() { var fieldset = $('.group-wrapper fieldset').get(fieldGroupNavigationListIndex); // Grab the first id, holding the wanted hashurl. var hashUrl = $(fieldset).attr('id').replace(/^field_group-/, '').split(' ')[0]; window.location.hash = hashUrl; }); }); } }; })(jQuery);; /** * @file * Drupal to Google Maps API bridge. */ /*global jQuery, Drupal, GLatLng, GSmallZoomControl, GLargeMapControl, GMap2 */ /*global GMapTypeControl, GSmallMapControl, G_HYBRID_MAP, G_NORMAL_MAP */ /*global G_PHYSICAL_MAP, G_SATELLITE_MAP, GHierarchicalMapTypeControl */ /*global GKeyboardHandler, GLatLngBounds, GMenuMapTypeControl, GEvent */ /*global GOverviewMapControl, GScaleControl, GUnload */ /*jshint -W069 */ (function () { // BEGIN closure var handlers = {}; var maps = {}; var ajaxoffset = 0; Drupal.gmap = { /** * Retrieve a map object for use by a non-widget. * Use this if you need to be able to fire events against a certain map * which you have the mapid for. * Be a good GMap citizen! Remember to send change()s after modifying variables! */ getMap: function (mapid) { if (maps[mapid]) { return maps[mapid]; } else { // Perhaps the user passed a widget id instead? mapid = mapid.split('-').slice(1, -1).join('-'); if (maps[mapid]) { return maps[mapid]; } } return false; }, unloadMap: function (mapid) { delete maps[mapid]; }, addHandler: function (handler, callback) { if (!handlers[handler]) { handlers[handler] = []; } handlers[handler].push(callback); }, globalChange: function (name, userdata) { for (var mapid in Drupal.settings.gmap) { if (Drupal.settings.gmap.hasOwnProperty(mapid)) { // Skip maps that are set up but not shown, etc. if (maps[mapid]) { maps[mapid].change(name, -1, userdata); } } } }, setup: function (settings) { var obj = this; var initcallback = function (mapid) { return (function () { maps[mapid].change("bootstrap_options", -1); maps[mapid].change("boot", -1); maps[mapid].change("init", -1); // Send some changed events to fire up the rest of the initial settings.. maps[mapid].change("maptypechange", -1); maps[mapid].change("controltypechange", -1); maps[mapid].change("alignchange", -1); // Set ready to put the event system into action. maps[mapid].ready = true; maps[mapid].change("ready", -1); }); }; if (settings || (Drupal.settings && Drupal.settings.gmap)) { var mapid = obj.id.split('-'); if (Drupal.settings['gmap_remap_widgets']) { if (Drupal.settings['gmap_remap_widgets'][obj.id]) { jQuery.each(Drupal.settings['gmap_remap_widgets'][obj.id].classes, function () { jQuery(obj).addClass(this); }); mapid = Drupal.settings['gmap_remap_widgets'][obj.id].id.split('-'); } } var instanceid = mapid.pop(); mapid.shift(); mapid = mapid.join('-'); var control = instanceid.replace(/\d+$/, ''); // Lazy init the map object. if (!maps[mapid]) { if (settings) { maps[mapid] = new Drupal.gmap.map(settings); } else { maps[mapid] = new Drupal.gmap.map(Drupal.settings.gmap[mapid]); } // Prepare the initialization callback. var callback = initcallback(mapid); setTimeout(callback, 0); } if (handlers[control]) { for (var i = 0; i < handlers[control].length; i++) { handlers[control][i].call(maps[mapid], obj); } } else { // Element with wrong class? } } } }; jQuery.fn.createGMap = function (settings, mapid) { return this.each(function () { if (!mapid) { mapid = 'auto' + ajaxoffset + 'ajax'; ajaxoffset++; } settings.id = mapid; jQuery(this) .attr('id', 'gmap-' + mapid + '-gmap0') .css('width', settings.width) .css('height', settings.height) .addClass('gmap-control') .addClass('gmap-gmap') .addClass('gmap') .addClass('gmap-map') .addClass('gmap-' + mapid + '-gmap') .addClass('gmap-processed') .each(function () { Drupal.gmap.setup.call(this, settings); }); }); }; })(); // END closure Drupal.gmap.factory = {}; Drupal.gmap.map = function (v) { this.vars = v; this.map = undefined; this.ready = false; var _bindings = {}; /** * Register interest in a change. */ this.bind = function (name, callback) { if (!_bindings[name]) { _bindings[name] = []; } return _bindings[name].push(callback) - 1; }; /** * Change notification. * Interested parties can act on changes. */ this.change = function (name, id, userdata) { var c; if (_bindings[name]) { for (c = 0; c < _bindings[name].length; c++) { if (c !== id) { _bindings[name][c](userdata); } } } if (name !== 'all') { this.change('all', -1, name, userdata); } }; /** * Deferred change notification. * This will cause a change notification to be tacked on to the *end* of the event queue. */ this.deferChange = function (name, id, userdata) { var obj = this; // This will move the function call to the end of the event loop. setTimeout(function () { obj.change(name, id, userdata); }, 0); }; this.getMapTypeName = function (type) { if (type == 'map' || type == 'roadmap') return 'Map'; if (type == 'hybrid') return 'Hybrid'; if (type == 'physical' || type == 'terrain') return 'Physical'; if (type == 'satellite') return 'Satellite'; }; this.getMapTypeId = function (type) { if (type == 'Map' || type == 'Roadmap') return google.maps.MapTypeId.ROADMAP; if (type == 'Hybrid') return google.maps.MapTypeId.HYBRID; if (type == 'Physical' || type == 'Terrain') return google.maps.MapTypeId.TERRAIN; if (type == 'Satellite') return google.maps.MapTypeId.SATELLITE; }; }; //////////////////////////////////////// // Map widget // //////////////////////////////////////// Drupal.gmap.addHandler('gmap', function (elem) { var obj = this; var _ib = {}; // Respond to incoming zooms _ib.zoom = obj.bind("zoom", function (zoom) { obj.map.setZoom(obj.vars.zoom); }); // Respond to incoming moves _ib.move = obj.bind("move", function () { obj.map.panTo(new google.maps.LatLng(obj.vars.latitude, obj.vars.longitude)); }); // Respond to incoming width changes. _ib.width = obj.bind("widthchange", function (w) { obj.map.getDiv().style.width = w; google.maps.event.trigger(obj.map); }); // Send out outgoing width changes. // N/A // Respond to incoming height changes. _ib.height = obj.bind("heightchange", function (h) { obj.map.getDiv().style.height = h; google.maps.event.trigger(obj.map); }); // Send out outgoing height changes. // N/A // Respond to incoming control type changes. _ib.ctc = obj.bind("controltypechange", function () { if (obj.vars.controltype === 'Small') { obj.map.setOptions({zoomControlOptions: {style: google.maps.ZoomControlStyle.SMALL}}); } else if (obj.vars.controltype === 'Large') { obj.map.setOptions({zoomControlOptions: {style: google.maps.ZoomControlStyle.LARGE}}); } // obsolete else if (obj.vars.controltype === 'Android') { obj.map.setOptions({zoomControlOptions: {style: google.maps.ZoomControlStyle.SMALL}}); } }); // Send out outgoing control type changes. // N/A // Respond to incoming map type changes. _ib.mtc = obj.bind("maptypechange", function () { obj.map.setMapTypeId(obj.getMapTypeId(obj.vars.maptype)); }); // Send out outgoing map type changes. // N/A obj.bind("bootstrap_options", function () { // Bootup options. var opts = {}; // Object literal google.maps.MapOptions obj.opts = opts; // Disable default UI for custom options opts.disableDefaultUI = true; // Set draggable property if (obj.vars.behavior.nodrag) { opts.draggable = false; } else if (obj.vars.behavior.nokeyboard) { opts.keyboardShortcuts = false; } // Set default map type (set to road map if nothing selected) switch (obj.vars.maptype) { case 'Hybrid': opts.mapTypeId = google.maps.MapTypeId.HYBRID; break; case 'Physical': opts.mapTypeId = google.maps.MapTypeId.TERRAIN; break; case 'Satellite': opts.mapTypeId = google.maps.MapTypeId.SATELLITE; break; /* falls through */ case 'Map': /* falls through */ default: opts.mapTypeId = google.maps.MapTypeId.ROADMAP; break; } // Null out the enabled types. opts.mapTypeIds = []; if (obj.vars.baselayers.Map) { opts.mapTypeIds.push(google.maps.MapTypeId.ROADMAP); } if (obj.vars.baselayers.Hybrid) { opts.mapTypeIds.push(google.maps.MapTypeId.HYBRID); } if (obj.vars.baselayers.Physical) { opts.mapTypeIds.push(google.maps.MapTypeId.TERRAIN); } if (obj.vars.baselayers.Satellite) { opts.mapTypeIds.push(google.maps.MapTypeId.SATELLITE); } if (obj.vars.draggableCursor) { opts.draggableCursor = obj.vars.draggableCursor; } if (obj.vars.draggingCursor) { opts.draggingCursor = obj.vars.draggingCursor; } if (obj.vars.backgroundColor) { opts.backgroundColor = obj.vars.backgroundColor; } // Map type control opts.mapTypeControl = true; opts.mapTypeControlOptions = {}; if (obj.vars.mtc === 'standard') { opts.mapTypeControlOptions.style = google.maps.MapTypeControlStyle.DEFAULT; } else if (obj.vars.mtc === 'horiz') { opts.mapTypeControlOptions.style = google.maps.MapTypeControlStyle.HORIZONTAL_BAR; } else if (obj.vars.mtc === 'menu') { opts.mapTypeControlOptions.style = google.maps.MapTypeControlStyle.DROPDOWN_MENU; } else if (obj.vars.mtc === 'none') { opts.mapTypeControl = false; } // Navigation control type if (obj.vars.controltype !== 'None') { opts.zoomControl = true; } if (obj.vars.pancontrol) { opts.panControl = true; } if (obj.vars.streetviewcontrol) { opts.streetViewControl = true; } if (obj.vars.controltype === 'Small') { obj.zoomControlOptions = {style: google.maps.ZoomControlStyle.SMALL}; } else if (obj.vars.controltype === 'Large') { obj.zoomControlOptions = {style: google.maps.ZoomControlStyle.LARGE}; } // Set scale control visibility opts.scaleControl = obj.vars.behavior.scale; // Scroll wheel control if (obj.vars.behavior.nomousezoom) { opts.scrollwheel = false; } // Disable double-click zoom if (obj.vars.behavior.nocontzoom) { opts.disableDoubleClickZoom = true; } // Overview Map if (obj.vars.behavior.overview) { opts.overviewMapControl = true; opts.overviewMapControlOptions = {opened: true}; } // Map styles. if (obj.vars.mapstyles) { obj.opts.styles = obj.vars.mapstyles; } }); obj.bind("boot", function () { obj.map = new google.maps.Map(elem, obj.opts); //console.log(obj.map); }); obj.bind("init", function () { var map = obj.map; // Not implemented in API v3 // if (obj.vars.behavior.overview) { // map.addControl(new GOverviewMapControl()); // } // if (obj.vars.behavior.googlebar) { // map.enableGoogleBar(); // } if (obj.vars.extent) { var c = obj.vars.extent; var extent = new google.maps.LatLngBounds(new google.maps.LatLng(c[0][0], c[0][1]), new google.maps.LatLng(c[1][0], c[1][1])); obj.vars.latitude = extent.getCenter().lat(); obj.vars.longitude = extent.getCenter().lng(); obj.vars.zoom = map.getBoundsZoomLevel(extent); } if (obj.vars.behavior.collapsehack) { // Modify collapsable fieldsets to make maps check dom state when the resize handle // is clicked. This may not necessarily be the correct thing to do in all themes, // hence it being a behavior. setTimeout(function () { var r = function () { var coord = map.getCenter(); google.maps.event.trigger(map, "resize"); map.setCenter(new google.maps.LatLng(coord.lat(), coord.lng()), obj.vars.zoom); }; jQuery(elem).parents('fieldset.collapsible').children('legend').children('a').click(r); jQuery('.vertical-tab-button', jQuery(elem).parents('.vertical-tabs')).children('a').click(r); jQuery(window).bind('hashchange', r); // Would be nice, but doesn't work. //$(elem).parents('fieldset.collapsible').children('.fieldset-wrapper').scroll(r); }, 0); } map.setCenter(new google.maps.LatLng(obj.vars.latitude, obj.vars.longitude)); map.setZoom(obj.vars.zoom); // Send out outgoing zooms google.maps.event.addListener(map, "zoom_changed", function () { obj.vars.zoom = map.getZoom(); obj.change("zoom", _ib.zoom); }); // Send out outgoing moves google.maps.event.addListener(map, "center_changed", function () { var coord = map.getCenter(); obj.vars.latitude = coord.lat(); obj.vars.longitude = coord.lng(); obj.change("move", _ib.move); }); // Send out outgoing map type changes. google.maps.event.addListener(map, "maptypeid_changed", function () { // If the map isn't ready yet, ignore it. if (obj.ready) { obj.vars.maptype = obj.getMapTypeName(map.getMapTypeId()); obj.change("maptypechange", _ib.mtc); } }); /* google.maps.event.addListener(map, 'click', function(event) { alert(Drupal.gmap.getIcon("big blue", 0)); var marker = new google.maps.Marker({ position: event.latLng, map: map }); google.maps.event.addListener(marker, 'click', function() { marker.setMap(null); }); }); */ }); }); //////////////////////////////////////// // Zoom widget // //////////////////////////////////////// Drupal.gmap.addHandler('zoom', function (elem) { var obj = this; // Respond to incoming zooms var binding = obj.bind("zoom", function () { elem.value = obj.vars.zoom; }); // Send out outgoing zooms jQuery(elem).change(function () { obj.vars.zoom = parseInt(elem.value, 10); obj.change("zoom", binding); }); }); //////////////////////////////////////// // Latitude widget // //////////////////////////////////////// Drupal.gmap.addHandler('latitude', function (elem) { // var obj = this; // // Respond to incoming movements. // var binding = obj.bind("move", function () { // elem.value = '' + obj.vars.latitude; // }); // // Send out outgoing movements. // $(elem).change(function () { // obj.vars.latitude = Number(this.value); // obj.change("move", binding); // }); }); //////////////////////////////////////// // Longitude widget // //////////////////////////////////////// Drupal.gmap.addHandler('longitude', function (elem) { // var obj = this; // // Respond to incoming movements. // var binding = obj.bind("move", function () { // elem.value = '' + obj.vars.longitude; // }); // // Send out outgoing movements. // $(elem).change(function () { // obj.vars.longitude = Number(this.value); // obj.change("move", binding); // }); }); //////////////////////////////////////// // Latlon widget // //////////////////////////////////////// Drupal.gmap.addHandler('latlon', function (elem) { var obj = this; // Respond to incoming movements. var binding = obj.bind("move", function () { elem.value = '' + obj.vars.latitude + ',' + obj.vars.longitude; }); // Send out outgoing movements. jQuery(elem).change(function () { var t = this.value.split(','); obj.vars.latitude = Number(t[0]); obj.vars.longitude = Number(t[1]); obj.change("move", binding); }); }); //////////////////////////////////////// // Maptype widget // //////////////////////////////////////// Drupal.gmap.addHandler('maptype', function (elem) { var obj = this; // Respond to incoming movements. var binding = obj.bind("maptypechange", function () { elem.value = obj.vars.maptype; }); // Send out outgoing movements. jQuery(elem).change(function () { obj.vars.maptype = elem.value; obj.change("maptypechange", binding); }); }); (function () { // BEGIN CLOSURE var re = /([0-9.]+)\s*(em|ex|px|in|cm|mm|pt|pc|%)/; var normalize = function (str) { var ar; if ((ar = re.exec(str.toLowerCase()))) { return ar[1] + ar[2]; } return null; }; //////////////////////////////////////// // Width widget // //////////////////////////////////////// Drupal.gmap.addHandler('width', function (elem) { var obj = this; // Respond to incoming width changes. var binding = obj.bind("widthchange", function (w) { elem.value = normalize(w); }); // Send out outgoing width changes. jQuery(elem).change(function () { var n; if ((n = normalize(elem.value))) { elem.value = n; obj.change('widthchange', binding, n); } }); obj.bind('init', function () { jQuery(elem).change(); }); }); //////////////////////////////////////// // Height widget // //////////////////////////////////////// Drupal.gmap.addHandler('height', function (elem) { var obj = this; // Respond to incoming height changes. var binding = obj.bind("heightchange", function (h) { elem.value = normalize(h); }); // Send out outgoing height changes. jQuery(elem).change(function () { var n; if ((n = normalize(elem.value))) { elem.value = n; obj.change('heightchange', binding, n); } }); obj.bind('init', function () { jQuery(elem).change(); }); }); })(); // END CLOSURE //////////////////////////////////////// // Control type widget // //////////////////////////////////////// Drupal.gmap.addHandler('controltype', function (elem) { var obj = this; // Respond to incoming height changes. var binding = obj.bind("controltypechange", function () { elem.value = obj.vars.controltype; }); // Send out outgoing height changes. jQuery(elem).change(function () { obj.vars.controltype = elem.value; obj.change("controltypechange", binding); }); }); // // Map cleanup. // if (Drupal.jsEnabled) { // $(document).unload(GUnload); // } Drupal.behaviors.GMap = { attach: function (context, settings) { if (Drupal.settings && Drupal.settings['gmap_remap_widgets']) { jQuery.each(Drupal.settings['gmap_remap_widgets'], function (key, val) { jQuery('#' + key).addClass('gmap-control'); }); } jQuery('.gmap-gmap:not(.gmap-processed)', context).addClass('gmap-processed').each(function () { Drupal.gmap.setup.call(this); }); jQuery('.gmap-control:not(.gmap-processed)', context).addClass('gmap-processed').each(function () { Drupal.gmap.setup.call(this); }); }, detach: function (context, settings) { jQuery('.gmap-processed', context).each(function (element) { //find mapid var id = jQuery(this).attr('id'); var mapid = id.split('-', 2); //unload map Drupal.gmap.unloadMap(mapid[1]); }).removeClass('gmap-processed'); } }; ;