Blair Cox
Posts: 0
Joined: Thu Jun 04, 2015 2:29 pm

Google Maps multiple marker info window

So riddle me this...

How do I get the info window to populate when displaying multiple markers??? I've read and followed the tutorial, but I'm loading from a service request and the only way I've managed to get multiple markers to appear is by mapping. I'm getting the same results as many who are creating the map and markers via JavaScript.

Can you provide a clear example of how to walk through the local storage array and properly place each marker with its info window populated?? Please?

Image

Vinny B
Posts: 0
Joined: Fri Aug 22, 2014 2:22 pm

Google Maps multiple marker info window

Hello

I have been working on this for a week and no help from appery except an old post that YURI made. Thank you Yuri!!!!

Code: Select all

I hope it helps you. It populates multiple markers from localstorage and displays the title and an image or you can set the image to null and it will only show the title. I have NO IDEA how to make them work on click event. So I found this work around. 

It look like this

Image

********************************OR ********************************
******************can just do titles or different images**************
Image

**********THE CODE****

On button click event

var list_location = localStorage.getItem('mysqlFireCompaniesArray');
var obj = JSON.parse(list_location);
var coordsArray = obj;
var marker;
var image = 'files/views/assets/image/e30532.png';
var map = Appery("googlemap_6").options.mapElement.gmap('get', 'map');
for (var i = 0, j = coordsArray.length; i < j; i++) {
var marker = new MarkerWithLabel({
position: new google.maps.LatLng( coordsArray.Lat, coordsArray.Lon ),
icon: image,
labelContent: coordsArray.Engine,
map: map,
labelAnchor: new google.maps.Point(22, 0),
labelClass: "labels", // the CSS class for the label
labelStyle: {opacity: 0.75},

});

}

