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/
Related
I am appending item by jQuery. But after appending can't bind the event on the appended item. I am appending as follows:
var item = '<div id="'+newInputId+'" class="col-md-9" style="padding-right: 0px;">';
item += '<input id="txtInScope" type="text" value="'+currentScopeVal+'" class="form-control" readonly="readonly"/>';
item += '</div>';
item += '<div id="inScopeActionDiv'+newInputId+'" class="col-md-3" style="padding-left: 2px;">';
item += '<button type="button" class="btn btn-warning btn-sm remButton" title="Remove this item">Remove Item</button>';
item += '</div>';
$('#inScopeDiv').append(item);
And after appending this I want to bind a click event on the above remButton class as below:
$("#inScopeDiv").delegate(".remButton", "click", function(){
alert('you clicked me again!');
});
$('#inScopeDiv').on('click', '.remButton', function() {
alert("working");
})
$('.remButton').live('click', function() {
alert('live');
})
But no result. What can I try next?
$('.remButton').live('click', function() {
alert('live');
})
jquery method live is not valid anymore:
"As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live()."
Source: jquery live
Little explanation about event attachment:
You must realize that a target what you want to add a event, exists BEFORE to call the add event function(in this case with the method on of jQuery).
on another hand, exists with jquery a manner to make work a event attachment without the existence of the element before:
$('html').on('click', '#inScopeDiv .remButton', function () {
alert('works!');
});
Bind it on a parent that is not dynamic but always in the DOM.
You need to add the listener each time you add an item:
$('#inScopeDiv').append(item)
.off() //unbind old listeners so no duplicate listeners
.on('click', '.remButton', function() {
alert("working");
});
You could store the appended div in a variable using .appendTo and then you could attach the click event directly to the variable. See it working: JSFiddle
$(".appendDiv").click(function () {
var item = "<div>I'm a new div!</div>";
var appended_div = $(item).appendTo(".container");
appended_div.click(function () {
alert("Working!");
});
});
On a page I have couple of divs, that look like this:
<div class="product-input">
<input type="hidden" class="hidden-input">
<input type="text">
<button class="remove">X</button>
</div>
I'm trying to bind an event to that remove button with this code (simplified):
$('.product-input').each(function() {
product = $(this);
product_field = product.find('.hidden-input');
product.on('click', '.remove', function(event) {
product_field.val(null);
});
});
It works perfectly when there is only one "product-input" div. When there is more of them, all remove buttons remove value from the hidden field from the last product-input div.
https://jsfiddle.net/ryzr40yh/
Can somebody help me finding the bug?
You dont need to iterate over the element for binding the same event. you can rather bind the event to all at once:
$('.product-input').on('click', '.remove', function(event) {
$(this).prevAll('.hidden-input').val("");
});
If the remove buttons are not added dynamically, you will not need event delegation:
$('.remove').click(function(event) {
$(this).prevAll('.hidden-input').val("");
});
Working Demo
You need to declare product and product_field as local variables, now they are global variables. So whichever button is clicked inside the click handler product_field will refer to the last input element.
$('.product-input').each(function() {
var product = $(this);
var product_field = product.find('.hidden-input');
product.on('click', '.remove', function(event) {
product_field.val(null);
});
});
Demo: Fiddle
But you can simplify it without using a loop as below using the siblings relationship between the clicked button and the input field
$('.product-input .remove').click(function () {
$(this).siblings('.hidden-input').val('')
})
Demo: Fiddle
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
});
I'm trying to get an programatically added li data-val on click, as below:
$(function () {
$("#bpadd").click(function () {
var bpinput = document.getElementById("bpinput").value;
$('#bpitem').append('<li data-val="' + bpinput + ' clicked">' + bpinput + '</li>');
});
$('#bpitem li').click(function () {
alert($(this).attr('data-val'));
});
This is the html sample:
<input type="text" id="bpinput">
<input type="button" id="bpadd" value="+">
<ul id="bpitem">
<li data-val="Test 1 clicked">Test 1</li>
</ul>
If I click in Test 1, it works, but nothing happens when I click in a new item, why is that so?
You need to use the .ondoc function on some selector that'll work for every newly added element, like this:
$('#bpitem').on('click', 'li', function () {
alert($(this).attr('data-val'));
});
As you can see on the docs, the function will bind the events on newly-added elements that match the selector rather than just binding it to existing ones like the .click function does.
Try this:
$('#bpitem').on('click', 'li', function () {
alert($(this).attr('data-val'));
});
The .click() method binds the click handler only to elements that exist at the time that line of code runs. If you use .on(), you bind the handler to your parent #bpitem element (which exists initially) but when a click occurs jQuery checks if the clicked child element matches the selector in the second parameter and thus it works on children of #bpitem that were added dynamically.
try:
$('#bpitem').on('click', 'li', function() {
alert('clicked');
);
This will dynamically add event listeners to ALL bpitem li elements instead of the ones that are there when this is first ran
I have the following code to create some element:
<div id="parent">
<div id="block_1" >
<div>
<input type="text">
</div>
<img src="arrow.jpg">
<div>
<input type="text">
</div>
<div>Remove</div>
</div>
</div>
the result look like this:
When user presses the ADD button it will go to a Javascript function and create the same block of div. Here is the code:
function add_block() {
var curDiv = $('#parent');
var i = $('#parent div').size()/4 + 1;
var newDiv='<div id="block_'+ i + '" class="parent_div">' +
'<div>' +
'<input type="text">' +
'</div>' +
'<img src="arrow.jpg">' +
'<div>' +
'<input type="text">' +
'</div><div><a class="remove_block" href="#">Remove</a></div>' +
'</div>';
$(newDiv).appendTo(curDiv);
};
Whenever the user press the "Remove" link on the left hand side of the block, that corresponding block should be removed. And this is what I did:
$('a.remove_block').on('click',function(events){
$(this).parents('div').eq(1).remove();
});
The problem is that only the remove in the original block work, the rest didn't . Anybody know why?
I am new to jQuery and Javascript, so I really appreciate any help and suggestion
Note: I use jQuery 2.0.3
Because it's dynamic content, you can't bind events like the static content, it will not bind to the elements because they don't appear at the time you bind.
So you should bind event like this:
$('#parent').on('click', 'a.remove_block', function(events){
$(this).parents('div').eq(1).remove();
});
You need to use event delegation for dynamically added elements. Even though you have used .on() the syntax used does not use event delegation.
When you register a normal event it adds the handler to only those elements which exists in the dom at that point of time, but when uses event delegation the handler is registered to a element which exists at the time of execution and the passed selector is evaluated when the event is bubbled upto the element
$(document).on('click', '.remove_block', function(events){
$(this).parents('div').eq(1).remove();
});
$('a.remove_block').on('click',function(events){
$(this).parents('.parent_div').remove();
return false;
});
I had the situation where the dynamic element to remove wasn't a descendant of my event listener:
siteSel.on('select2:select', function (e) {
// remove some other dynamic element on page.
});
Solution I found was using when() method.
siteSel.on('select2:select', function (e) {
let dynamicElement = $('.element');
$.when(dynamicElement).then(dynamicElement.remove());
});
You can use the .live for this:
$('body').live('click','#idDinamicElement', function(){
// your code here
});