JavaScript/jQuery How to do .click function properly? - javascript

I have some buttons generated dynamically based on form inputs selected:
$.each(fields, function (i, field) {
var field_id = $('[name=' + field.name + ']').closest("fieldset").attr('id');
$("#results").append('<button id="jumpToThisStep" data-id="'+field_id.replace('q','')+'">'+field.value+ ' ' +'</button>');
});
}
In my doc.ready function I have the following:
$('#jumpToThisStep').click(function() {
var jump_to = $(this).data('id');
showStep(jump_to);
});
HTML:
<button id="jumpToThisStep" data-id="0"> ... </button>
<button id="jumpToThisStep" data-id="1"> ... </button>
<button id="jumpToThisStep" data-id="2"> ... </button>
Upon inspecting the elements they all have the proper data-id binding. But the only one that fires is the first one. What is preventing the others from preforming their .click?

You need to use event delegation here since your buttons are added dynamically so event delegation will help you to attach the click event to these newly created button:
$('#results').on('click', '.jumpToThisStep', function() {
var jump_to = $(this).data('id');
showStep(jump_to);
});
Also id is unique, you need to use class for your button instead.

HTML DOM id must be unique. use class instead of.
<button class="jumpToThisStep" data-id="0"> ... </button>
<button class="jumpToThisStep" data-id="1"> ... </button>
<button class="jumpToThisStep" data-id="2"> ... </button>
If you want to bind event on DOM which you add to document after document ready event, must to use event delegation.
$('#results').on('click', '.jumpToThisStep',function() {
var jump_to = $(this).data('id');
showStep(jump_to);
});

Related

Remove buttons added by jQuery

