jQuery events don't work after append [duplicate] - javascript

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
I'm trying to build my first "serious" webpage. I have just started and I stuck on applying old event listeners on new div section.
I would like to apply all old listeners on $(".novo").append("new div ..")
I have tried to use on() functions but it doesn't seem to work.
And also I have issues when adding new list. It adds to every present div. I want to add it only on clicked div.
<body>
<button class="novo">Novo</button>
<div class="container">
<div class="grupa">
<h1>To-Do List<span id="form"><i class="fas fa-edit"></i></span></h1>
<input type="text" placeholder="Add New Todo">
<ul>
<li><span><i class="fas fa-trash-alt"></i></span> Sabah</li>
</ul>
</div>
<script type="text/javascript" src="Assets\JS\projekt.js">
</script>
</body>
jS:
$("ul").on("click", "li", function(){
$(this).toggleClass("completed");
});
$("ul").on("click", "span", function(event){
$(this).parent().fadeOut(500, function(){
$(this).remove();
});
event.stopPropagation();
});
$("input[type='text']").keypress(function(key){
if(key.which === 13){
var todoText = $(this).val();
$("ul").append("<li><span><i class='fas fa-trash-alt'></i></span> " + todoText + "</li>");
}
});
$("#form").click(function(){
$("input[type='text']").fadeToggle(150);
});
$(".novo").on("click", function(){
$(".container").append("<div class='grupa'><h1>To-Do List<span id='form'><i class='fas fa-edit'></i></span></h1><input type='text' placeholder='Add New Todo'><ul><li><span><i class='fas fa-trash-alt'></i></span> Sabah</li></ul></div>");
});
Thank You!!

You have to move your .on() bindings to a level higher up. That is because when you apply the .on() bindings to the <ul> element, the said element must be available in the DOM at runtime. That means that the newly added <ul>, triggered by clicking on the .novo button, will not have any JS events bounds to it.
In this case, you should move the binding to a parent element that is already present at runtime, e.g. the .container element. Refactoring your code, you can do this:
$(".container").on("click", ".grupa ul li", function(){
$(this).toggleClass("completed");
});
$(".container").on("click", ".grupa ul span", function(event){
$(this).parent().fadeOut(500, function(){
$(this).remove();
});
event.stopPropagation();
});

Related

Dynamically create button and then remove that button when clicked in jquery

