How to add onclick event in dynamicly add html code via JavaScript? - javascript

I try to add some list element in loop via JS. Every element <li>contains <a> tag, now I want to add onClick event in every adding <a> tag. I try to do it so:
liCode = '<li>Text using variable foo: ' + foo + '</li>';
$('#list').append(function() {
return $(liCode).on('click', clickEventOccurs(foo));
});
In clickEventOccurs I just output to console foo. It works in strange way: this event performed just on init when every tag is adding to list, but after click on <a> doesn`t perform anything. How to make it works in proper way - on click performed code in clickEventOccurs?

Firstly, you are assigning not a callback function, but a result of function evaluation. In right way it should be like this:
$('#list').append(function() {
return $(liCode).click(function() {
clickEventOccurs(foo);
});
});
Also, as you are using jQuery you might use benefits of events delegation and use .on method this way:
$('#list').on('click', 'li', function() {
return clickEventOccurs(foo);
});

on() is good for handling events, even to elements which will be created dynamically.
$('body').on('click', '#list li', function(){
clickEventOccurs(foo);
});

http://jsfiddle.net/lnplnp/uGJnc/
HTML :
<ol id="list">
<li>Text using variable foo: foovalue</li>
</ol>
JAVASCRIPT/JQUERY :
function appending(foo) {
liCode = '<li>Text using variable foo: ' + foo + '</li>';
$('#list').append($(liCode));
}
$('#list').on('click', 'li', function() {
return clickEventOccurs($("a", this).text());
});
function clickEventOccurs(v){
console.log(v.split(":")[1].trim());
}
appending("foo1");
appending("foo2");
appending("foo3");

To pass a variable to that function you'll have to make a second anonymous one, otherwise your clickEventOccurs function will be called at assignment, not as a callback.
$('#list').append(function() {
return $(liCode).click(function() {
clickEventOccurs(foo)
});
});

Related

onclick generates invalid function

I have a variable that is attached to a function. I am trying to use that variable in an onclick event.
This is what I am doing
var show = function() {
console.log("hello");
};
$(container).append(
"<div class='info' onclick=" + show + ">Show</div>"
);
However the generated html comes out like this
<div class="info" onclick="function()" {="" console.log("hello");="" }="">
Show
</div>
Any idea how I can fix this so that when I click the div my function gets called ?
You can simply do like this, Just make show a function and call it on click.
This will work
<script>
function show() {
console.log("hello");
}
$(container).append(
'<div class="info" onclick="show()">Show</div>'
);
</script>
This is kind of an unusual approach to what you're trying to do. I think it would be more idiomatic in jQuery to either
a) define the element first, with event handler, and then append it,
$("<div>Show</div>", {
"class": "info",
on: {
click: function(e) {
console.log("Hello");
}
}
}).appendTo($(container));
or
b) append a new element and then add an event handler to it after appending it.
$(container).append("<div class='info'>Show</div>");
$(container).children('.info').last().on('click', function(e) { console.log("Hello"); });
Between those two, I'd recommend the first in this case.
The variable show is a function, Then how can you bind it with string?
The code should be like,
$(container).append("<div class='info' onClick='show()'>Show</div>");
try using :
var show = function() {
console.log("hello");
};
$(container).append("<div class='info' onclick="+'show()'+">Show</div>");
This will work.
The reason why your code
var show = function() {
console.log("hello");
};
$(container).append("<div class='info' onclick=" + show + ">Show</div>");
was not working as required as show is an object of type function, so when one uses the function name without the () the variable is replaced bu the code that it consists.
Hope it helps.

How to apply multiple events to the same function

I'm not the best at this jquery stuff. But I'm trying to seperate the action from the function so I can apply multiple events that cause the same function. Unfortunately this isn't working. Anyone know why?
Updated Function, but still errors
$(document).ready(function() {
var $info_items = jQuery('.checkbox.has_info, .has_info');
$info_items.click(function(event) {
$(this).show_text(event);
});
// I suspect it has something to do with this initalizer of the function here
jQuery.fn.show_text = function(event){
var $info_item = jQuery(this);
$info_items.filter(function(index){
return $(".hidden_text").css("display","block");
}).not($info_item).parent().next().next().hide("slow");
$info_item.parent().next().next().show("fast");
});
});
What is e, the event? You need to name the event argument to the click() function to use it. Also, to invoke show_text such that it has a this, you need to invoke it on an element:
$info_items.click(function (event) {
// 'this' is the element in $info_items which was clicked
// invoke show_text on the element in question
$(this).show_text(event);
});
You also have an extra ) on your final }); line.
You can use jQuery bind to attach several events to a single function.
$('#whatever').bind('mouseover focus click', function() {
your_custom_function();
});
Are you looking for something like this?
var handle = function(event) {
$(event.currentTarget).show_text(event);
};
$info_items.bind('click blur', handle);

How to do early binding for event handler in JavaScript? (example with jQuery)

JavaScript's late binding is great. But how do I early bind when I want to?
I am using jQuery to add links with event handlers in a loop to a div. The variable 'aTag ' changes in the loop. When I click the links later, all links alert the same message, which is the last value of 'aTag'. How do I bind a different alert message to all links?
All links should alert with the value that 'aTag' had when the event handler was added, not when it was clicked.
for (aTag in tagList) {
if (tagList.hasOwnProperty(aTag)) {
nextTag = $('');
nextTag.text(aTag);
nextTag.click(function() { alert(aTag); });
$('#mydiv').append(nextTag);
$('#mydiv').append(' ');
}
}
You can pass data to the bind method:
nextTag.bind('click', {aTag: aTag}, function(event) {
alert(event.data.aTag);
});
This will make a copy of aTag, so each event handler will have different values for it. Your use case is precisely the reason this parameter to bind exists.
Full code:
for (aTag in tagList) {
if (tagList.hasOwnProperty(aTag)) {
nextTag = $('');
nextTag.text(aTag);
nextTag.bind('click', {aTag: aTag}, function(event) {
alert(event.data.aTag);
});
$('#mydiv').append(nextTag);
$('#mydiv').append(' ');
}
}
You can also make a wrapper function that takes the text to alert as a parameter, and returns the event handler
function makeAlertHandler(txt) {
return function() { alert(txt); }
}
and replace
nextTag.click(function() { alert(aTag); });
with
nextTag.click(makeAlertHandler(aTag));
You need to keep a copy of this variable, like this:
for (aTag in tagList) {
if (tagList.hasOwnProperty(aTag)) {
nextTag = $('');
nextTag.text(aTag);
var laTag = aTag;
nextTag.click(function() { alert(laTag); });
$('#mydiv').append(nextTag);
$('#mydiv').append(' ');
}
}
The aTag variable is changing each time you loop, at the end of the loop it's left as the last item in the loop. However, each of the functions you created point at this same variable. Instead, you want a variable per, so make a local copy like I have above.
You can also shorten this down a lot with chaining, but I feel it clouds the point in this case, since the issue is scoping and references.

Is there an easier way to reference the source element for an event?

I'm new to the whole JavaScript and jQuery coding but I'm currently doing this is my HTML:
<a id="tog_table0"
href="javascript:toggle_table('#tog_table0', '#hideable_table0');">show</a>
And then I have some slightly ponderous code to tweak the element:
function toggle_table(button_id, table_id) {
// Find the elements we need
var table = $(table_id);
var button = $(button_id);
// Toggle the table
table.slideToggle("slow", function () {
if ($(this).is(":hidden"))
{
button.text("show");
} else {
button.text("hide");
}
});
}
I'm mainly wondering if there is a neater way to reference the source element rather than having to pass two IDs down to my function?
Use 'this' inside the event. Typically in jQuery this refers to the element that invoked the handler.
Also try and avoid inline script event handlers in tags. it is better to hook those events up in document ready.
NB The code below assumes the element invoking the handler (the link) is inside the table so it can traverse to it using closest. This may not be the case and you may need to use one of the other traversing options depending on your markup.
$(function(){
$('#tog_table0').click( toggle_table )
});
function toggle_table() {
//this refers to the element clicked
var $el = $(this);
// get the table - assuming the element is inside the table
var $table = $el.closest('table');
// Toggle the table
$table.slideToggle("slow", function () {
$el.is(":hidden") ? $el.text("show") : $el.text("hide");
}
}
You can do this:
show
and change your javascript to this:
$('a.tableHider').click(function() {
var table = $(this.name); // this refers to the link which was clicked
var button = $(this);
table.slideToggle("slow", function() {
if ($(this).is(':hidden')) { // this refers to the element being animated
button.html('show');
}
else {
button.html('hide');
}
});
return false;
});
edit: changed script to use the name attribute and added a return false to the click handler.
I'm sure this doesn't answer your question, but there's a nifty plugin for expanding table rows, might be useful to check it out:
http://www.jankoatwarpspeed.com/post/2009/07/20/Expand-table-rows-with-jQuery-jExpand-plugin.aspx

How do I add a click handler to a class and find out which element was clicked?

I have been using the following method for adding a click event to an id, I was wondering if I could do the same with a class.... I have a number of items (which are created in a for each loop) and I need to be able to click them and then pickup which was clicked... here is my existing code
$('submit-button').bind('click', submit_click);
function submit_click() {
alert('I am clicked');
}
I was wondering if there is some way to pass in a variable into my function for the click so i can check the ID?? or similar
hence this
function submit_click(element) { // notice element
alert(element + ' clicked');
}
Any help really appreciated
Thank you
EDIT
I have tried the following and in debug "elem" is undefined...
$('.clear').bind('click', clear_click($(this)));
function clear_click(elem)
{
alert(elem.attr("id"));
}
WORKING SOLUTION
I have the working solution but I don't fully understand why, I would love to know why it works..
First of all I tried
$('.clear').bind('click', clear_click($(this)) );
This seemed to work "BUT" when I loaded the page it enter the "clear_click" method without being clicked - strange...
Then I tried this..
$('.clear').bind('click', function() { clear_click($(this)) } );
This works great! But I don't understand why I must pass a function and then within this function call my clear_click.
Can anyone explain why 1 works and the other doesn't?
Whenever I need to call a callback function or similar I should first open a function() and then call the method inside the function?
$(".yourclass").click ( function() {
$(this).attr ( "id" ); //S(this) returns the current element
});
and you can code like this
$('.yourclass').bind('click', function() { submit_click($(this)) });
function submit_click(elem)
{
alert ( elem.attr ("id" ) );
}
Edit
$('.clear').bind('click', function() { clear_click($(this)) });
function clear_click(elem)
{
alert(elem.attr("id"));
}
This will work fine for you.
Update
To answer your second question:
You can bind a function as a second argument when using the click event, but you cant bind a function and apply arguments. On the other hand, there is no need to send this as an argument to the clear_click function since the this keyword inside the function refers to the element itself:
So this works in your case:
$('.clear').bind('click', clear_click);
function clear_click() {
alert(this.id);
}
Sending this as an argument is not needed and bad coding:
$('.clear').bind('click', clear_click(this));
In the event handler, the first argument is the event object. You can extract the clicked element from that object using currentTarget or target. In jQuery, this always refers to the currentTarget in the event handler context:
var handler = function(e) {
var id = this.id; // this == e.currentTarget
}
$('submit').click(handler); // .click(fn) is shorthand for .bind('click', fn)
More examples:
$('submit').bind('click', function(e) {
console.log(e.target) // the target that was clicked on
console.log(e.currentTarget) // the element that triggered the click
console.log(this) // the same as above
});
Just add $(this) to your function, You don't need to send any parameters because you are still in the context of the clicked element.
function submit_click() { // notice element
alert($(this).attr('id') + ' clicked');
}
When you bind a handler to a function, the clicked element will be the first argument
$('.submit-button').click(submit_click);
function submit_click(element){
//element is the .submit-buttom element
alert(element+' was clicked');
alert($(element)+' was clicked');
}
This should work:
$('.submit-button').bind('click', submit_click($(this)));
function submit_click(element) { // notice element
alert($(element).attr("id") + ' clicked');
}

Categories

Resources