Gmaps4rails - How to call infowindow marker outside from maps - ruby-on-rails

I have used gmaps4rails before with success but this time i have a need that i cant figure out how to do it.
I have my builder working and generating my map_info partials, also, i am able to open every infowindow from markers by clicking inside the map.
What i need is to call the infowindow of a marker from a list. (onclick event inside a div for instance)
builder inside controller
#gmaps_markers = Gmaps4rails.build_markers(#partners) do |partner, marker|
marker.lat partner.latitude
marker.lng partner.longitude
marker.title partner.company
marker.json({:id => partner.id })
marker.infowindow render_to_string(partial: 'pages/partials/subscribe/map_info', locals: { partner: partner })
end
javascript markers + maps generator
handler = Gmaps.build('Google', {
markers: {
clusterer: {
gridSize: 10,
maxZoom: 15
}
}
});
handler.buildMap({
provider: {
disableDefaultUI: false
},
internal: {
id: 'gmaps'
}
},
function() {
markers = handler.addMarkers(#{
raw #gmaps_markers.to_json
});
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
handler.getMap().setZoom(8);
handler.map.centerOn;
}
);
Let me know if you need more details!
Thanks

The easiest option is to trigger the click event on the marker:
function openMarkerInfo(id) {
$.each(markers, function(index, marker) {
if (marker.id == id) {
google.maps.event.trigger(marker.getServiceObject(), 'click')
}
});
};
See working plunk here

You need to add id to marker
Change your map and markers generation js to
Gmaps.store = {}
handler = Gmaps.build('Google', {
markers: {
clusterer: {
gridSize: 10,
maxZoom: 15
}
}
});
handler.buildMap({
provider: {
disableDefaultUI: false
},
internal: {
id: 'gmaps'
}
},
function() {
Gmaps.store.markers = handler.addMarkers(#{
raw #gmaps_markers.to_json
});
handler.bounds.extendWith(Gmaps.store.markers);
handler.fitMapToBounds();
handler.getMap().setZoom(8);
handler.map.centerOn;
});
Then write js function
Gmaps.openMarkerInfo = function(id) {
$.each(Gmaps.store.markers, function() {
if (this.serviceObject.id == id) {
var infowindow = this.infowindow;
infowindow.open(Gmaps.map.map, marker.serviceObject);
}
});
}
Then add it to onclick of your list element
Gmaps.openMarkerInfo(1);

i found a solution. Take a look...
Javascript onclick function
openInfoWindow = function(id) {
$.each(Gmaps.store.markers, function() {
if (this.serviceObject.id == id) {
google.maps.event.trigger(this.getServiceObject(), 'click')
}
});
}
Javascript maps + markers generator
Gmaps.store = {}
Gmaps.store.handler = Gmaps.build('Google',
{
markers: {
clusterer: {
gridSize: 10, maxZoom:15
}
}
});
Gmaps.store.handler.buildMap({
provider: {
disableDefaultUI: false
},
internal: {
id: 'gmaps'
}
},
function(){
markers = #{raw #gmaps_markers.to_json};
Gmaps.store.markers = markers.map(function(m) {
marker = Gmaps.store.handler.addMarker(m);
marker.serviceObject.set('id', m.id);
return marker;
});
Gmaps.store.handler.bounds.extendWith(Gmaps.store.markers);
Gmaps.store.handler.fitMapToBounds();
}
);
And then, call onclick event.
openInfoWindow(id);
Working and no bugs so far...
:)

Related

gmap3 mouseover not working for infowindow

I tried following https://v6.gmap3.net/en/catalog/10-overlays/marker-41 but infowindow not working how should i do
$('.map-object').gmap3({
map: {
options: {
center:[46.578498,2.457275],
zoom: 5
}
},
marker:{
values:[
{latLng:[48.8620722, 2.352047], data:"Paris !"},
],
options:{
draggable: false
},
events:{
mouseover: function(marker, event, context){
var map = $(this).gmap3("get"),
infowindow = $(this).gmap3({get:{name:"infowindow"}});
if (infowindow){
infowindow.open(map, marker);
infowindow.setContent(context.data);
} else {
$(this).gmap3({
infowindow:{
anchor:marker,
options:{content: context.data}
}
});
}
},
mouseout: function(){
var infowindow = $(this).gmap3({get:{name:"infowindow"}});
if (infowindow){
infowindow.close();
}
}
}
}
});
There is a marker in France but the infowindow does not come out when I hover over it.
Thanks for the help.

when mouseover or out change icon marker