**************I also had to add a javascript file called markerWithLabel ******
***********************code*****************
/**

  • @name MarkerWithLabel for V3

  • @version 1.0.1 [September 17, 2010]

  • @author Gary Little (inspired by code from Marc Ridey of Google).

  • @copyright Copyright 2010 Gary Little [gary at luxcentral.com]

  • @fileoverview MarkerWithLabel extends the Google Maps JavaScript API V3

  • codegoogle&#46;maps&#46;Marker/code class.
    *

  • MarkerWithLabel allows you to define markers with associated labels. As you would expect,

  • if the marker is draggable, so too will be the label. In addition, a marker with a label

  • responds to all mouse events in the same manner as a regular marker. It also fires mouse

  • events and "property changed" events just as a regular marker would.
    */

    /*
    *

  • Licensed under the Apache License, Version 2.0 (the "License");

  • you may not use this file except in compliance with the License.

  • You may obtain a copy of the License at
    *

  • http://www.apache.org/licenses/LICENS...
    *

  • Unless required by applicable law or agreed to in writing, software

  • distributed under the License is distributed on an "AS IS" BASIS,

  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  • See the License for the specific language governing permissions and

  • limitations under the License.
    */

    /*jslint browser:true /
    /global document,google */

    /**

  • This constructor creates a label and associates it with a marker.

  • It is for the private use of the MarkerWithLabel class.

  • @constructor

  • @param {Marker} marker The marker with which the label is to be associated.

  • @private
    */
    function MarkerLabel(marker) {
    this.marker = marker;

    this.labelDiv_ = document.createElement("div");
    this.labelDiv_.style.cssText = "position: absolute; overflow: hidden;";

    // Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil
    // in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that
    // events can be captured even if the label is in the shadow of a google.maps.InfoWindow.
    // Code is included here to ensure the veil is always exactly the same size as the label.
    this.eventDiv_ = document.createElement("div");
    this.eventDiv.style.cssText = this.labelDiv.style.cssText;
    }

    // MarkerLabel_ inherits from OverlayView:
    MarkerLabel_.prototype = new google.maps.OverlayView();

    /**

  • Adds the DIV representing the label to the DOM. This method is called

  • automatically when the marker's codesetMap/code method is called.

  • @private
    */
    MarkerLabel_.prototype.onAdd = function () {
    var me = this;
    var cMouseIsDown = false;
    var cDraggingInProgress = false;
    var cSavedPosition;
    var cSavedZIndex;
    var cLatOffset, cLngOffset;
    var cIgnoreClick;

    // Stops all processing of an event.
    //
    var cAbortEvent = function (e) {
    if (e.preventDefault) {
    e.preventDefault();
    }
    e.cancelBubble = true;
    if (e.stopPropagation) {
    e.stopPropagation();
    }
    };

    this.getPanes().overlayImage.appendChild(this.labelDiv);
    this.getPanes().overlayMouseTarget.appendChild(this.eventDiv);

    this.listeners_ = [
    google.maps.event.addDomListener(document, "mouseup", function (mEvent) {
    if (cDraggingInProgress) {
    mEvent.latLng = cSavedPosition;
    cIgnoreClick = true; // Set flag to ignore the click event reported after a label drag
    google.maps.event.trigger(me.marker, "dragend", mEvent);
    }
    cMouseIsDown = false;
    google.maps.event.trigger(me.marker, "mouseup", mEvent);
    }),
    google.maps.event.addListener(me.marker.getMap(), "mousemove", function (mEvent) {
    if (cMouseIsDown && me.marker.getDraggable()) {
    // Change the reported location from the mouse position to the marker position:
    mEvent.latLng = new google.maps.LatLng(mEvent.latLng.lat() - cLatOffset, mEvent.latLng.lng() - cLngOffset);
    cSavedPosition = mEvent.latLng;
    if (cDraggingInProgress) {
    google.maps.event.trigger(me.marker, "drag", mEvent);
    } else {
    // Calculate offsets from the click point to the marker position:
    cLatOffset = mEvent.latLng.lat() - me.marker.getPosition().lat();
    cLngOffset = mEvent.latLng.lng() - me.marker.getPosition().lng();
    google.maps.event.trigger(me.marker, "dragstart", mEvent);
    }
    }
    }),
    google.maps.event.addDomListener(this.eventDiv, "mouseover", function (e) {
    me.eventDiv.style.cursor = "pointer";
    google.maps.event.trigger(me.marker, "mouseover", e);
    }),
    google.maps.event.addDomListener(this.eventDiv, "mouseout", function (e) {
    me.eventDiv.style.cursor = me.marker.getCursor();
    google.maps.event.trigger(me.marker, "mouseout", e);
    }),
    google.maps.event.addDomListener(this.eventDiv, "click", function (e) {
    if (cIgnoreClick) { // Ignore the click reported when a label drag ends
    cIgnoreClick = false;
    } else {
    cAbortEvent(e); // Prevent click from being passed on to map
    google.maps.event.trigger(me.marker, "click", e);
    }
    }),
    google.maps.event.addDomListener(this.eventDiv, "dblclick", function (e) {
    cAbortEvent(e); // Prevent map zoom when double-clicking on a label
    google.maps.event.trigger(me.marker, "dblclick", e);
    }),
    google.maps.event.addDomListener(this.eventDiv, "mousedown", function (e) {
    cMouseIsDown = true;
    cDraggingInProgress = false;
    cLatOffset = 0;
    cLngOffset = 0;
    cAbortEvent(e); // Prevent map pan when starting a drag on a label
    google.maps.event.trigger(me.marker, "mousedown", e);
    }),
    google.maps.event.addListener(this.marker, "dragstart", function (mEvent) {
    cDraggingInProgress = true;
    cSavedZIndex = me.marker.getZIndex();
    }),
    google.maps.event.addListener(this.marker, "drag", function (mEvent) {
    me.marker.setPosition(mEvent.latLng);
    me.marker.setZIndex(1000000); // Moves the marker to the foreground during a drag
    }),
    google.maps.event.addListener(this.marker, "dragend", function (mEvent) {
    cDraggingInProgress = false;
    me.marker.setZIndex(cSavedZIndex);
    }),
    google.maps.event.addListener(this.marker, "position_changed", function () {
    me.setPosition();
    }),
    google.maps.event.addListener(this.marker, "zindex_changed", function () {
    me.setZIndex();
    }),
    google.maps.event.addListener(this.marker, "visible_changed", function () {
    me.setVisible();
    }),
    google.maps.event.addListener(this.marker, "labelvisible_changed", function () {
    me.setVisible();
    }),
    google.maps.event.addListener(this.marker, "title_changed", function () {
    me.setTitle();
    }),
    google.maps.event.addListener(this.marker, "labelcontent_changed", function () {
    me.setContent();
    }),
    google.maps.event.addListener(this.marker, "labelanchor_changed", function () {
    me.setAnchor();
    }),
    google.maps.event.addListener(this.marker, "labelclass_changed", function () {
    me.setStyles();
    }),
    google.maps.event.addListener(this.marker_, "labelstyle_changed", function () {
    me.setStyles();
    })
    ];
    };

    /**

  • Removes the DIV for the label from the DOM. It also removes all event handlers.

  • This method is called automatically when the marker's codesetMap(null)/code

  • method is called.

  • @private
    */
    MarkerLabel.prototype.onRemove = function () {
    var i;
    this.labelDiv.parentNode.removeChild(this.labelDiv);
    this.eventDiv.parentNode.removeChild(this.eventDiv_);

    // Remove event listeners:
    for (i = 0; i < this.listeners.length; i++) {
    google.maps.event.removeListener(this.listeners);
    }
    };

    /**

  • Draws the label on the map.

  • @private
    */
    MarkerLabel_.prototype.draw = function () {
    this.setContent();
    this.setTitle();
    this.setStyles();
    };

    /**

  • Sets the content of the label.

  • The content can be plain text or an HTML DOM node.

  • @private
    */
    MarkerLabel.prototype.setContent = function () {
    var content = this.marker.get("labelContent");
    if (typeof content.nodeType === "undefined") {
    this.labelDiv.innerHTML = content;
    this.eventDiv.innerHTML = this.labelDiv.innerHTML;
    } else {
    this.labelDiv.appendChild(content);
    content = content.cloneNode(true);
    this.eventDiv_.appendChild(content);
    }
    };

    /**

  • Sets the content of the tool tip for the label. It is

  • always set to be the same as for the marker itself.

  • @private
    */
    MarkerLabel.prototype.setTitle = function () {
    this.eventDiv.title = this.marker_.getTitle() || "";
    };

    /**

  • Sets the style of the label by setting the style sheet and applying

  • other specific styles requested.

  • @private
    */
    MarkerLabel_.prototype.setStyles = function () {
    var i, labelStyle;

    // Apply style values from the style sheet defined in the labelClass parameter:
    this.labelDiv.className = this.marker.get("labelClass");
    this.eventDiv.className = this.labelDiv.className;

    // Clear existing inline style values:
    this.labelDiv.style.cssText = "";
    this.eventDiv.style.cssText = "";
    // Apply style values defined in the labelStyle parameter:
    labelStyle = this.marker.get("labelStyle");
    for (i in labelStyle) {
    if (labelStyle.hasOwnProperty(i)) {
    this.labelDiv.style = labelStyle;
    this.eventDiv_.style = labelStyle;
    }
    }
    this.setMandatoryStyles();
    };

    /**

  • Sets the mandatory styles to the DIV representing the label as well as to the

  • associated event DIV. This includes setting the DIV position, zIndex, and visibility.

  • @private
    */
    MarkerLabel.prototype.setMandatoryStyles = function () {
    this.labelDiv.style.position = "absolute";
    this.labelDiv.style.overflow = "hidden";
    // Make sure the opacity setting causes the desired effect on MSIE:
    if (typeof this.labelDiv.style.opacity !== "undefined") {
    this.labelDiv.style.filter = "alpha(opacity=" + (this.labelDiv.style.opacity * 100) + ")";
    }

    this.eventDiv.style.position = this.labelDiv.style.position;
    this.eventDiv.style.overflow = this.labelDiv.style.overflow;
    this.eventDiv.style.opacity = 0.01; // Don't use 0; DIV won't be clickable on MSIE
    this.eventDiv.style.filter = "alpha(opacity=1)"; // For MSIE

    this.setAnchor();
    this.setPosition(); // This also updates zIndex, if necessary.
    this.setVisible();
    };

    /**

  • Sets the anchor point of the label.

  • @private
    */
    MarkerLabel.prototype.setAnchor = function () {
    var anchor = this.marker.get("labelAnchor");
    this.labelDiv.style.marginLeft = -anchor.x + "px";
    this.labelDiv.style.marginTop = -anchor.y + "px";
    this.eventDiv.style.marginLeft = -anchor.x + "px";
    this.eventDiv.style.marginTop = -anchor.y + "px";
    };

    /**

  • Sets the position of the label. The zIndex is also updated, if necessary.

  • @private
    */
    MarkerLabel.prototype.setPosition = function () {
    var position = this.getProjection().fromLatLngToDivPixel(this.marker.getPosition());

    this.labelDiv.style.left = position.x + "px";
    this.labelDiv.style.top = position.y + "px";
    this.eventDiv.style.left = this.labelDiv.style.left;
    this.eventDiv.style.top = this.labelDiv.style.top;

    this.setZIndex();
    };

    /**

  • Sets the zIndex of the label. If the marker's zIndex property has not been defined, the zIndex

  • of the label is set to the vertical coordinate of the label. This is in keeping with the default

  • stacking order for Google Maps: markers to the south are in front of markers to the north.

  • @private
    */
    MarkerLabel.prototype.setZIndex = function () {
    var zAdjust = (this.marker.get("labelInBackground") ? -1 : +1);
    if (typeof this.marker.getZIndex() === "undefined") {
    this.labelDiv.style.zIndex = parseInt(this.labelDiv.style.top, 10) + zAdjust;
    this.eventDiv.style.zIndex = this.labelDiv.style.zIndex;
    } else {
    this.labelDiv.style.zIndex = this.marker.getZIndex() + zAdjust;
    this.eventDiv.style.zIndex = this.labelDiv_.style.zIndex;
    }
    };

    /**

  • Sets the visibility of the label. The label is visible only if the marker itself is

  • visible (i.e., its visible property is true) and the labelVisible property is true.

  • @private
    */
    MarkerLabel.prototype.setVisible = function () {
    if (this.marker.get("labelVisible")) {
    this.labelDiv.style.display = this.marker.getVisible() ? "block" : "none";
    } else {
    this.labelDiv.style.display = "none";
    }
    this.eventDiv.style.display = this.labelDiv_.style.display;
    };

    /**

  • @name MarkerWithLabelOptions

  • @class This class represents the optional parameter passed to the {@link MarkerWithLabel} constructor.

  • The properties available are the same as for codegoogle&#46;maps&#46;Marker/code with the addition

  • of the properties listed below. To change any of these additional properties after the labeled

  • marker has been created, call codegoogle&#46;maps&#46;Marker&#46;set(propertyName, propertyValue)/code.
    *

  • When any of these properties changes, a property changed event is fired. The names of these

  • events are derived from the name of the property and are of the form codepropertyname_changed/code.

  • For example, if the content of the label changes, a codelabelcontent_changed/code event

  • is fired.
    *

  • @property {string|Node} [labelContent] The content of the label (plain text or an HTML DOM node).

  • @property {Point} [labelAnchor] By default, a label is drawn with its anchor point at (0,0) so

  • that its top left corner is positioned at the anchor point of the associated marker. Use this

  • property to change the anchor point of the label. For example, to center a 50px-wide label

  • beneath a marker, specify a codelabelAnchor/code of codegoogle&#46;maps&#46;Point(25, 0)/code.

  • (Note: x-values increase to the right and y-values increase to the bottom.)

  • @property {string} [labelClass] The name of the CSS class defining the styles for the label.

  • Note that style values for codeposition/code, codeoverflow/code, codetop/code,

  • codeleft/code, codezIndex/code, codedisplay/code, codemarginLeft/code, and

  • codemarginTop/code are ignored; these styles are for internal use only.

  • @property {Object} [labelStyle] An object literal whose properties define specific CSS

  • style values to be applied to the label. Style values defined here override those that may

  • be defined in the codelabelClass/code style sheet. If this property is changed after the

  • label has been created, all previously set styles (except those defined in the style sheet)

  • are removed from the label before the new style values are applied.

  • Note that style values for codeposition/code, codeoverflow/code, codetop/code,

  • codeleft/code, codezIndex/code, codedisplay/code, codemarginLeft/code, and

  • codemarginTop/code are ignored; these styles are for internal use only.

  • @property {boolean} [labelInBackground] A flag indicating whether a label that overlaps its

  • associated marker should appear in the background (i.e., in a plane below the marker).

  • The default is codefalse/code, which causes the label to appear in the foreground.

  • @property {boolean} [labelVisible] A flag indicating whether the label is to be visible.

  • The default is codetrue/code. Note that even if codelabelVisible/code is

  • codetrue/code, the label will not be visible unless the associated marker is also

  • visible (i.e., unless the marker's codevisible/code property is codetrue/code).
    */
    /**

  • Creates a MarkerWithLabel with the options specified in {@link MarkerWithLabelOptions}.

  • @constructor

  • @param {MarkerWithLabelOptions} [opt_options] The optional parameters.
    */
    function MarkerWithLabel(opt_options) {
    opt_options = opt_options {};
    opt_options.labelContent = opt_options.labelContent "";
    opt_options.labelAnchor = opt_options.labelAnchor new google.maps.Point(0, 0);
    opt_options.labelClass = opt_options.labelClass "markerLabels";
    opt_options.labelStyle = opt_options.labelStyle {};
    opt_options.labelInBackground = opt_options.labelInBackground false;
    if (typeof opt_options.labelVisible === "undefined") {
    opt_options.labelVisible = true;
    }

    this.label = new MarkerLabel_(this); // Bind the label to the marker

    // Call the parent constructor. It calls Marker.setValues to initialize, so all
    // the new parameters are conveniently saved and can be accessed with get/set.
    // Marker.set triggers a property changed event (called "propertyname_changed")
    // that the marker label listens for in order to react to state changes.
    google.maps.Marker.apply(this, arguments);
    }

    // MarkerWithLabel inherits from codeMarker/code:
    MarkerWithLabel.prototype = new google.maps.Marker();

    MarkerWithLabel.prototype.setMap = function (theMap) {
    // Call the inherited function...
    google.maps.Marker.prototype.setMap.apply(this, arguments);

    // ... then deal with the label:
    this.label.setMap(theMap);
    };

    **************I do load geolaction on PAGE LOAD with NO MAPPING*****
    There is no mapping on the page******************

    ****There is also a CSS i had to add to adjust the title color soze and font*

    /*Google Labels */
    .labels {
    color: white;
    background-color: red;
    font-family: "Lucida Grande", "Arial", sans-serif;
    font-size: 10px;
    text-align: center;
    width: 60px;
    white-space: nowrap;
    }


