fullcalendar.io - Holding Event in memory - javascript

I believe javascript is holding the event in memmory but I can't figure out where and how to get around it. maybe you guys can help. I have created a JSFiddle to demonstrate the problem
JSFIDDLE
So it happens when you update one event. Then you move to another event go to update that event. It brings the old event to the new event. Changes the start and end and everything. First event updates fine.
When you click event. These functions are fired.
function eventClick(calEvent){
$('#edit-event-title').val(calEvent.code);
$('#edit-event-description').val(calEvent.description);
$('#event-start-edit-dpick').data('DateTimePicker').date(calEvent.start).format('YYYY-MM-DD');
$('#event-start-time-edit-dpick').data('DateTimePicker').date(calEvent.start).format('HH:mm');
$('#event-end-edit-dpick').data('DateTimePicker').date(calEvent.end).format('YYYY-MM-DD');
$('#event-end-time-edit-dpick').data('DateTimePicker').date(calEvent.end).format('HH:mm');
$('#fc_edit').click();
}
function createUpdateEvent(calEvent, create) {
//create event
if(create){
// create the event
} else {
$(".antosubmit2").on("click", function() {
calEvent.code = $("#edit-event-title").val();
calEvent.title = $("#edit-event-title option:selected").html();
calEvent.description = $("#edit-event-description").val();
calEvent.start = moment($('#event-start-edit-dpick').data('DateTimePicker').date().format('YYYY-MM-DD') + ' ' +
$('#event-start-time-edit-dpick').data('DateTimePicker').date().format('HH:mm') +
$('#event-start-edit-dpick').data('DateTimePicker').date().format('Z'));
calEvent.end = moment($('#event-end-edit-dpick').data('DateTimePicker').date().format('YYYY-MM-DD') + ' ' +
$('#event-end-time-edit-dpick').data('DateTimePicker').date().format('HH:mm') +
$('#event-end-edit-dpick').data('DateTimePicker').date().format('Z'));
calendar.fullCalendar('updateEvent', calEvent);
$('.antoclose').click();
});
}
}
function recalcHeaderHours(event){
var currentday = moment(event.start).format("YYYY-MM-DD");
if (event.totalHours > 0) {
var prev = $("#dailytotal-"+currentday).text() || 0;
$("#dailytotal-"+currentday).text(+prev + +event.totalHours);
}
}
I hope you guys can assist. Thanks for your time :)