lHi,
I have some divs in a html doc and when I click the div I am adding a button. eg attached:
HTML:
<div class="week">
<div class="day wk1" id="day1">
<label for="day1">Test</label>
</div>
<div class="day wk1" id="day2">
<label for="day2">Test</label>
</div>
When I add a button by clicking on the div, no problem.
Add Button:
$(".day").click(function (e) {
e.preventDefault();
var check = $("#day7").width() - 2;
var insert = $(this).prop("id");
insert = `#${insert}`;
var par = $('<br class="break"><button class="testing">').html('Shift Manual Insert').width(check).css("background-color", "green");
par.appendTo(insert);
// console.log(insert);
});
When I remove the button by clicking on it it does remove it but simultaneously adds a new button as per the code above and below.
Remove Button:
$(".day").on('click','.testing', function(e){
e.preventDefault();
$(".break").remove;
$(this).remove();
});
I am sure I am doing something silly but for the life of me, I cannot figure it out? Please ignore my incorrect use of id's and classes, this is purely a test to gain experience.
Any help will be most appreciated.
Kind regards
Wayne
The event is getting propagated from the click handler on dom with .testing class to it's parent that is dom with .day class. .day have another click handler which add the element.So after removing the element again $(".day").click(function(e) { is getting fired which is adding back the button element
Replacee.preventDefault(); with e.stopPropagation(); in the click handler of .testing
$(".day").click(function(e) {
console.log('x')
e.preventDefault();
var check = $("#day7").width() - 2;
var insert = $(this).prop("id");
insert = `#${insert}`;
var par = $('<br class="break"><button class="testing">').html('Shift Manual Insert').width(check).css("background-color", "green");
par.appendTo(insert);
// console.log(insert);
});
$(".day").on('click', '.testing', function(e) {
e.stopPropagation();
$(".break").remove;
$(this).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="week">
<div class="day wk1" id="day1">
<label for="day1">Test</label>
</div>
<div class="day wk1" id="day2">
<label for="day2">Test</label>
</div>
Your button is present inside the div. So when you click the button, your div click event is also fired. This is due to event bubbling. Check https://www.w3schools.com/jquery/event_stoppropagation.asp
$(".day").on('click','.testing', function(e){
e.stopPropagation();
e.preventDefault();
$(".break").remove;
$(this).remove();
});

trigger method not working in jQuery

I have a page which has about 100 divs like this.
<div id="ListItem_JBEEB_847">
<span title="-HD">
<span>F</span>
<span style="pointer-events: none;">-HD</span>
</span>
</div>
The IDs have different number. And I am trying to click on this div/or the spam via jQuery one by one. So, I made a loop like this..
$('div').each(function(){
div = $(this).attr('id');
if(div){
if(div.includes('ListItem_JBEEB')){
get_div = jQuery("#" + div).trigger('click');
}
}
});
The above code should work, but for some reason it doesn't. It works with styling and all other DOM manipulations like changing color of the text via
jQuery("#" + div).css({'color': 'red'}) so the loop is ok, I also tried to target the span using jQuery("#" + div).find('span').trigger('click') but nothing happens.
btw: on the website, if you click any of the divs, the instantly show you more information, but with the this nothing changes, I am not sure if the trigger click is even working
Here is the updated version of your code. Instead of jQuery("#" + div).trigger('click'), you can use $(this).trigger('click') and separately, define what should happen on the click event.
$(document).ready(function() {
$('div').each(function() {
div = $(this).attr('id');
if (div && div.includes('ListItem_JBEEB')) {
$(this).trigger('click');
}
});
});
$('div').on('click', function() {
console.log($(this).attr('id') + ' got clicked..');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ListItem_JBEEB_847">
<span title="-HD">
<span>F</span>
<span style="pointer-events: none;">-HD</span>
</span>
</div>
<div id="ListItem_JBEEB_848">
<span title="-HD">
<span>F</span>
<span style="pointer-events: none;">-HD-1</span>
</span>
</div>
<div id="ListItem_JBEEB_849">
<span title="-HD">
<span>F</span>
<span style="pointer-events: none;">-HD-2</span>
</span>
</div>
You have to initialize the click event before calling it, You have to check that the particular click event is already initialized before calling it not not else it won't perform the click event.
For Example
// THIS WILL WORK
$(document).ready(function() {
jQuery("#ListItem_JBEEB_847").click(function(){
alert('a');
});
$('div').each(function(){
div = $(this).attr('id');
if(div){
if(div.includes('ListItem_JBEEB')){
jQuery("#" + div).click();
}
}
});
});
// THIS WILL NOT WORK
$(document).ready(function() {
$('div').each(function(){
div = $(this).attr('id');
if(div){
if(div.includes('ListItem_JBEEB')){
jQuery("#" + div).click();
}
}
});
jQuery("#ListItem_JBEEB_847").click(function(){
alert('a');
});
});

Dynamically adding event listener in html

I have two ULs in HTML ,one for user and one for shared user.
<div class="container">
<div id="userList" style=" ;width:45%;margin:10px;display:inline-block;vertical-align: top;">
<span>Users</span>
<ul class="usersUL">
<li title="Add user">user1</li>
<li title="Add user">user2</li>
</ul>
</div>
<div id="sharedUsers"style="width:45%;margin:10px;display:inline-block;vertical-align: top;">
<span>Shared Users</span>
<ul class="usersUL" >
</ul>
</div>
</div>
I want to add the li in UL one to the second list on user click and vice versa. The way I have done this is like so
//add to shared users from userslist
$("#userList li").click(function(){
$("#sharedUsers ul").append('<li title="Remove user">'+$(this).html()+'</li>');
//add to users list from shared users
$("#sharedUsers li").click(function(){
$("#userList ul").append('<li title="Add user">'+$(this).html()+'</li>');
$(this).remove();
});
$(this).remove();
});
I know what I doing wrong , I am not adding new event listener once the list item to sent back to the first UL from the second UL.But I am struggling to find the best way I can do this.
Here is the js fiddle: https://jsfiddle.net/4n7Ly4r2/
You can't nest a click event within a click event. Also, you need to bind the click event to the dynamic content using on():
JS Fiddle
$(document).on('click', '#userList li', function() {
$("#sharedUsers ul").append('<li title="Remove user">' + $(this).html() + '</li>');
$(this).remove();
});
$(document).on('click', '#sharedUsers li', function() {
$("#userList ul").append('<li title="Add user">' + $(this).html() + '</li>');
$(this).remove();
});
If you want to bind an event listener to a dynamically created element you need to use jQuery.on, like this $("#userList").on("click", "li", function(){ ... });.
Hope it helps.
Using 'on' or not does not really matter, as long as not defining function on the fly:
$('#userList li').click(relocLi);
$('#sharedUsers li').click(relocLi);
function relocLi() {
if ($(this).attr('title') == "Add user") {
$(this).attr('title', 'Remove user');
$("#sharedUsers ul").append($(this));
} else {
$(this).attr('title', 'Add user');
$("#userList ul").append($(this));
}
}

Find the id by class in nested div jquery

I have an html like this
<div class='click' id='1'>
one
<div class='click' id='2'>
two
<div class='click' id='3'>
three
<div class='click' id='4'>
four
<div class='click' id='5'>
five
</div>
</div>
</div>
</div>
if i have and click event on class click ,there is any way to return the id of which i click
such as
$('.click').click(function(){
alert('id whitch i click')
});
Becase if i click on three i allway get the id of one and two three.
Sure, just do this:
$('.click').click(function(e){ //e=event
alert($(this).attr("id")); // alert clicked element's id
e.stopPropagation(); // stop event propagation so it doesnt propagate to click 1 and click 2
})
Update: As mentioned by Felix Kling, you can access de DOM directly and use:
alert(this.id);
Demo: http://jsfiddle.net/tzJUN/ using this.id http://jsfiddle.net/c65x9/
If you keen : jQuery attr vs prop?
Stop propogation will stop the click event the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
API:
.stoppropagation - http://api.jquery.com/event.stoppropagation/
Code
$(document).ready(function () {
$('.click').click(function (event) {
event.stopPropagation();
alert($(this).prop("id")); //<< --- or this.id
});
});
$('.click').click(function(e){
$(this).attr("id");
alert($(this).attr("id"));//here you can see your clicked id
})
Yes. its simple
$(document).ready(function(){
$('.click').click(function(){
var ID=$(this).attr('id');
alert(ID);
//This ID varible will return ID of the Div Clicked
});
});

How to execCommand from li?

I'm losing focus on contentEditable when my menu li option is clicked so when I try to execCommand the selection no longer exists and does not affect the selection. How can I solve this without adding an input?
Updated:
** jsFiddle **
HTML
<div contenteditable=true>
paragraph1<br/>
paragraph2<br/>
paragraph3
</div>
<div contenteditable=true>
paragraph4<br/>
paragraph5<br/>
paragraph6
</div>
<input type=button id=show value=ToggleMenu>
<ul id=submenu>
<li>p</li>
<li>h1</li>
<li>h2</li>
</ul>
Javascript
$("#show").on("click",function(){
$("#submenu").toggle();
});
$("#submenu").on("click","li",function(){ //when this is clicked, editable div loses focus.
document.execCommand("formatBlock", false, $(this).text());
console.log($(this).text(), "was clicked");
});
You could do something like the following:
use mousedown instead of click
prevent the default event behaviour
get the relevant <li>'s content
call document.execCommand()
Demo: http://jsfiddle.net/timdown/SNTyY/13/
Code:
var $submenu = $("#submenu");
$("#show").on("click",function(){
$submenu.toggle();
});
$submenu.mousedown("li",function(e){
var li = e.target;
e.preventDefault();
document.execCommand("formatBlock", false, $(li).text());
});
$submenu.click(function(e) {
e.preventDefault();
});
One issue with your code is that it is not HTML compliant. For example, the sub menu should be
<ul id = 'submenu'>
<li>p</li>
<li>h1</li>
<li>h2</li>
</ul>
Instead of using li as a selector for your click event, try
$("#submenu").on("click", "li", function(){
document.execCommand("formatBlock", false, $(this).text());
alert($(this).text());
});
This throws an alert box on a click event, so you know the click is registering.
Fiddle

Categories

Resources