JS Events not attaching to elements created after load - javascript

Problem: Creating an Element on a button click then attaching a click event to the new element.
I've had this issue several times and I always seem to find a work around but never get to the root of the issue. Take a look a the code:
HTML:
<select>
<option>567</option>
<option>789</option>
</select>
<input id="Add" value="Add" type="button"> <input id="remove" value="Remove" type="button">
<div id="container">
<span class="item">123</span>
<br/>
<span class="item">456</span>
<br/>
</div>
JavaScript
$(".item").click(function () {
if ($("#container span").hasClass("selected")) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
$("add").click(function() {
//Finds Selected option from the Select
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = choice;//Value from Option
newSpan.className = "item";
var divList = $("#container");
divList.appendChild(newSpan);//I've tried using Jquery's Add method with no success
//Deletes the selected option from the select
})
Here are some methods I've already tried:
Standard jQuery click on elements with class "item"
Including using the `live()` and `on()` methods
Setting inline `onclick` event after element creation
jQuery change event on the `#Container` that uses Bind method to bind click event handler
Caveat: I can not create another select list because we are using MVC and have had issues retrieving multiple values from a list box. So there are hidden elements that are generated that MVC is actually tied to.

Use $.on instead of your standard $.click in this case:
$("#container").on("click", ".item", function(){
if ( $("#container span").hasClass("selected") ) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
It looks to me like you want to move the .selected class around between .item elements. If this is the case, I would suggest doing this instead:
$("#container").on("click", ".item", function(){
$(this)
.addClass("selected")
.siblings()
.removeClass("selected");
});
Also note your $("add") should be $("#add") if you wish to bind to the element with the "add" ID. This section could also be re-written:
$("#add").click(function() {
$("<span>", { html: $("select").val() })
.addClass("item")
.appendTo("#container");
});

Related

Input value of a cloned div not changing or firing events

I have a mock hidden div that I edit, clone and show to users. In this div is an input for which I set the value attribute using jQuery (tried with probably all methods). After I generate the new div and show it to users, the input does not fire any kind of events (focus, focusout, change) neither does the value of input change in HTML.
What am I missing or doing wrong?
Edit (code): HTML
<div class="item-wrapper" id="mock-item">
<div class="item-img"></div>
<div class="item-primary">
<p class="item-name">Foo Bar</p>
<input type="text" class="set-amount">
</div>
</div>
JS:
$("div.item-wrapper").click((e) => {
let item_id = e.currentTarget.id
let itemDetails = {
item_name: $(`#${item_id} .item.name`).text(),
suggested_amount: $(`#${item_id} #item-amount`).text(),
icon_url: $(`#${item_id} .item.big`).attr("style"),
}
$(".item-img", tmp).attr("style", itemDetails.icon_url)
$("#mock-item .item-name").text(itemDetails.item_name)
$("#mock-item .set-amount")[0].setAttribute("value", itemDetails.suggested_amont)
$("#mock-item").clone().removeAttr("id").appendTo(".item-wrapper").show()
})
Cloning an element removes all the event listeners from it. If you would like to listen for all event listeners on elements with a given selector, you can use jQuery's .on:
$(document).on("click", ".class", function () {
const $this = $(this);
});
You could also set the withDataAndEvents parameter on .clone to true: .clone(true).

How to select element after it was added to DOM

On my HTML I have buttons list and text input field. Input field is to add extra buttons to my buttons list.
On jQuery I have eventListener when one of these buttons with .choices is clicked console log its value.
It works fine without any errors. But when I add extra button to my list with same class (.choices) new button appears but it doesn't respond to my click.
Any suggestions?
<div class="buttons">
<button id="button0" class="choices">Running</button>
<button id="button1" class="choices">Yoga</button>
<button id="button2" class="choices">Karate</button>
</div>
JS
$("#add-button").click(function(){
var inputValue = $("#add-input").val();
var generatedId = "button" + healthyChoices.length;
healthyChoices.push(inputValue);
$("<button>").attr("id", generatedId).appendTo(".buttons");
$("#" + generatedId).attr("value", inputValue);
$("#" + generatedId).attr("class", "choices");
$("#" + generatedId).text(inputValue);
$("#add-input").val("");
});
$(".choices").click(function(){
var selectedGroup = $(this).val();
console.log(selectedGroup);
});
The .click method does not handle elements dynamically added to the DOM. You should be using the .on method (as indicated by dfsq's comment).
See this SO post: Difference between .on('click') vs .click()

How to dynamically remove elements in javascript?

Is there a way to dynamically remove elements with javascript or jquery. Suppose I have a function createElements() which creates new element and another function removeElement() which is suppose to remove the corresponding element. You will notice that when you run the snippet that when you click on the remove button all the element is gone! How could I implement this code? Isn't there a jquery selector where i could simply use removeElement(this) or somenething like that? Any suggestions are most welcome :) thank you.
function createElements() {
const boom = document.getElementById('boom');
boom.insertAdjacentHTML(
'beforeend', '<div class="newElem"><p >new element created dynamically yay!</p><button onclick="removeElement()">remove</button></div>'
);
}
function removeElement() {
alert('element removed dynamically boOoOoOoOooo!')
$('.newElem').remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<br>
<button onclick="createElements()">Create new element</button>
You can do it like this:
function createElements() {
const boom = document.getElementById('boom');
boom.insertAdjacentHTML(
'beforeend', '<div class="newElem"><p >new element created dynamically yay!</p><button onclick="removeElement(this)">remove</button></div>'
);
}
function removeElement(element) {
alert('element removed dynamically boOoOoOoOooo!')
$(element).parent(".newElem").remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<br>
<button onclick="createElements()">Create new element</button>
You just need to follow one single API. Use either pure JavaScript or jQuery. I would also suggest you to use unobstructive approach. Also, the way you remove the elements is wrong. You are removing everything.
See this way:
$(function() {
$("button#add").click(function() {
$("#boom").after('<div class="newElem"><p >new element created dynamically yay!</p><button class="remove">remove</button></div>');
});
$(document).on("click", ".remove", function() {
alert('element removed dynamically boOoOoOoOooo!')
$(this).closest(".newElem").remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<button id="add">Create new element</button>
To be able to always delete the div that encompasses the remove button, you have to traverse the DOM tree. There are lots of jQuery goodies for this: http://api.jquery.com/category/traversing/
In this particular case, I would do the following:
var elementCounter = 0;
function createElements() {
const boom = document.getElementById('boom');
boom.insertAdjacentHTML(
'beforeend', '<div class="newElem"><p >'+elementCounter+': new element created dynamically yay!</p><button onclick="removeElement(event)">remove</button></div>'
);
elementCounter++;
}
function removeElement(event) {
alert('element removed dynamically boOoOoOoOooo!')
$(event.target).closest('.newElem').remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<br>
<button onclick="createElements()">Create new element</button>
So you pass on the click event to the function as a parameter, and then with event.target you find out which button was clicked. $(event.target).closest(".newElem") will get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

remove onclick when attached to children

I have the following code:
layoutOverlaysBldg = $("#layout-overlays-bldg")
layoutOverlaysBldg.on("click", "div", function(event) {
var floor;
console.log("floornum: " + this.dataset.floornum);
floor = parseInt(this.dataset.floornum);
...
$("#choose-floor").fadeOut();
$("#choose-apt").fadeIn();
});
later - based on data I'm getting back from the DB - I want to remove some of the .on("click", "div", ...) from only some of the divs. I already have the selector that is getting the right divs but I cannot figure out how to remove the click event. I have tried .off("click") after selecting the right div but it has no effect.
This issue here is because you are using a delegated event. You can add or remove the event for all child elements, but not individual ones given your div selector.
With that in mind the easiest way to do what you need is to add the event based on a class, then add and remove that class on the children as needed. Something like this:
layoutOverlaysBldg = $("#layout-overlays-bldg")
layoutOverlaysBldg.on("click", "div.clickable", function(event) {
// your code...
});
You can then enable/disable the event on the child div by adding or removing the .clickable class.
You can try like this :
Example :
<div id="test">
<div id="first">first</div>
<div id="second">second</div>
</div>
<div onclick="unbindSecondDiv();">UNBIND</div>
<script>
function unbindSecondDiv()
{
test = $("#second")
test.unbind("click");
alert('Selected Area Click is Unbind');
}
$(document).ready(function(){
//BIND SELECTED DIV CLICK EVENT
test = $("#test > div")
test.bind("click" , function(event) {
alert($(this).attr('id'));
});
});
</script>
In the above example , selected DIV elements click event is bind.
And after execute function unbindSecondDiv() , second DIV click event will be unbind.
Have a try , may helps you.

jquery mutiple div with a single definition script

i have this jQuery code:
$(document).ready(function () {
$("#hide").click(function () {
$("div1").hide();
});
$("#show").click(function () {
$("div1").show();
});
});
and this jsp/html
for{int=0;i<V_loopnumber;i++)
{
%>
<button id='show' height:10px>showit</button>
<div1>
something
<button id='hide' height:10px>hideit</button>
</div1>
<%
}
For example if I have 3 elements, it produces 3 divs. However,if I push the button all the divs will be showed or hided cause they got the same name.
how can I differentiate the button with the respective divs?
Your markup has a few problems. You can not assign the same ID twice. Also div1 is not a valid tag name.
Perhaps you can restructure your markup along the lines of the following example:
<div class="container">
<button class="show">showit</button>
<div class="inner">
something
<button class="hide">hideit</button>
</div>
</div>
I assigned the buttons classes instead of ids and got rid of the div1 elements.
Now you can listen for a click event on the buttons and hide the related elements using the .closest() (http://api.jquery.com/closest/) method like this:
$(".hide").click(function () {
$(this).closest(".inner").hide();
});
$(this).closest(".inner") will retrieve the the closest element with the class inner up in the dom tree.
$(".show").click(function () {
$(this).parent().find(".inner").show();
});
$(this).parent().find(".inner") will go up one level in the dom tree and find the element with the class inner.
http://jsfiddle.net/KGk7B/
First, element ids must be unique. Use a class instead. Second, <div1> isn't a valid tag. Use a div with a class instead. Third, use traversal functions to find the specific element to toggle.
$(document).ready(function () {
$(".hide").click(function () {
$(this).closest('.show-hide-container').hide();
});
$(".show").click(function () {
$(this).next('.show-hide-container').show();
});
});
for{int=0;i<V_loopnumber;i++)
{
%>
<button class='show' height:10px>showit</button>
<div class="show-hide-container">
something
<button class='hide' height:10px>hideit</button>
</div>
<%
}
id must be unique on your page, use class
<button class='show' height:10px>showit</button>
and use $(this) in event callback function instead of using selector
$(".hide").click(function(){
$(this).parent().hide(); // this is hard select of your div1, i wrote only for your html
});
IMPORTANT: Use div instead of div1, div1 tag is undefined.

Categories

Resources