What i want is when user do mouseover (hover) then the icon change. My code is below:
handler = Gmaps.build("Google", {
markers: {
maxRandomDistance: null
}
});
handler.buildMap({
provider: {},
internal: {
id: "map-canvas"
}
}, function() {
var markers;
markers = handler.addMarkers(ar);
_.each(ar, function(json, index) {
json.marker = markers[index];
$(".location-" + json.id).on("mouseover", function() {
json.picture = {
url: "http://maps.google.com/mapfiles/ms/icons/green-dot.png",
width: 36,
height: 36
};
json.marker.setMap(handler.getMap());
json.marker.panTo();
handler.removeMarker(json.marker);
handler.addMarker(json);
}).on("mouseout", function() {
json.picture = '';
handler.removeMarker(json.marker);
handler.addMarker(json);
});
});
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
Using this code, the color of the marker can change from red to green. However, when the user remove their mouse from the hover area, the color does not change back to the original color. Please can anyone suggest me on this issue?
Thanks
Hai thank for #apneadiving answer. I modify my code to this
hoverPicture = {
url: "http://maps.google.com/mapfiles/ms/icons/green-dot.png",
width: 33,
height: 33
};
handler = Gmaps.build("Google", {
markers: {
maxRandomDistance: null
}
});
handler.buildMap({
provider: {},
internal: {
id: "map-canvas"
}
}, function() {
var markers;
markers = handler.addMarkers(ar);
_.each(ar, function(json, index) {
var gr;
json.marker = markers[index];
gr = {};
gr.marker = void 0;
$(".location-" + json.id).on("mouseover", function() {
gr = {
lat: json.lat,
lng: json.lng,
picture: hoverPicture
};
json.marker.panTo();
handler.removeMarker(json.marker);
gr.marker = handler.addMarker(gr);
}).on("mouseout", function() {
handler.removeMarker(gr.marker);
json.marker = handler.addMarker(json);
});
});
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
So the new icon need to insert to variable after addMarker
Try something like:
_.each(ar, function(json, index) {
var json.marker = markers[index];
var initialPicture = json.picture;
var hoverPicture = {
url: "http://maps.google.com/mapfiles/ms/icons/green-dot.png",
width: 36,
height: 36
}
$(".location-" + json.id).on("mouseover", function() {
json.picture = hoverPicture;
json.marker.setMap(handler.getMap());
json.marker.panTo();
handler.removeMarker(json.marker);
handler.addMarker(json);
}).on("mouseout", function() {
json.picture = initialPicture;
handler.removeMarker(json.marker);
var newMarker = handler.addMarker(json);
json.marker = newMarker;
});
});

get instance of map in jquery ui map

i want to make the markers clustered with markerClusterer but i cannot get the map instance with jquery ui map . js
tried:
var map = $('#map_canvas').gmap('getMap');
or
var map = $('map_canvas').gmap('get', 'map');
and after:
var markerCluster = new MarkerClusterer(map, allMarkers);
but with errors
Thank you
Tried this . No Errors but no clusters...
$('#map_canvas').gmap({ 'callback': function () {
var self = this;
$.getJSON('Data/markers.json', function (data) {
$.each(data.markers, function (i, marker) {
self.addMarker({ 'position': new google.maps.LatLng(marker.latitude,marker.longitude)}).click(function () {
$.ajax({
type: "GET",
url: "/LocoMap/LocoMap/InfoMobilePartialView/",
data: { latitude: marker.latitude, longitude: marker.longitude},
success: function (data) {
$("#marker-info").remove();
$(document.body).append("<div id='marker-info' data-role ='page'> </div>");
var $contentDiv = $("#marker-info");
$contentDiv.html(data).trigger('create');
$.mobile.changePage("#marker-info", { changeHash: false, type: "get", transition: 'pop',rel:"external" });
},
error: function (errorData) { onError(errorData); }
});
});
});
});
self.set('MarkerClusterer', new MarkerClusterer(this.get('map'), this.get('markers')));
}});
$('#map_canvas').gmap({'zoom': 2, 'disableDefaultUI':true}).bind('init', function(evt, map) {
$.getJSON( 'Data/markers.json', function(data) {
$.each( data.markers, function(i, m)
$('#map_canvas').gmap('addMarker', { 'position': new google.maps.LatLng(m.latitude, m.longitude), 'bounds':true } );
});
});
$('#map_canvas').gmap('set', 'MarkerClusterer', new MarkerClusterer(map,$(this).gmap('get', 'markers')));
});
with no errors and no clusters
it seems **$(this).gmap('get', 'markers')));** returns Array[0]

Change zIndex in HighChart

using Highchart, how can we change the zIndex for a line according to its state, or dynamically from a click event ?
I tried :
plotOptions: {
series: {
states: {
select: {
lineWidth: 2,
zIndex:10
}
},
with : this.setState(this.state === 'select' ? '' : 'select'); in the Click event but it doesn't work.
Alright, it's definitely not pretty, but I couldn't find a way to actually set the zIndex, so I had to do some maneuvering to fake it and bring each series to the front in a certain order. Here's the snippet to include:
Highcharts.Series.prototype.setState = (function (func) {
return function () {
if (arguments.length>0){
if (arguments[0] !== ''){
if (typeof this.options.states[arguments[0]]['zIndex'] !== 'undefined'){
this.options.oldZIndex = this.group.zIndex;
this.group.zIndex = this.options.states[arguments[0]]['zIndex'];
}
}else{
if (typeof this.options['oldZIndex'] !== "undefined"){
this.group.zIndex = this.options['oldZIndex'];
}
}
var order = [], i = 0;
$.each(this.chart.series, function(){
order.push({id:i,zIndex:this.group.zIndex,me:this});
i++;
});
order.sort(function(a,b){return (a.zIndex>b.zIndex) ? 1 : -1;});
$.each(order, function(){
this.me.group.toFront();
});
func.apply(this, arguments);
}
};
} (Highcharts.Series.prototype.setState));
And here's the JSFiddle demonstrating:
http://jsfiddle.net/G9d9H/9/
Let me know if that's what you needed.
I think a better solution is to set the series.group.toFront() method on click (I prefer to use it on mouseover)
plotOptions: {
series: {
events: {
click: function () {
this.group.toFront();//bring series to front when hovered over
}
}
}
}

Linked jQuery sortable lists and Backbone collections

I'm still finding my way with Backbone and I've always use Prototype instead of jQuery in the past so please forgive me if I'm doing something stupid.
I'm trying to develop a UI containing several connected unordered lists where each sortable list is represented by a separate Backbone collection. I'm using ICanHaz and Mustache templates but that's not of importance for my question.
When dragging items between the lists, how would I best achieve the automatic updating of the collections (remove a model from one and insert it into another)? I'm currently trying to use the receive and remove methods in the jQueryUI Sortable interaction — am I at least on the right lines?
var WS = {};
(function(ns) {
ns.Item = Backbone.Model.extend();
ns.Content = Backbone.Collection.extend({
model: ns.Item,
url: location.href,
initialize: function(el) {
this.el = $(el);
this.deferred = this.fetch();
},
recalculate: function() {
var count = this.length;
this.el.next(".subtotal").html(count);
},
setOrder: function() {
$.ajax({
url: this.url + "/reorder",
type: "POST",
data: "tasks=" + $(this.el).attr("id") + "&" + this.el.sortable("serialize")
});
}
});
ns.ContentRow = Backbone.View.extend({
tagName: "li",
className: "item",
events: {
"click .delete": "destroy"
},
initialize: function(options) {
_.bindAll(this, "render", "destroy");
this.model.bind("change", this.render);
this.model.view = this;
},
render: function() {
var row = ich.item(this.model.toJSON());
$(this.el).html(row);
return this;
},
destroy: function() {
if (confirm("Really delete?")) {
this.model.destroy({
success: function(model, response) {
$(model.view.el).remove();
},
error: function(model, response) {
console.log(response);
}
});
}
}
});
ns.ListView = Backbone.View.extend({
initialize: function(collection) {
this.el = collection.el;
this.collection = collection;
this.collection.bind("add", this.addOne, this);
_.bindAll(this, "addOne");
this.el.sortable({
axis: "y",
connectWith: ".tasks",
receive: _.bind(function(event, ui) {
// do something here?
}, this),
remove: _.bind(function(event, ui) {
// do something here?
}, this),
update: _.bind(function(event, ui) {
var list = ui.item.context.parentNode;
this.collection.setOrder();
}, this)
});
},
insert: function(item) {
var prefix = this.el.parentsUntil('ul').parent().attr("id"),
view = new ns.ContentRow({
model: item,
id: prefix + "_" + item.id
});
this.el.append(view.render().el);
},
addOne: function(item) {
if (item.isNew()) {
item.save({}, {
success: _.bind(function(model, response) {
// I should set id from JSON response when live
model.set({ id: this.collection.length });
this.insert(model);
}, this)
});
} else {
this.insert(item);
}
},
addAll: function() {
this.collection.each(this.addOne);
},
render: function() {
this.collection.deferred.done(_.bind(function() {
this.addAll();
}, this));
}
});
ns.AppView = Backbone.View.extend({
lists: [],
initialize: function(holder) {
holder.find("ul").each(_.bind(function(index, list) {
var Items = new WS.Content(list),
App = new WS.ListView(Items);
App.render();
this.lists.push(Items);
}, this));
}
});
})(WS);
$(document).ready(function() {
var App = new WS.AppView($("#tasks"));
});
You are on the right track. You will probably want to add the id of each sortable element into the template somewhere. Then when you receive the event, you know which model to add or remove from the collection. For example add...
<div data-id={{id}}> ... my thing ... </div>
And in the sortable call get the target's id attribute and call Collection.add() or remove()
Just use Backbone.CollectionView.. it has this functionality built in out of the box.
var listView = new Backbone.CollectionView( {
el : $( "#list1" ),
sortable : true,
sortableOptions : {
connectWith : "#list2"
},
collection : new Backbone.Collection
} );
var listView = new Backbone.CollectionView( {
el: $( "#list2" ),
sortable : true,
sortableOptions : {
connectWith : "#list1"
},
collection : new Backbone.Collection
} );

Resources