I fixed your issue.
The problem is that you put the on click event to the ".antosubmit2" in line 83. On first event open there will be 1 click on this class, but on the 2. event open the code put another click on it. If you open only one event 2 times, there will be no problem. But it you do it on different events, on the second open, 2 click fires on it. The newly added click use correct data, but the first click use the first event datas. This is your problem I guess.
The first click should be unbind from the ".antosubmit2".
Try to modify your code like this:
function createUpdateEvent(calEvent, create) {
//create event
if(create){
// create the event
} else {
$(".antosubmit2").unbind('click');
$(".antosubmit2").on("click", function() {...
You see the "unbind('click')" line, add it to the code and it will works.

Related

Have one button with two different behaviors for click and mouse down

I wish to have the same button behave different for left click and left mouse down.
On click it should add 15 to the current number, on mouse down it adds 1 for as long as the mouse is down
var value = 0;
document.getElementById("Addbtn").addEventListener("mousedown", mouseDown);
document.getElementById("Addbtn").addEventListener("click", mouseClick);
function mouseDown() {
this.value++;
document.getElementById("demo").innerHTML = this.value.tosSring();
}
function mouseClick() {
this.value += 15;
document.getElementById("demo").innerHTML = this.value.tosSring();
}
The problem both events gets fired and I wish to distinguish them so when mouse is hold down click won't fire and vise versa.
Is there a way to achieve this?
Cheers
As I said in the comment, since click and mousedown are related and there is no way to disconnect them from each other, the solution can come with a bit of a trick, adding a timeout to determine if it was a "long hold" of the mouse down.
Added a little bonus to disable the click if mouse down has been triggered, you can remove it if not needed.
Also notice, its on a 1 second waiting (1000 ms), change it according to how much you can wait before saying its a mousedown event. 1 second seems long to a user sometime ( about 500 ms is a sweet spot for me)
var value = 0;
var mouseHoldTimeout;
var mouseDownDone = false;
document.getElementById("Addbtn").addEventListener("mousedown", mouseDown);
document.getElementById("Addbtn").addEventListener("click", mouseClick);
function mouseDown() {
mouseHoldTimeout = setTimeout(() => {
value++;
mouseDownDone = true;
document.getElementById("demo").innerHTML = value.toString();
}, 1000);
}
function mouseClick() {
if (mouseHoldTimeout) {
clearTimeout(mouseHoldTimeout);
mouseHoldTimeout = null;
}
if (mouseDownDone) {
mouseDownDone = false;
return;
}
value += 15;
document.getElementById("demo").innerHTML = value.toString();
}
mousedown event will trigger when you click either the left or right or even the middle.It does not matter which one do you click it runs the function. In contrast click event will trigger when you click the left.So it seems when you click the left you trigger mousedown(for left) and click event.
As the document provides the click event triggers after mousedown and mouseup.
js mouse basics

JS Always getting the same event object "e" parameter with mousedown

I'm trying to handle a middle mouse button click event with JQuery on a DataTable (https://datatables.net/). Here is my code.
var tbl = document.getElementById("entries");
$(tbl).on('mousedown', function (e) {
e.preventDefault();
if (e.which == 2) {
var table = window.table_entries;
var data = table.dataTable.row($(e.detail)).data();
window.open("/plugin/Changes/#Model.Revision/" + data.BuildId, '_blank');
}
});
I'm always getting the same BuildId (284), no matter where I click. How can I get the correct row?
I also have another code snippet, which works perfectly fine
tbl.addEventListener("cdt.click", function (e) {
var table = window.table_entries;
var data = table.dataTable.row($(e.detail)).data();
window.open("/plugin/Changes/#Model.Revision/" + data.BuildId, '_blank');
window.location("/plugin/Changes/#Model.Revision/" + data.BuildId);
});
Thanks in advance!
if you want to check de middle button click with jquery check this code
$("#foo").on('click', function(e) {
if( e.which == 2 ) {
e.preventDefault();
alert("middle button");
}
});
From this question Triggering onclick event using middle click
And if you want to check downmouse you can check this other #KyleMit answer
Detect middle button click (scroll button) with jQuery
#Jordi Jordi (because I can't comment right now) : Based on JQuery's documentation, click & mousedown both works.
$('h1').on('mousedown', function(e) {
alert(e.which);
});
Will display 1 for LClick, 2 for Middle, 3 for RClick. But this isn't the question.
If you're getting the same BuildId, it's because your selector isn't the good one.
If you're searching to get an exact row, you should change your selector like this :
$('td').on('mousedown', function (e) {
e.preventDefault();
if (e.which == 2) {
// Here you should get the row like this :
var row = $(this).parent();
}
});
Now it's your job to do what you want with this. The var "row" will contain the TR, meaning the row you just give a click.
EDIT : Note that your second code snippet doesn't include e.preventDefault(). Maybe it's the reason this second one works ?

A Double Click event also triggers Click event in EaselJS

Adding Event Listener
function Solitaire() {
this.table.addEventListener("click", this.handleClick.bind(this));
this.table.addEventListener("dblclick", this.handleDoubleClick.bind(this));
}
Handling Event
Solitaire.prototype.handleDoubleClick = function(event) {
console.log("DoubleClick");
};
Solitaire.prototype.handleClick = function(event) {
console.log("Click");
};
Expected output (in console) on a double click event
DoubleClick
But the output I get in console:
Click
Click
DoubleClick
I don't know about easeljs, but I can tell you about how it is done in jQuery, where you need to "hack" it to make it actually work.
var DELAY = 500;
$('#my_element').on('click', function(e){
++clicks; // Count the clicks
if(clicks === 1){
// One click has been made
var myTimerToDetectDoubleClick = setTimeout(function(){
console.log('This was a single click');
doStuffForSingleClick();
clicks = 0;
}, DELAY);
} // End of if
else{
// Someone is clicking pretty damn fast, they probably mean double click :p
clearTimeout(myTimerToDetectDoubleClick);
doStuffForDoubleClick();
clicks = 0;
}
}).on('dblclick', function(evt){
evt.preventDefault(); // cancel system's default double click
});
The basic essence will remain the same for event handling for easeljs. You can imitate this behaviour accordingly there.

How to differentiate single click event and double click event?

I have a single button in li with id "my_id". I attached two jQuery events with this element
1.
$("#my_id").click(function() {
alert('single click');
});
2.
$("#my_id").dblclick(function() {
alert('double click');
});
But every times it gives me the single click
Instead of utilizing more ad-hoc states and setTimeout, turns out there is a native property called detail that you can access from the event object!
element.onclick = event => {
if (event.detail === 1) {
// it was a single click
} else if (event.detail === 2) {
// it was a double click
}
};
Modern browsers and even IE-9 supports it :)
Source: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
The behavior of the dblclick event is explained at Quirksmode.
The order of events for a dblclick is:
mousedown
mouseup
click
mousedown
mouseup
click
dblclick
The one exception to this rule is (of course) Internet Explorer with their custom order of:
mousedown
mouseup
click
mouseup
dblclick
As you can see, listening to both events together on the same element will result in extra calls to your click handler.
You need to use a timeout to check if there is an another click after the first click.
Here is the trick:
// Author: Jacek Becela
// Source: http://gist.github.com/399624
// License: MIT
jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) {
return this.each(function(){
var clicks = 0, self = this;
jQuery(this).click(function(event){
clicks++;
if (clicks == 1) {
setTimeout(function(){
if(clicks == 1) {
single_click_callback.call(self, event);
} else {
double_click_callback.call(self, event);
}
clicks = 0;
}, timeout || 300);
}
});
});
}
Usage:
$("button").single_double_click(function () {
alert("Try double-clicking me!")
}, function () {
alert("Double click detected, I'm hiding")
$(this).hide()
})
<button>Click Me!</button>
EDIT:
As stated below, prefer using the native dblclick event: http://www.quirksmode.org/dom/events/click.html
Or the one provided by jQuery: http://api.jquery.com/dblclick/
The modern correct answer is a mix between the accepted answer and #kyw 's solution.
You need a timeout to prevent that first single click and the event.detail check to prevent the second click.
const button = document.getElementById('button')
let timer
button.addEventListener('click', event => {
if (event.detail === 1) {
timer = setTimeout(() => {
console.log('click')
}, 200)
}
})
button.addEventListener('dblclick', event => {
clearTimeout(timer)
console.log('dblclick')
})
<button id="button">Click me</button>
A simple function. No jquery or other framework is required. Pass your functions as parameters
<div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div>
<script>
function doubleclick(el, onsingle, ondouble) {
if (el.getAttribute("data-dblclick") == null) {
el.setAttribute("data-dblclick", 1);
setTimeout(function () {
if (el.getAttribute("data-dblclick") == 1) {
onsingle();
}
el.removeAttribute("data-dblclick");
}, 300);
} else {
el.removeAttribute("data-dblclick");
ondouble();
}
}
</script>
I'm afraid that the behaviour is browser dependent:
It is inadvisable to bind handlers to
both the click and dblclick events for
the same element. The sequence of
events triggered varies from browser
to browser, with some receiving two
click events before the dblclick and
others only one. Double-click
sensitivity (maximum time between
clicks that is detected as a double
click) can vary by operating system
and browser, and is often
user-configurable.
http://api.jquery.com/dblclick/
Running your code in Firefox, the alert() in the click() handler prevents you from clicking a second time. If you remove such alert, you get both events.
Well in order to double click (click twice) you must first click once. The click() handler fires on your first click, and since the alert pops up, you don't have a chance to make the second click to fire the dblclick() handler.
Change your handlers to do something other than an alert() and you'll see the behaviour. (perhaps change the background color of the element):
$("#my_id").click(function() {
$(this).css('backgroundColor', 'red')
});
$("#my_id").dblclick(function() {
$(this).css('backgroundColor', 'green')
});
This answer is made obsolete through time, check #kyw's solution.
I created a solution inspired by the gist posted by #AdrienSchuler. Use this solution only when you want to bind a single click AND a double click to an element. Otherwise I recommend using the native click and dblclick listeners.
These are the differences:
Vanillajs, No dependencies
Don't wait on the setTimeout to handle the click or doubleclick handler
When double clicking it first fires the click handler, then the doubleclick handler
Javascript:
function makeDoubleClick(doubleClickCallback, singleClickCallback) {
var clicks = 0, timeout;
return function() {
clicks++;
if (clicks == 1) {
singleClickCallback && singleClickCallback.apply(this, arguments);
timeout = setTimeout(function() { clicks = 0; }, 400);
} else {
timeout && clearTimeout(timeout);
doubleClickCallback && doubleClickCallback.apply(this, arguments);
clicks = 0;
}
};
}
Usage:
var singleClick = function(){ console.log('single click') };
var doubleClick = function(){ console.log('double click') };
element.addEventListener('click', makeDoubleClick(doubleClick, singleClick));
Below is the usage in a jsfiddle, the jQuery button is the behavior of the accepted answer.
jsfiddle
Another simple Vanilla solution based on the A1rPun answer (see his fiddle for the jQuery solution, and both are in this one).
It seems that to NOT trigger a single-click handler when the user double-clicks, the single-click handler is necessarily triggered after a delay...
var single = function(e){console.log('single')},
double = function(e){console.log('double')};
var makeDoubleClick = function(e) {
var clicks = 0,
timeout;
return function (e) {
clicks++;
if (clicks == 1) {
timeout = setTimeout(function () {
single(e);
clicks = 0;
}, 250);
} else {
clearTimeout(timeout);
double(e);
clicks = 0;
}
};
}
document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false);
How to differentiate between single clicks and double clicks on one and the same element?
If you don't need to mix them, you can rely on click and dblclick and each will do the job just fine.
A problem arises when trying to mix them: a dblclick event will actually trigger a click event as well, so you need to determine whether a single click is a "stand-alone" single click, or part of a double click.
In addition: you shouldn't use both click and dblclick on one and the same element:
It is inadvisable to bind handlers to both the click and dblclick events for the same element. The sequence of events triggered varies from browser to browser, with some receiving two click events before the dblclick and others only one. Double-click sensitivity (maximum time between clicks that is detected as a double click) can vary by operating system and browser, and is often user-configurable.
Source: https://api.jquery.com/dblclick/
Now on to the good news:
You can use the event's detail property to detect the number of clicks related to the event. This makes double clicks inside of click fairly easy to detect.
The problem remains of detecting single clicks and whether or not they're part of a double click. For that, we're back to using a timer and setTimeout.
Wrapping it all together, with use of a data attribute (to avoid a global variable) and without the need to count clicks ourselves, we get:
HTML:
<div class="clickit" style="font-size: 200%; margin: 2em; padding: 0.25em; background: orange;">Double click me</div>
<div id="log" style="background: #efefef;"></div>
JavaScript:
<script>
var clickTimeoutID;
$( document ).ready(function() {
$( '.clickit' ).click( function( event ) {
if ( event.originalEvent.detail === 1 ) {
$( '#log' ).append( '(Event:) Single click event received.<br>' );
/** Is this a true single click or it it a single click that's part of a double click?
* The only way to find out is to wait it for either a specific amount of time or the `dblclick` event.
**/
clickTimeoutID = window.setTimeout(
function() {
$( '#log' ).append( 'USER BEHAVIOR: Single click detected.<br><br>' );
},
500 // how much time users have to perform the second click in a double click -- see accessibility note below.
);
} else if ( event.originalEvent.detail === 2 ) {
$( '#log' ).append( '(Event:) Double click event received.<br>' );
$( '#log' ).append( 'USER BEHAVIOR: Double click detected.<br>' );
window.clearTimeout( clickTimeoutID ); // it's a dblclick, so cancel the single click behavior.
} // triple, quadruple, etc. clicks are ignored.
});
});
</script>
Demo:
JSfiddle
Notes about accessibility and double click speeds:
As Wikipedia puts it "The maximum delay required for two consecutive clicks to be interpreted as a double-click is not standardized."
No way of detecting the system's double-click speed in the browser.
Seems the default is 500 ms and the range 100-900mms on Windows (source)
Think of people with disabilities who set, in their OS settings, the double click speed to its slowest.
If the system double click speed is slower than our default 500 ms above, both the single- and double-click behaviors will be triggered.
Either don't use rely on combined single and double click on one and the same item.
Or: add a setting in the options to have the ability to increase the value.
It took a while to find a satisfying solution, I hope this helps!
Here's an alternative of jeum's code for an arbitrary number of events:
var multiClickHandler = function (handlers, delay) {
var clicks = 0, timeout, delay = delay || 250;
return function (e) {
clicks++;
clearTimeout(timeout);
timeout = setTimeout(function () {
if(handlers[clicks]) handlers[clicks](e);
clicks = 0;
}, delay);
};
}
cy.on('click', 'node', multiClickHandler({
1: function(e){console.log('single clicked ', e.cyTarget.id())},
2: function(e){console.log('double clicked ', e.cyTarget.id())},
3: function(e){console.log('triple clicked ', e.cyTarget.id())},
4: function(e){console.log('quadro clicked ', e.cyTarget.id())},
// ...
}, 300));
Needed this for a cytoscape.js app.
Use the excellent jQuery Sparkle plugin. The plugin gives you the option to detect first and last click. You can use it to differentiate between click and dblclick by detecting if another click was followed by the first click.
Check it out at http://balupton.com/sandbox/jquery-sparkle/demo/
I wrote a simple jQuery plugin that lets you use a custom 'singleclick' event to differentiate a single-click from a double-click:
https://github.com/omriyariv/jquery-singleclick
$('#someDiv').on('singleclick', function(e) {
// The event will be fired with a small delay.
console.log('This is certainly a single-click');
}
I like to avoid jquery (and other 90-140k libs), and as noted browsers handle onclick first, so here is what I did on a website I created (this example also covers getting a clicked location local x y )
clicksNow-0; //global js, owell
function notify2(e, right) { // called from onclick= and oncontextmenu= (rc)
var x,y,xx,yy;
var ele = document.getElementById('wrap');
// offset fixed parent for local win x y
var xxx= ele.offsetLeft;
var yyy= ele.offsetTop;
//NScape
if (document.layers || document.getElementById&&!document.all) {
xx= e.pageX;
yy= e.pageY;
} else {
xx= e.clientX;
yy= e.clientY;
}
x=xx-xxx;
y=yy-yyy;
clicksNow++;
// 200 (2/10ths a sec) is about a low as i seem to be able to go
setTimeout( "processClick( " + right + " , " + x + " , " + y + ")", 200);
}
function processClick(right, x, y) {
if (clicksNow==0) return; // already processed as dblclick
if (clicksNow==2) alert('dbl');
clicksNow=0;
... handle, etc ...
}
hope that helps
Based on Adrien Schuler (thank you so much!!!) answer, for Datatables.net and for many uses, here is a modification:
Function
/**
* For handle click and single click in child's objects
* #param {any} selector Parents selector, like 'tr'
* #param {any} single_click_callback Callback for single click
* #param {any} double_click_callback Callback for dblclick
* #param {any} timeout Timeout, optional, 300 by default
*/
jQuery.fn.single_double_click = function (selector, single_click_callback, double_click_callback, timeout) {
return this.each(function () {
let clicks = 0;
jQuery(this).on('click', selector, function (event) {
let self = this;
clicks++;
if (clicks == 1) {
setTimeout(function () {
if (clicks == 1) {
single_click_callback.call(self, event);
} else {
double_click_callback.call(self, event);
}
clicks = 0;
}, timeout || 300);
}
});
});
}
Use
$("#MyTableId").single_double_click('tr',
function () { // Click
let row = MyTable.row(this);
let id = row.id();
let data = row.data();
console.log("Click in "+id+" "+data);
},
function () { // DBLClick
let row = MyTable.row(this);
let id = row.id();
let data = row.data();
console.log("DBLClick in "+id+" "+data);
}
);
let clickTimes = 0;
let timer = null;
roundBox.click = function (e) {
clearTimeout(timer);
timer = setTimeout(() => { // 单击事件
console.log("single click");
}, 600);
clickTimes++;
if (clickTimes == 2) { // 双击
clearTimeout(timer);
clickTimes = 0;
console.log("double click");
toggleExpanded(id);
}
}
this worked for me–
var clicked=0;
function chkBtnClcked(evnt) {
clicked++;
// wait to see if dblclick
if (clicked===1) {
setTimeout(function() {
clicked=0;
.
.
}, 300); // test for another click within 300ms
}
if (clicked===2) {
stopTimer=setInterval(function() {
clicked=0;
.
.
}, 30*1000); // refresh every 30 seconds
}
}
usage–
<div id="cloneimages" style="position: fixed;" onclick="chkBtnClcked(evnt)" title="Click for next pic; double-click for slide show"></div>
Just posting the native HTML answer just in case the need is to be easy and HTML.
<p ondblclick="myFunction()" id = 'id'>Double-click me</p>
This of course has native Jquery options. ie... $('#id').attr('ondblclick',function(){...}) or, as stated previously, $('#id').dblclick(function(){...});
I know this is old, but below is a JS only example of a basic loop counter with a single timer to determine a single vs double click. Hopefully this helps someone.
var count = 0;
var ele = document.getElementById("my_id");
ele.addEventListener('click', handleSingleDoubleClick, false);
function handleSingleDoubleClick()
{
if(!count) setTimeout(TimerFcn, 400); // 400 ms click delay
count += 1;
}
function TimerFcn()
{
if(count > 1) console.log('you double clicked!')
else console.log('you single clicked')
count = 0;
}
Try this code
let click = 0;
element.onclick = (event) => {
click++;
console.log(click);
setTimeout(() => {
click = 0;
}, 300);
if (click === 2) {
console.log("double Click");
click = 0;
console.log(click);
}
};
If you want to distinguish between a single and double click, the event handler of the single click has to wait until it is proven, that the single click is not the beginning of a double click. This makes single clicks lagging. The example shows this.
var distinguish = (() => {
var target = null;
var timeout = null;
return (element, action) => {
element.addEventListener ('click', e => {
if (e.target === target) {
clearTimeout (timeout);
target = null;
timeout = null;
action ('double');
} else {
target = e.target;
timeout = setTimeout (() => {
target = null;
timeout = null;
action ('single');
}, 500);
}
});
};
})();
var button = document.getElementById ('button');
distinguish (button, kind => console.log (kind + ' click'));
<input id="button" type="button" value="click">
Pure JS, to truly differentiate single- vs double-click, (e.g. not triggering both at the same time). I'm using this combination of the native event.detail and a custom delay, to prevent the single-click from firing, if it gets cancelled by a double-click.
This approach is also very performance friendly, as it doesn't start a new timer every time we click in quick succession.
The only minor thing (as with some of the other solutions too), is that it may still fire both events, if the user double-clicks very very slowly. This can be prevented by highering the delay, but that would make single-clicking feel even more laggy.
Also there is a lot of differences in the suggested answers as to how they handle quick multi-clicking. So to make things clear, here is what happens in every consecutive click with this approach:
triggers a slightly delayed single-click, if it isn't cancelled by a doubleclick
triggers double-click
nothing
triggers double-click
nothing
...(every 2nd click is a doubleclick, which feels very natural)
I included a snippet so you can test it for yourself.
document.querySelector('button').addEventListener('click', single_or_double);
let isSingleClick; // flag to allow or cancel single clicks
function single_or_double(){
if (isSingleClick = event.detail == 1){ //check for a singleclick and store flag globally at the same time
setTimeout(() => {
if(isSingleClick){ //check if the flag is still set after the delay
console.log("single");
}
}, 200); // singleclick delay in milliseconds
}
else if (event.detail == 2) {
console.log("double");
}
}
<button>Single OR Double-Click</button>

AJAX addEventListener - passing parameters to another function

I'll keep this short - I've got a list of buttons, that I create using a loop, and when one of them gets clicked I want to be able to pass its id attribute to another file in order to dynamically generate a new page.
Here's the code:
for (var i in data.contacts) {
var temp = document.createElement('div');
temp.className = "contacts";
var dude = document.createElement('input');
dude.type = "button";
dude.value = data.contacts[i];
dude.id = data.contacts[i];
dude.className = "dude_button" + data.contacts[i];
dude.addEventListener('click', function(event) { gotoProfile(dude.id); }, false);
temp.appendChild(dude);
temp.appendChild(document.createElement('br'));
theDiv.appendChild(temp);
}
// and now in another file, there's gotoProfile():
function gotoProfile(x) {
var username = document.getElementById(x).value;
if (xmlHttp) {
try {
.... etc.
Now see this works, sort of, but the problem is that when I click any button, it only passes the last dude.id value from the list data.contacts. Obviously I want every button's addEventListener to pass its own data.contacts[i] value, instead of just the last one.
Help appreciated, thanks guys.
Because JavaScript has no block scope, dude will refer to the last assigned element (because the loop finished) when the event handler is called. You have to capture the reference to the current dude by e.g. using an immediate function:
dude.addEventListener('click', (function(d) {
return function(event) {
gotoProfile(d.id);
}
}(dude)), false);
This is a common error when creating functions in a loop.
But you can make it even easier. The event object has a property target that points to the element the event was raised on. So you can just do:
dude.addEventListener('click', function(event) {
gotoProfile(event.target.id);
}, false);
And with that said, you don't need to add a handler for every button. As you are doing the same for every button, you could attach the same event handler above to the parent of the buttons (or a common ancestor) and it would still work. You just have to filter out the clicks that don't happen on a button:
parent.addEventListener('click', function(event) {
if(event.target.nodeName == 'INPUT' && event.target.type == "button") {
gotoProfile(event.target.id);
}
}, false);

Categories