onclick in InfoWindow content - javascript

I got a little problem in my code, I try to launch a function in the content of a InfoWindow in javascript, and, I don't know why, I got difficulties to do that. I've looked at a lot of topics about it on stackoverflow and elsewhere, applied exactly what I've seen on these topics but...
Note: this is a part of my entire code, this is why "infobulle" doesn't seem to be declared.
In the same way, "this.jsonActivity" and "mapView" are correctly initialized before this part of code.
Here, "newActivity" in parameter is a Marker from the google maps API, and what I'm trying to do is to display an InfoWindow next to the current marker when we click on it. Everything's ok, the entire text is correctly displayed in the InfoWindow but the problem is that I can't call the "alertMessage()" method when I click on the button, nothing happens... and I really don't know why !!
Well, here's my code, thank you for your help :)
google.maps.event.addListener(newActivity, "click", function() {
if(infobulle)
infobulle.close();
var contenu = '<strong>' + this.jsonActivity.title + '</strong><br/>' +
this.jsonActivity.description + '<br/>' +
'<h3>Routing:</h3>' +
'<button onclick="alertMessage()">Click me</button>';
infobulle = new google.maps.InfoWindow({
content: contenu,
maxWidth: 120
});
infobulle.open(mapView, this);
function alertMessage() {
alert("alertMessage");
}
});
EDIT:
this is perfect, it's working now!
I've tried all of your solutions and only one is working for me, the one that declares the function as global, thanks to Dr.Molle!
Now I put what I've tried for the two other solutions:
google.maps.event.addListener(newActivity, "click", function() {
if(infobulle)
infobulle.close();
var contenu = '<strong>' + this.jsonActivity.title + '</strong><br/>' +
this.jsonActivity.description + '<br/>' +
'<h3>Routing:</h3>' +
'<button id="myAlert">Click me</button>';
infobulle = new google.maps.InfoWindow({
content: contenu,
maxWidth: 120
});
infobulle.open(mapView, this);
document.getElementById("myAlert").addEventListener(function() {
alert("something");
});
});
For the solution suggested by Jared Smith. It's like before, everything is correctly displayed except for the button when I click on it, nothing happens.
And for the solution suggested by Alexander:
google.maps.event.addListener(newActivity, "click", function() {
if(infobulle)
infobulle.close();
var contenu = '<strong>' + this.jsonActivity.title + '</strong><br/>' +
this.jsonActivity.description + '<br/>' +
'<h3>Routing:</h3>' +
'<button onclick="(function() {
alert(\"something\");
})();">Click me</button>';
infobulle = new google.maps.InfoWindow({
content: contenu,
maxWidth: 120
});
infobulle.open(mapView, this);
});
and this time, even the elements where I'm supposed to click the button don't appear...
Well for these two solutions, maybe I don't have used them correctly... so if you find something to say, please go ahead :)
EDIT(2):
Okay now I've got an other question: if I want to put a variable as parameter of the function, how am I supposed to do this? Just typing the name of the variable as parameter does not working.
I've tried:
var contenu = '<strong>' + this.jsonActivity.title + '</strong><br/>' +
this.jsonActivity.description + '<br/>' +
'<h3>Routing:</h3>' +
'<button onclick="alertMessage(\'something\')">Click me</button>';
window.alertMessage = function(thing) {
alert(thing);
};
which is working because I put directly the string as parameters.
But if I declare:
var text = "something";
var contenu = '<strong>' + this.jsonActivity.title + '</strong><br/>' +
this.jsonActivity.description + '<br/>' +
'<h3>Routing:</h3>' +
'<button onclick="alertMessage(text)">Click me</button>';
window.alertMessage = function(thing) {
alert(thing);
};
It's not working anymore, do you know how to fix this?

