I am trying to create a click event for an image using jQuery but I fail every time I try.
First I have a div:
<div id="price-holder"></div>
then I am using jQuery to insert this HTML by using the following:
$("#price-menu li:nth-child(2)").click(function() {
var pregHTML = $("#cakesmash-price").html();
$("#price-holder").html(pregHTML);
});
However, using this HTML doesn't work
<div id="cakesmash-price" style="display:none">
<img id="cake" src="images/order.png" height="32px" onclick="pregbasic(this);">
</div>
I tried to use the attribute onclick for the image and also tried using jQuery's selector with the ID like so
$("#cake").click(function(){
})
but both didn't work.
Can anyone help me?
Thanks
This assumes that the element is actually being added to the page.
I am betting you are adding the click event before you add the element to the page meaning the selector did not find anything so it did not add the event.
Either add the event after you add the element or use event delegation.
$("#price-holder").html(pregHTML);
$("#cake").click(function(){
});
or
$("#price-holder").on("click", "#cake", function () {
});
Your error could be due to your choice of selectors "#price-menu li:nth-child(2)". Try using the JS .children and .eq selectors. Also if your code was added dynamically consider using the .on() event handler rather than the .click().
Just start with the DOM you actually want, without using jQuery to do this:
<div id="price-holder">
<div id="cakesmash-price" style="display:none">
<img id="cake" src="images/order.png" height="32px">
</div>
</div>
Then you can just add you click handler on #cake:
$('#cake').on('click', function (event) {
// your logic goes here
});
Related
I have this code:
var element= document.getElementsByRegex('^signalo-.*');
$(document).on( 'click', element, function(){
alert($(this).attr('id'))
} );
I have unknown numbers of buttons with the id, all beginning with "signalo-" and a number after it, like signalo-1 , signalo-2 ....
I know how to bind events for dynamic generated elements on page as you see in my code example, but the problem here is that for the event binding you have to pass a specific selector as the second argument which confuses me a little.
I know how to use wildcards both with pure javascript and with jQuery and I know hot to bind events to dynamic content but what I can't figure out is how to combine them together.
Can anyone help?
You can use jQuery's 'attribute begins with' selector to achieve this:
$(document).on('click', '[id^="signalo-"]', function() {
console.log($(this).prop('id'))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="signalo-1">signalo-1</div>
<div id="signalo-2">signalo-2</div>
<div id="notsignalo-1">notsignalo-1</div>
<div id="signalo-3">signalo-3</div>
I am generating twitter bootstrap modals dynamically based on the user action (Long Story). Lets say some times user can see 100 modals on his screen. In each and every modal I have 5 dynamic buttons, each have it own purpose and did same in all modals, and have different id's.
I am attaching onClick events to those buttons by using jquery when ever there is a new twitter modal opens up by using the button id as follows
$(document).on("click","#btn"+btnNumber, function(){
//Code Goes Gere
});
So If I open 100 modals, each have 5 buttons, Is it good idea to assigning click events for 500 times ?
or Is it good Idea to assign click events by using it's name attribute for 1 time as follows
$(document).ready(function(){
$(document).on("click","btnNameAttr", function(){
//Code Goes Gere
});
});
The jQuery on() can help you in this. First you need to detach appending DATA to your element ID like btn+btnNumber. You can add your custom information in any data-x attribute like data-custom-info and use the jQuery attr('data-custom-info') syntax to retrieve the information. The event handlers registered with on() method is also available for future elements(elements created after script execution). Like below.
When creating new button, add render it as..
<input .... class="btnWithData" data-custom-info="1" ... />
<input .... class="btnWithData" data-custom-info="2" ... />
and your event handler goes like..
$(document).ready(function(){
$('body').on('click','.btnWithData',function(){
//DO WHATEVER
var buttonData=$(this).attr('data-custom-info');
//DO WHATEVER
});
});
You should assign delegated event listeners using jQuery.on() method as #Ananthan-Unni suggests, but in the form:
$.on('click', 'button', listener)
In this case you do not need to assign unique ids or attributes. You can use tag name or class name as a selector (2nd argument).
Have a look here: https://api.jquery.com/on/ and read on delegated events.
Best is don't use closures they require memory. Rely on good old data tags, instead:
$(document).ready(function () {
$("#wrapper").on("click", "btnNameAttr", function () {
var n;
n = $(this).data("number");
// code goes here
});
});
To differentiate the actually clicked element inside #wrapper you use data-number attributes like this:
<div id="wrapper">
<img data-number="000" />
<img data-number="001" />
<img data-number="002" />
<img data-number="003" />
</div>
This code will perform much better and you can still have all functionality you want by using wrapping <div> elements and data-number="" attributes. And you don't interfere with class or id attributes you might already have on those elements.
You can even add the command to the tag:
<img data-number="000" data-command="edit" />
<img data-number="000" data-command="show" />
<img data-number="000" data-command="delete" />
And switch on it:
switch ($(this).data("command"))
{
case "edit":
// edit element with number n here
break;
}
I am adding an element on a certain condition. But I don't want it suddenly appear but rather would like to slide it down. Here's how I add it:
$('.myDiv').after('<div>added content</div>');
How do I combine it with slideDown?
Try this instead :
$(".myDiv").after("<div style='display:none;'>added content</div>");
$(".myDiv").next("div").slideDown();
Good Luck !!
Try this out:
$('.myDiv').after('<div style="display:none">added content</div>').next().slideDown();
You need to use .next() on the div to which it is attached because .after()... adds the element as a sibling to the div to which it is added
Try this
$('.myDiv').after('<div style="display:none;" class="newDiv">New Content</div>');
$('.myDiv').next('.newDiv').slideDown();
first make sure the new content that you input is hidden using .newdiv{display:none;} either in your css file or inline code like: <div style="display:none;">
then use a callback function to only start after the code was inserted in the document when you used the after() method.
$('.myDiv').after('<div class="newdiv">added content</div>', function(){
$('.newdiv').slideDown();
});
I'm not sure, how to use .click in the right way.
I looked at the manual (http://api.jquery.com/click/) but could not find the answer for my problem:
I'm generating an div structure with JS like this:
<div>
<img id='img_1' src="click.gif">
</div>
<div id='content_1'> Text</div>
Lots of those blocks are generated with the following function. At the end, each image gets an click event to change the css of the related text: click on img_1 changes css on content_1.
I try this code (simplified version):
$.each(data, function(selector,content) {
id=prepare(selector);
$('#boxDiv').append(' <div>\
<img id="img_'+id+'" src="click.gif">\
</div>\
<div id="content_'+id+'"> Text</div>');
$('#img_'+id).click(function(a) {
$('#content_'+id).css('height','100px');});
});
But this code does not work as I exacted.
Every 'img_'+id Element gets his related click event (so far, so god)
But the function does not change the css of the related 'content_'+id! All the time, the last content element is changed.
It looks like, that the .click call-back function does not get the idat the time of adding click event, but at the time of execution the callback function. At this time, the id is (of course) always the last element.
So the question is, how to bring the current (related) id inside the .click -callback function?
//Update: I'm not sure, if using live() could help in this case: i tried this, without any success.
The problem is not an missing click event. The Problem is, that at every click, the callback-function is fired by using the last id.
Example.
The generated content looks like this:
<div>
<img id='img_1' src="click.gif">
</div>
<div id='content_1'> Text</div>
<div>
<img id='img_2' src="click.gif">
</div>
<div id='content_2'> Text</div>
<div>
<img id='img_3' src="click.gif">
</div>
<div id='content_3'> Text</div>
The JS code binds one click event to img_1, one click event to img_2 and one click event to img_3.
I changed the content of the callback function to:
$('#expand_'+id).live('click',function() {console.info(id);});
SO i see the content of ID: by clicking img_1 or img_2 id is 3. Probably because, 3 is the last value for the each loop. So how can i get the related id inside the call-back?
Thank you for any kind of help.
Found the problem in your fiddle (and your updated code):
You forgot to put varin front of id, which makes it global. All event handlers reference the same id and its value is the one from the last iteration.
Declare it as
var id = ....;
to make it local.
That said, I would use jQuery to create all the elements:
$.each(data, function(selector,content) {
var id = selector;
var $img = $('<span />', {
id: 'img_' + id,
text: 'click'
}).click(function() {
$('#content_'+id).css('height','100px');
});
var $div = $('<div />', {
id: 'content_' + id,
text: 'Text'
});
$('<div />').append($img).append($div).appendTo('#boxDiv');
});
There are also other ways to find the #content_X elements. In your structure, this element is always the next sibling of the parent of the image. So instead searching for the element with this ID, inside the event handler, you could do:
$(this).parent().next().css(...);
Or even bind the event handler to the parent div instead directly to the image.
The click event handler will have access to the id (and content) variable, as it's defined in the parent function. In JavaScript, inner functions have access to all the variables of the function in which they are defined.
The problem is simply that you are missing the # ID selector from a couple of your jQuery selector string:
$('#boxDiv').append('...');
//some code removed
$('#content_' + id).css('height', '100px');
Instead of using the .click call-back function, you should use the .live call-back function. Quoting the jquery docs:
"Description: Attach a handler to the event for all elements which match the current selector, now and in the future."
Try this:
$.each(data, function(id,content) {
$('boxDiv').append(' <div>\
<img id="img_'+id+'" src="click.gif">\
</div>\
<div id="content_'+id+'"> Text</div>');
$('#img_'+id).live('click', function() {
$('content_'+id).css('height','100px');});
});
Don't you mean
$.each(data, function(id,content) {
$('#boxDiv').append(' <div>\
<img id="img_'+id+'" src="click.gif">\
</div>\
<div id="content_'+id+'"> Text</div>');
$('#img_'+id).click, function(a) {
$('#content_'+id).css('height','100px');
});
});
? There were two missing # before ID
Need to use one single button to toggle the show and hide for div
my code looks something like this
function showTable(number){
$('#div_'+number).show('slow');
$('#button_'+number).html("Hide Table").click(function(){
hideTable(number);
return false;
});
}
function hideTable(number){
$('#div_'+number).hide('slow');
$('#button_'+number).html("Show Table").click(function(){
showTable(number);
return false;
});
}
<div id="div_1" style="display:none"></div>
<button id="button_1" onClick="javascript:showTable(1)">Show Table</button>
<div id="div_2" style="display:none"></div>
<button id="button_2" onClick="javascript:showTable(2)">Show Table</button>
<div id="div_1" style="display:none"></div>
<button id="button_3" onClick="javascript:showTable(3)">Show Table</button>
The function is working fine at first. But after i show and hide it once, whenever I tried to show it again, it starts chaining show/hide/show/hide by itself without any clicks. And the more I do it, the longer it does the chaining. It seems it's just a loop that everytime it doubles the amount of looping(like show/hide for 2/4/8/16/32 times ....) the more I do the longer it loops. Anyone have a clue what's going on?
I tried to remove the click part in the hideTable function, the loop stops but still whenever I try to hit showTable, it will show then hide it self automatically like it's auto executing the stuff in the click function without any clicks...
Also is there anyway to use the jquery tagging style to call the function instead of using onclick? i know I can do like
$("#button_1").click(function(){......................});
$("#button_2").click(function(){......................});
$("#button_3").click(function(){......................});
but is there anyway I can group all of them together into a single function and still able to tell which button is clicked? Because I need a way to track which div to show and hide, and change the the text in corresponding button. Thank you very much in advance. m(_ _)m
You're piling on more and more redundant event handlers with each "click". That's what those calls to ".click()" in the handlers do — add another event handler.
You only need to add an event handler once. And adding an event handler does not remove the prior handler. Since you're using jQuery, use it to add the handlers, not old-fashioned "onclick" attributes.
Give all those <div> elements a class value, like "toggled".
<div id="div_1" style="display:none" class='toggled'>
You can do the same with the buttons. Then you can set up event handlers by using the class to refer to them in a jQuery selector.
A better way to do this is with toggle. Refer to JQuery toggle showhide
you should gove all your divs the same class eg class="toggleable" on the ones you want to toggle.
Then try:
jQuery(".toggleable input[type='button']").click(function()
{
jQuery(this).closest("div.toggleable").toggle();
});
This will put an onlick on your buttons inside your div which will find the closest parent div with class toggleable and will either hide/show your div.
To read about toggle():
http://api.jquery.com/toggle/
to read about selectors:
http://api.jquery.com/category/selectors/
I agree with Pointy but since I can't seem to add onto the answer, I must make another.
$('[data-show-table]').click(function() {
var $this_button = $(this);
$('#div_' + $(this).attr('data-show-table')).toggle(function() {
var msg = $(this).css('display') == 'none' ? 'Show table' : 'Hide table';
$this_button.html(msg);
});
});
<div id="div_1" style="display:none">Table 1</div>
<button id="button_1" data-show-table="1">Show Table</button>
<div id="div_2" style="display:none">Table 2</div>
<button id="button_2" data-show-table="2">Show Table</button>
<div id="div_3" style="display:none">Table 3</div>
<button id="button_3" data-show-table="3">Show Table</button>