I am adding extra selects and text fields to a form using jQuery. However I want to be able to remove added text fields using the remove button.
Once a field has been added jQuery can not seem to detect it.
jQuery
var counter = 2;
$("#addButton").click(function () {
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'contact-list-div-' + counter).attr("class", 'contact-list-div');
newTextBoxDiv.after().html('<select></select>' +
'<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" >' + '<button type="button" class="removeButton" id="removeButton-' + counter + '">Remove Button</button>');
newTextBoxDiv.appendTo("#contact-list");
counter++;
});
$(".removeButton").click(function() {
alert(this.id); //this never shows, only on the element that was
//added directly added using html, in this case removeButton-1
});
HTML
<div id="contact-list">
<div class="contact-list-div" id="contact-list-div-1">
<select></select>
<input>
<button type='button' class='removeButton' id='removeButton-1'>Remove Button</button>
</div>
</div>
<input type='button' value='Add Button' id='addButton'>
$('#contact-list').on('click', '.removeButton', function() {
//Your code
});
You need to use event-delegation:
$(document).on('click', '.removeButton',function() {
$(this).parents('.contact-list-div').remove();
});
You appending content to your DOM after the event-listener for your click on .removeButton is registered. So this element does not exist at the time your binding a click event to it.
Through event-delegation you are able to bind an event-listiner to an existing parent (document in this case, but #contact-list would be working too). And this will listen to all events of its descendants matching the .removeButton - selector.
Demo
This is because you are binding the events to elements that do not yet exist.
Use jQuery delegation to enable handlers on not yet existing elements:
$("body").on("click", ".removeButton", function() {
alert(this.id);
});
You add the click listener only at the first button.
Try using delegate:
$(document).delegate(".removeButton", "click", function() {
alert(this.id);
});
This tells the document that whenever a event click occours on an element with class "removeButton" it should call that callback
(You can see it working here)
Because the element is dynamicly added with jQuery, the normal .click event of jQuery will be not able to detect the new added elements.
Use instead .on. See the example below:
$("body").on("click", ".removeButton", function() {
alert(this.id); //this never shows, only on the element that was
//added directly added using html, in this case removeButton-1
});

how to judge which button has been clicked using there className instead of ID

I have 100 buttons in a table having same class name but different id c-1,c-2,....,c-n <input type="button" class="btn-c" id="c-1" value="ADD">
how will i Know which button has been clicked using their className and whithout using onclick event on the each button
<input type="button" ... onclick="call_function(this);"
for simplicity let say I want to alert(button.id); on the click of any of the 100 buttons
If you have so many buttons, it makes sense to use event delegation:
$('table').on('click', '.btn-c', function() {
alert(this.id); // will get you clicked button id
});
This is optimal approach for performance standpoint as you bind only one event handler to parent element and benefit from child element event bubbling.
UPD. This is pure javascript version of the same code:
document.getElementById('table').addEventListener('click', function(e) {
if (/\bbtn-c\b/.test(e.target.className)) {
alert(e.target.id);
}
}, false);
Demo: http://jsfiddle.net/zn0os4n8/
Using jQuery - attach a click handler to the common class and use the instance of this to get the id of the clicked button
$(".btn-c").click(function() {
alert(this.id); //id of the clicked button
});
You need to attach an event to a parent element and listen for the clicks. You can than use the event object to determine what is being clicked on. You can check if it is the element you want and do whatever you want.
document.body.addEventListener("click", function (e) { //attach to element that is a parent of the buttons
var clickedElem = e.target; //find the element that is clicked on
var isC = (clickedElem.classList.contains("c")); //see if it has the class you are looking for
var outStr = isC ? "Yes" : "No"; //just outputting something to the screen
document.getElementById("out").textContent = outStr + " : " + clickedElem.id;
});
<button class="d" id="b0">x</button>
<button class="c" id="b1">y</button>
<button class="c" id="b2">y</button>
<button class="c" id="b3">y</button>
<button class="d" id="b4">x</button>
<div id="out"></div>
Note: this is not going to work in older IEs without polyfills.

Getting element id with jquery

The code should print the id of the selected div but it does not. I did not find the error. Thanks for help.
HTML
<body>
<div id="form_area">
<div>
<button onclick="return add_row();" style="width:100%;">Add Row</button>
</div>
</div>
</body>
Javascript
$(document).ready(function() {
$('#form_area div').click(function(e) {
console.log($(this).attr('id'));
});
});
function add_row() {
var random_id = Math.floor((Math.random() * 1000) + 1);
$('#form_area').prepend('<div id="' + random_id + '" class="form_row"></div>');
}
Ok, I think I understand what you are missing. You are trying to log the ID after adding a row using add_row function,
.form_row is added dynamically to the DOM. So when executing $('.form_row').click(, there is no .form_row to bind the handler. The below way of using .on method binds the handler to #form_area and executes the handler only when the click event is from .form_row
$('#form_area').on('click', '.form_row', function () {
console.log(this.id);
});
$('#form_area div') selects the div inside the div #form_area which doesn't have an ID
Below comment in html shows which div is selected,
<div id="form_area">
<div> <!-- $('#form_area div') selects this div-->
<button onclick="return add_row();" style="width:100%;">Add Row</button>
</div>
</div>
To access id use 'on' as your div is dynamically generated:
$(document).ready(function() {
$('#form_area').on('click', '.form_row', function () {
console.log(this.id);
});
});
Try console.log($('#form_area div').attr('id'));
Firstly, you have jQuery - you should use that to register your event handlers instead of using obsolete, error prone inline event handlers.
Secondly, your button handler is inside #formarea and so is also triggering the click handler since the button's parent has no ID. This is probably not desired.
Thirdly, your event handlers need to be delegated because you're trying to catch events on dynamically added elements.
So, remove the onclick attribute and add this:
$('#formarea button').on('click', addRow);
$('#formarea').on('click', '.form_row', function() { // delegated, for dynamic rows
console.log(this.id); // NB: not $(this).attr('id') !!
});
function addRow(ev) {
// unmodified
}
See http://jsfiddle.net/alnitak/aZTbA/

Grab attribute of element clicked - using on click event handler

In my html I have a screen with with about 25 thumbnails, and each of them has a like button in the format:
<input type="button" class="btn btn-primary btn-small" id="likeBtn" data-id="545206032225604" value="Like">
Where data-id is different for each image.
The idea is to then use that id to make a POST request to the facebook graph API and like the post.
I have a event listener like so:
$('#likeBtn').click(function () {
facebook.likePhoto(controller.likeReady);
});
The issue I am having is I am unsure how to grab that data-id from the element that is actually clicked.
Let me know if I can provide any more information.
Thanks
Use .data()
$('#likeBtn').click(function () {
var data_id = $(this).data('id');
facebook.likePhoto(controller.likeReady);
});
Read this
Id attribute must be unique . Use classes Instead.
change HTML
Use class likeBtn instead of id likeBtn as you said you have many buttons like this .
<input type="button" class="btn btn-primary btn-small likeBtn" data-id="545206032225604" value="Like">
Noe your js becomes
$('.likeBtn').click(function () {
var data_id = $(this).data('id');
facebook.likePhoto(controller.likeReady);
});
Read Two HTML elements with same id attribute: How bad is it really?
Updated after OP's comment
Use .on()
As elements are added dynamically you can not bind events directly to them .So you have to use Event Delegation.
$(document).on('click','.likeBtn',function () {
var data_id = $(this).data('id');
facebook.likePhoto(controller.likeReady);
});
Syntax
$( elements ).on( events, selector, data, handler );
Try this:
$('#likeBtn').click(function () {
var dataId = $(this).prop('data-id');
console.log(dataId); //or do something else
facebook.likePhoto(controller.likeReady);
});
Though, if I understand this correctly, do you have multiple elements with the id likeBtn?
$('#likeBtn').click(function () {
var id;
id = $(this).attr('data-id');
facebook.likePhoto(controller.likeReady);
});

in Javascript Dom ,the newly added element can't be selected?

<body>
<div id="options">
<p class="input">
<input type="text"/>
<a class="remove" >Remove</a>
</p>
<p class="input">
<input type="text"/>
<a class="remove" >Remove</a>
</p>
</div>
<a href = "#" id ="click" >Add Option</a>
</body>
And:
$(function() {
$("#click").click(function add_option(){
var options = document.getElementById("options");
var p=document.createElement("p");
p.setAttribute("class","input");
var input=document.createElement("input");
input.setAttribute("type","text")
options.appendChild(p);
p.appendChild(input);
var a=document.createElement("a");
a.setAttribute("class","remove");
var text = document.createTextNode(" Remove");
a.appendChild(text);
insertAfter(a,input);//if exist insertAfter
}
)
$(".remove").click(function remove_option(){
$(this).parent().remove();
})
})
when i click Add Option,it works,but when i click the remove of the newly added,it doesn't remove .whether the $(".remove") selector have effects on it?(the initial two remove work).how to make the newly added elements work?
try using it with .live()
$(".remove").live("click",function(){
$(this).parent().remove();
});
At the time you bind the event handler to the .remove elements, the new elements don't exist yet (obviously). That's why jQuery cannot find them and bind the event handler.
You can solve this using .live [docs] or .delegate [docs]:
$(".remove").live('click', function(){
$(this).parent().remove();
});
These methods bind the event handler to the document root and inspect every click event (in this case) and test whether the target matches the selector. If it does, the handler is executed.
I also would advise you to not mix plain DOM operations and jQuery like that. Your click event handler can be written in a more concise way:
$("#click").click(function(){
$('<p />', {'class': 'input'})
.append($('<input />', {type: 'text'})
.append($('<a />', {'class': 'remove', href: '#', text: 'Remove'})
.appendTo('#options');
});
There are exceptions, like accessing properties of DOM elements, but here you really should make use of jQuery.
This works: http://jsfiddle.net/UJERQ/
$("#click").click(function add_option(){
$("#options").append('<p class="input"><input type="text"/><a class="remove" > Remove</a></p>')
addTheClicks();
})
function addTheClicks(){
var btns = $(".remove");
var btnsLength = btns.length;
for(i=0;i<btnsLength;i++){
var hasClickAlready = $.data(btns.eq(i).get(0), 'events' );
if(hasClickAlready == null){
btns.eq(i).click(function(){
$(this).parent().remove()
})
}
}
}
addTheClicks();

Categories