make the function global accessible(currently it isn't):
window.alertMessage=function() {
alert("alertMessage");
}

Instead of
"<button onclick='blah'>"
You need
"<button id='myAlertButton'>"
Then in your eventListener callback after the infoWindow is added to the DOM
document.getElementById('myAlertButton').addEventListener(function(){
alert('Whatever');
});

The InfoWindow accepts an HTMLElement node as its content option. So you can build your HTML via JS and add the event JS-land, e.g.:
// Create Nodes
const ul = document.createElement('ul');
const setOrigin = document.createElement('li');
// Set hierarchy
ul.appendChild(setOrigin);
setOrigin.appendChild(document.createTextNode('Set Origin'));
// Add event listener
setOrigin.addEventListener('click', () => console.log('Set origin and so on…'));
// Set root node as content
const contextMenu = new google.maps.InfoWindow({
content: ul,
});

Related

JQuery / Javascript Click Event not detected in Dynamic table

I have looked through several answered questions, and tried to implement the solutions for my issue. I have a table being generated dynamically in javascript, that I then need a click event on in one column for each row.
I have tried the following:
$("#iFaceTbl tr").on('click', 'td.delInt', function(event) {
console.log("Clicked.");
let intId = event.target.id;
console.log("ID was: " + intId);
});
Wehre delInt is a class on the cell in each row.
When I run it, and watch the console, no click event is detected at all.
I'm sure I've done something wrong. For reference, here is the html, and javascript forming the table.
<table id="iFaceTbl"></table>
and
for (i=0; i < iFaces_count; i++) {
let html_to_insert = '<tr><td>' + intArray[i] + '</td><td id="' + intArray[i] +'" class="delInt"><i class="fa fa-trash delInt" aria-hidden="true"></span></td></tr>';
Currenthtml = Currenthtml + html_to_insert;
if (i == iFaces_count-1) {
iFaceTbl.innerHTML = Currenthtml;
}
}
Any help is greatly appreciated.
Was able to solve my issue with the change shown here to my event trigger. I had to remove the icon portion in favor of a 'X'. Code now looks like this:
$(document).on('click', '#iFaceTbl td', function(event) {
console.log("Clicked.");
let intId = event.target.id;
console.log("ID was: " + intId);
});

Dynamic click event issue

I have a table being loaded from a JSON array, but my click event solution does not seem to work. As the loop is cycled through, I add a click event to each listener to each of the new added divs.
document.getElementById(i.toString()).addEventListener("click", function(event)
{
console.log(event);
});
The issue is only the last element responds to the clicks.
My code is available on pastebin
This is happening because of the way you are currently trying to add new elements to your html.
Replace this (what you are currently doing):
nw.innerHTML = nw.innerHTML + "<div class='" + nodeType + "' id='" + i + "'><div class='nodeName'>" + json[i][0] + "</div></div>";
With this:
var div = document.createElement("div");
div.setAttribute("class", nodeType);
div.setAttribute("id", i.toString());
div.innerHTML = '<div class="nodeName">' + json[i][0] + '</div>';
nw.appendChild(div);
Here's a fiddle that shows a simpler version of this working.
In my opinion,
nw.innerHTML = nw.innerHTML + "<div class='" + nodeType + "' id='" + i + "'><div class='nodeName'>" + json[i][0] + "</div></div>";
this code override previous nw's elements and their event listeners too.
Therefore, instead of using innerHTML, try to use document.createElement("div") and append it to nw using appendChild(). It works in my test.

Placing quotes in JS parameters

I am dynamically populating an unordered list with JS for my mobile app. I am using JQuery mobile and Phonegap for developing.
In my list I want to call a function with parameters when clicked. I am able to call the function downloadPdf() without using any parameters, but not if I add them. I think it has something to do with quotes/double qoutes.
var $li = $("<li><a href='#' onclick='downloadPdf('"+val.title+"', '"+val.url+"')'>"+val.title+"</a></li>");
I am not able to debug as I am running this on my phone, so I hope someone with a more trained eye is able to see what's wrong here. Both val.title and val.url holds values of string type.
Do not use inline events. You are using jQuery, it makes it easy to attach events
var li = $("<li><a href='#'>"+val.title+"</a></li>");
li.find("a").on("click", function(){ downloadPdf(val.title,val.url); });
or use Data Attributes and a generic onclick handler
var li = $("<li><a class='download' href='#'>"+val.title+"</a></li>");
li.find("a").data("title", val.title).data("url", val.url);
and the generic click
$(document).on("click", "a.download", function (event) {
var anc = $(this);
downloadPdf( anc.data("title"), anc.data("url"));
event.preventDefault();
}
#epascarello is right, do not use inline event handlers.
But answering directly on the question just escape double quotes:
$("<li><a href='#' onclick='downloadPdf(\""+val.title+"\", \""+val.url+"\")'>"+val.title+"</a></li>");
Produces:
<li><a href='#' onclick='downloadPdf("value1", "value2")'>title</a></li>
Escape your quotes
var val = {title: 'foo', url: 'http://foo'}
var $li = $('<li>' + val.title + '</li>');
function downloadPdf() {
alert('params:' + JSON.stringify(arguments, null, 2));
}
$('body').append($li);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
or for better practice use click event handlers as #epascarello suggested.
Solution
First I advice putting the code in multiple lines just to ease reading.
var $li = $(''
+ '<li>'
+ '<a href="#" onclick="downloadPdf(\"' + val.title + '\", \"' + val.url + '\")">' + val.title
+ '</a>'
+ '</li>');
I specially do this for this awful templates.
Second you need to escape the quotes using \" or \'
Real advice
pay some attention to what epascarello is saying there. His way is way better and easy to understand, than the escaping mess in a single line.

Calling Jquery accordion on google maps only runs once

So I've created a google maps page with a bunch of markers generated from XML. The idea is that when you click on a marker a div will be generated that displays events information related to that marker. This all works fine but what I'm struggling with is now trying to attach an accordion to the events information. The code I have so far will show an accordion on the first marker you click on (can be any one and it returns the correct info, shows the div and has an accordion) but not on any subsequent marker clicks, even the same one for a second click.
I'm sure this must be a simple fix but I've tried a few variations (there are three attempts at the accordion that I have left in to show the different versions) and I am getting the same results.
Here is the code that binds the events to the markers as a google event listener..
function bindEvents(marker, id, venueName, website){
google.maps.event.addListener(marker, 'click', function(){
// TARGET and show eventsFeed on click
$('#eventsFeed').show(222);
var eventsList = document.getElementById('eventsList');
// ADDS styles to the events feed divs when created
// DECLARED here for the inclusion of the venueName & website as feedhead
// even when no events are present
var venueNameDiv = "<div class='venueNameFeed'>";
var webSiteDiv = "<a target='_blank' class='websiteInFeed' href='http://"+website+"'><span class='fa fa-home'></span></a>";
var titleInFeed = "<div class='"+id+" eventTitleFeed'>";
var accordDataWrap = "<h2 class='accordWrap>";
var eventInFeed = "<div class='eventDescFeed'>";
var dateInFeed = '<div class="eventDateFeed">';
var priceInFeed = "<div class='eventPriceFeed'>";
// CLOSE the divs after each entry
var divBrk = "</div>";
var closeAccordDataWrap = "</h2>";
var feedHead = venueNameDiv + venueName + divBrk;
// EMPTY array to line up matched events in
var eventsLine = [];
// CYCLE through eventsArray
for (var key in eventsArray){
var eventLoop = eventsArray[key];
// MATCH id to venue_id
var venue_id = eventLoop.venue_id;
if (venue_id == id){
// ONLY show events from todays date onward
var now = new Date();
var date = new Date(eventLoop.eventDATE);
// SET hours to 0 to ignore time part (always as 01:00:00 for event date?)
now.setHours(0,0,0,0);
if (date >= now){
//ADD all matched events to eventsLine array
eventsLine.push(titleInFeed + eventLoop.eventTitle + divBrk +
accordDataWrap + eventInFeed + eventLoop.event + divBrk +
dateInFeed + formatDate(eventLoop.eventDATE) + divBrk +
priceInFeed + "£" + eventLoop.price + divBrk + closeAccordDataWrap);
}
}
}
// TURNS the array into a string and replaces those damned, infernal commas!!
var outputString = eventsLine.toString().replace(/>,/g, '>');
// PUT the compiled array into the eventsFeed div (with venueName as title)
if (website==""){
eventsList.innerHTML = feedHead + outputString;
} else {
eventsList.innerHTML = feedHead + webSiteDiv + outputString;
}
// ADD the accordion
$(document).on('click', marker, function(){
$(eventsList).accordion({
header: "div."+id,
icons: null
})
})
// OR
$(eventsList).each(function(){
$(eventsList).accordion({
header: "div."+id,
icons: null
});
});
// OR
accordion(eventsList, id);
});
}
This third option calls a separate function which is defined as;
function accordion(placement,id){
$(placement).accordion({
header: "div."+id,
icons: null
});
}
As you can probably tell I'm pretty new to all of this so any help or advice with anything would be greatly appreciated! :)
Can you replace this code:
$(eventsList).each(function(){
$(eventsList).accordion({
header: "div."+id,
icons: null
});
});
with this code:
$(eventsList).each(function(){
$(this).accordion({
header: "div."+id,
icons: null
});
});
and try. Also it will be better if you can Create a fiddle for your code.

onmouseover for the last of several generated divs will not work in IE

I have a JavaScript function:
function addTool(id, text, tool, pic) {
var container = getById('infobox');
var origimg = getById('tempimg').src;
container.innerHTML += "<div id='" + id + "' class='toolText'>" + text + "<br><img class='toolImg' src='img/tools/" + tool + "'></div>";
getById(id).setAttribute('onMouseOver', "mOver('"+ id +"', '" + pic + "');");
getById(id).setAttribute('onMouseOut', "mOut('"+ id +"', '" + origimg + "');");
getById(id).setAttribute('href', 'javascript:mClick(id);');
}
Which generates several divs, using this code:
addTool("1p", "Bar", "tool1.jpg", 'img/p&g-part-2_skiss1-2.jpg');
addTool("2p", "Tube", "tool1.jpg", 'img/p&g-part-2_skiss1-2.jpg');
addTool("3p", "Rotating", "tool1.jpg", 'img/p&g-part-2_skiss1-2.jpg');
The mouse events work fine in all major browsers except IE. It seems that all divs except the last will have the mouse event in lowercase which will have the mouse event exactly as written, with upper case letters.
All mouse events will fire except for the last div, even if I write onmouseover instead of say ONmouseOVER, which works fine on all except the last.
Do not use setAttribute to add events. Use attachEventListener/addEvent
The problem you have is adding the elements to the div. You are basically wiping it away each time when you are adding the new elements. That is bad. You should be using appendChild to add new content to the div.
Basic idea:
function attachEvent(elem, eventName, fn) {
if ( elem.attachEvent ) {
elem.attachEvent( 'on' + eventName, fn);
} else {
elem.addEventListener( eventName, fn, false );
}
}
function addTool(text, message) {
var container = document.getElementById('infobox');
var newTool = document.createElement("a");
newTool.innerHTML = text;
newTool.href="#";
var myClickFnc = function(e) {
alert(message);
return false;
}
attachEvent(newTool, "click", myClickFnc);
container.appendChild(newTool);
}
addTool("cat","meow");
addTool("dog","bark");
addTool("pig","oink");
running example
Just as #epascarello pointed out, it seems that the setAttribute was the culprit, so I resolved it by setting the events in inline, such as this:
function addTool(id, text, tool, pic) {
var container = getById('infobox');
var origimg = getById('tempimg').src;
container.innerHTML += "<div id='" + id + "' class='toolText'" +
"onmouseover=\"mOver('"+ id +"', '" + pic + "');\" " +
"onmouseout=\"mOut('"+ id +"', '" + origimg + "');\" " +
"onclick=\"mClick(id);\"" +
">" + text + "<br><img class='toolImg' src='img/tools/" + tool + "'></div>";
}
Which worked just fine in all browsers, including IE.
You could do this part with JQuery:
$("#"+ id).mouseover(function() {
mOver('"+ id +"', '" + pic + "');
});
You can even take this a lot further:
https://stackoverflow.com/a/4158203/190596

Categories