I'm trying to populate a ul list with some li elements and give each li element a link that calls the same function with a different argument. However it doesn't seem to work, i've attached the code below, CheckForNewMail is called on document load. Can anyone please help me out?
function CheckForNewMail() {
//////////////////////////////////////////////////////////////////
// This will be dynamic
MailInInbox[0] = new Array("0", "Mail One");
MailInInbox[1] = new Array("12", "Mail Two");
MailInInbox[2] = new Array("32", "Mail Three");
MailInInbox[3] = new Array("5", "Mail Four");
//////////////////////////////////////////////////////////////////////
$('#mail-in-inbox').children().remove();
size = 4; element = $('#mail-in-inbox');
for(i = 0; i < size; ++i) {
var link = $('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>');
link.live('click', function() {
LoadMailById(i);
});
li = $('<li></li>');
li.append(link);
element.append(li);
}
}
function LoadMailById(id) {
alert("Button "+ id +" clicked!");
}
First, I'm making an assumption here:
id of the email in that click function, not the index e.g. 0, 12, 32, 5, rather than 0, 1, 2, 3.Given that (easy to adjust with .index() if the assumption is incorrect), you can do this:
function CheckForNewMail() {
MailInInbox[0] = ["0", "Mail One"];
MailInInbox[1] = ["12", "Mail Two"];
MailInInbox[2] = ["32", "Mail Three"];
MailInInbox[3] = ["5", "Mail Four"];
$('#mail-in-inbox').empty();
var size = 4, element = $('#mail-in-inbox');
for(i = 0; i < size; ++i) {
$('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>')
.data('id', MailInInbox[i][0]).wrap('<li/>').parent().appendTo(element);
}
}
There are a few changes here:
var declaration on variables (if they aren't already defined elsewhere).data() to store the id on the <a> we just createdThen, using that stored data, we can attach a single handler to the #mail-in-inbox container one time (on DOM ready), rather than one to each <a> each time this function runs, it should look like this:
$('#mail-in-inbox').delegate('.inbox-link', 'click', function() {
alert("Button "+ $.data(this, 'id') +" clicked!");
});
This would display "Button 0 clicked!", "Button 12 clicked", etc. You can test out all of the above in a demo here.
One problem is that the variable i will always be that of the last link because by the time the user clicks any link, the loop would have completed. One way to fix this would be to use the .data() method to associate a piece of information with each li element:
link.data('mailId', i); // within the loop
Then you can bind a single event handler for all inbox links inside #mail-in-inbox:
$('#mail-in-inbox').on('click', '.inbox-link', function() {
LoadMailById($(this).data('mailId'));
});
Edited to add: .on() was introduced in jQuery 1.7. If you are using jQuery 1.6 or older, use .delegate() or .live() (as in the question and the original version of this answer) instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With