Blair Cox
Posts: 0
Joined: Thu Jun 04, 2015 2:29 pm

Google Maps multiple marker info window

Wow! Thanks Vinny! It's a better start than what I've had. I'll work away at this during the week and let you know how I make out!

I'm sure many others will find this useful as well - thanks for sharing!!! :D

Blair

Vinny B
Posts: 0
Joined: Fri Aug 22, 2014 2:22 pm

Google Maps multiple marker info window

I was able to put a break in and get multiple lines from multiple columns in a row to the title. For example column ENGINE and column Ladder map to one title tag.

labelContent: coordsArray.Engine + "" + coordsArray.Ladder,

Blair Cox
Posts: 0
Joined: Thu Jun 04, 2015 2:29 pm

Google Maps multiple marker info window

Vinny - could you describe your model please? I just want to understand better how I can apply this to my model. I'm storing an array to localstorage. Within that I have two columns (lat, lng) that I need to pull out for each entry and apply to the map. Thanks!

var list_location = localStorage.getItem('mysqlFireCompaniesArray');
var obj = JSON.parse(list_location);
var coordsArray = obj;
var marker;
var image = 'files/views/assets/image/e30532.png';
var map = Appery("googlemap_6").options.mapElement.gmap('get', 'map');
for (var i = 0, j = coordsArray.length; i < j; i++) {
var marker = new MarkerWithLabel({
position: new google.maps.LatLng( coordsArray.Lat, coordsArray.Lon ),
icon: image,
labelContent: coordsArray.Engine,
map: map,
labelAnchor: new google.maps.Point(22, 0),
labelClass: "labels", // the CSS class for the label
labelStyle: {opacity: 0.75},

Vinny B
Posts: 0
Joined: Fri Aug 22, 2014 2:22 pm

Google Maps multiple marker info window

There is no mapping so in order to get the array from local storage u need that code. I'm far from a coder.

Blair Cox
Posts: 0
Joined: Thu Jun 04, 2015 2:29 pm

Google Maps multiple marker info window

ha!! Got it working :) You are the man!! thanks!

Blair Cox
Posts: 0
Joined: Thu Jun 04, 2015 2:29 pm

Google Maps multiple marker info window

hehehe, well kinda...

Got the custom icon to show... but no label or infobox yet...

Blair Cox
Posts: 0
Joined: Thu Jun 04, 2015 2:29 pm

Google Maps multiple marker info window

Can you share the CSS you got working with yours? Just wondering if you used fixed widths (px) or variable (%)?

Any idea how to make the markers clickable? This gets me a LOT closer to figuring out the other stuff, but just wondering if you got there already?

Vinny B
Posts: 0
Joined: Fri Aug 22, 2014 2:22 pm

Google Maps multiple marker info window

This is my CSS

/*Google Labels */
.labels {
color: white;
background-color: red;
font-family: "Lucida Grande", "Arial", sans-serif;
font-size: 10px;
text-align: center;
width: 60px;
white-space: nowrap;
}

Return to “Issues”