This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 5 years ago.
Currently, I am creating something that will simply allow me to create tasks, click them when they are done and swipe left to get rid of them.
The problem I am having is that when the new tasks are appended, they are not affected by any of the JQuery events on in the script.
Tl;dr: appended divs are not affected by the below javascript, how can I fix this issue?
<div class="app">
<div class="appHeader">
<h2>Tasks</h2>
<form class="createTask">
<input type="text" class="createTaskInput" size="10" maxlength="25" placeholder="Type here to create your task..." //>
</form>
</div>
<div class="task">
<div class="summary">This is an example task
<br>When you complete a task, click the red button
<br>Should you want to remove a task, swipe left on the task.
</div>
<div class="completion"></div>
</div>
</div>
<script>
$(".completion").on({
'touchstart': function() {
$(this).addClass("completed")
}
});
$(document).ready(function() {
$("div.task").on("swipeleft", swipeleftHandler);
function swipeleftHandler(event) {
$(event.target).addClass("swipeleft");
}
});
$(document).ready(function() {
$(".createTask").submit(function(e) {
var value = $(".createTaskInput").val();
$('.app').append('<div class="task"><div class="summary">' +
value + '</div><div class="completion"></div></div>')
e.preventDefault();
});
});
</script>
That is because you add the event listener before you add the objects.
A workaround is to add the event listener to the body like this.
$( "body" ).on( "swipeleft", "div.task", swipeleftHandler );
and
$(" body ").on( "touchstart", ".completion", function(){
$(this).addClass("completed")
});
Because you are not binding them after you add a new task see below
function swipeleftHandler(event) {
$(event.target).addClass("swipeleft");
}
function touchHandler(event) {
$(event.target).addClass("completed");
}
$(document).ready(function() {
$(".completion").on('touchstart', touchHandler);
$("div.task").on("swipeleft", swipeleftHandler);
$(".createTask").submit(function(e) {
var value = $(".createTaskInput").val();
var totalExisting = $('div.task').length;
$('.app').append('<div class="task"><div class="summary">' + value + '</div><div class="completion"></div></div>');
var newTask = $('div.task').eq(totalExisting);
newTask
.on("swipeleft", swipeleftHandler)
.on('touchstart', touchHandler);
e.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="appHeader">
<h2>Tasks</h2>
<form class="createTask">
<input type="text" class="createTaskInput" size="10" maxlength="25" placeholder="Type here to create your task..." //>
</form>
</div>
<div class="task">
<div class="summary">This is an example task
<br>When you complete a task, click the red button
<br>Should you want to remove a task, swipe left on the task.
</div>
<div class="completion"></div>
</div>
</div>
Related
I'm trying to Use a combination of JS and Jquery here to select the input text (a few elements previous), when the button is clicked.
I know how to do this just using JS but i want to understand how to do this using jQuery. I get the error message in console: TypeError: ele.setSelectionRange is not a function. Which I take it means that it is not defining the Input Value the way I need it to.
I'm not using ID or Class here to identify the input.
Can someone help me here? Thanks
JS
$(document).ready(function () {
$('.jimmy').click(function(e){
e.preventDefault;
jimsFunction(this);
});
});
function jimsFunction(input) {
let ele = $(input).parent().siblings(':first-child').children();
ele.select();
ele.setSelectionRange(0, 99999);
navigator.clipboard.writeText(ele.value);
alert("Copied: " + ele.value);
}
HTML
<div class="colbody">
<div>
<input type="text" value="www.brave.com" readonly>
</div>
<div>
View
</div>
<div>
<button type="button" class="jimmy">Copy URL</button>
</div>
</div>
setSelectionRange(0, 99999) is not a method on jQuery object. Use it on DOM element.
So try: [0]
Example:
$('.jimmy').click(function(e) {
e.preventDefault;
jimsFunction(this);
});
function jimsFunction(input) {
let ele = $(input).parent().siblings(':first-child').children();
ele[0].select();
ele[0].setSelectionRange(0, 99999);
navigator.clipboard.writeText(ele[0].value);
alert("Copied: " + ele[0].value);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="colbody">
<div>
<input type="text" value="www.brave.com" readonly>
</div>
<div>
View
</div>
<div>
<button type="button" class="jimmy">Copy URL</button>
</div>
</div>
Recently i tried to create dynamic elements and try to delete them. the problem is, every time i want to delete a specific element, the one get remove is the very first created element. i already try to use live() and on() method too. any idea why is this happen? thanks for help
<body>
<h2>To Do List</h2>
<div id="inputfield">
<input type="text" placeholder="add here" id="input">
<button onclick="addlist()">Add</button>
</div>
<div id="content">
</div>
addlist = () => {
let input = document.getElementById("input").value;
let html = '';
html += `<div style="display: flex; justify-content: center; flex-direction: row" class="main">
<div id="list">
<span id="isilist">` + input + `</span>
</div>
<div id="option">
<button id="deletebtn">delete</button>
</div>
</div>`
$("#content").append(html)
}
$("#content").on('click', 'button', function(){
$("#list").remove()
$("#option").remove()
})
or you can try it on https://jsfiddle.net/tLd3kvyo/
The problem was every time you created a new element, they all have the same id="list" hence when you tried removing it, the browser didn't know which id("#list") you were refering to and hence removed the first one. So,
Please change your delete code to this:
$("#content").on('click', 'button', function(){
$(this).parent().prev().remove();
$(this).parent().remove();
})
This will remove the button's parent and previous element too.
I would really appreciate your help here. I want list item that is created with the "#save" button to be removed on click. The commented methods don't work. If i put 'h1' or something else it works no problem. Also the "#delBtn" button removes all list items no problem. But i cant;t make it work when i click on a list item to be removed. Thanks for your time in advance.
function Contact(first, last) {
this.firstName = first;
this.lastName = last;
}
$(document).ready(function() {
let a_contacts = [];
$("#delBtn").click(function(){
$("li").remove();
});
$("#save").click(function(){
event.preventDefault()
var inputtedFirstName = $("input#new-first-name").val();
var inputtedLastName = $("input#new-last-name").val();
var newContact = new Contact(inputtedFirstName, inputtedLastName);
$("ul#contacts").append("<li class='contact'>" +'First Name: '+ newContact.firstName + ' Last Name: '+ newContact.lastName + "</li>");
a_contacts.push(newContact);
$("input#new-first-name").val("");
$("input#new-last-name").val("");
});
//---------------------------------------------------------------
// $("li").click(function() {
// $(this).remove();
// });
// $('li').click(function(e){
// $(e.target).remove();
// });
});
<!DOCTYPE html>
<html>
<head>
<link href="CSS/bootstrap.css" rel="stylesheet" type="text/css">
<link href="CSS/style.css" rel="stylesheet" type="text/css">
<script src="JS/jquery-3.2.1.js"></script>
<script src="JS/myjava.js"></script>
<title>Address book</title>
</head>
<body>
<div class="container">
<h1 id="haha" >Address book</h1>
<div class="row">
<div class="col-md-6">
<h2>Add a contact:</h2>
<form id="new-contact"><!-- form -->
<div class="form-group">
<label for="new-first-name">First name</label>
<input type="text" class="form-control" id="new-first-name">
</div>
<div class="form-group">
<label for="new-last-name">Last name</label>
<input type="text" class="form-control" id="new-last-name">
</div>
<button id="delBtn" class="btn">Add</button>
<button id="save" class="btn">Save</button>
</form><!-- form -->
<h2>Contacts:</h2>
<ul id="contacts">
</ul>
</div>
<div class="col-md-6">
<div id="show-contact">
<h2></h2>
<p>First name: <span class="first-name"></span></p>
<p>Last name: <span class="last-name"></span></p>
</div>
</div>
</div>
</div>
</body>
</html>
Try a delegated event listener. I believe that since these elements are being created dynamically, the event listeners don't find them and attach when the page loads. Try doing something like this:
`$(document).on('click', 'li', function () {
$(this).remove();
})`
What is happening is the document takes the event listener on page load and passes click effects to all li's after they are created.
This is most probably because you bind your click event on li elements that are already in your page at load time, and only at load time. This event won't apply for dynamically created new items…
Try this so answer.
If you want remove element li created by after document ready. You need use function delegate
Or you can write as below
$(document).on('click','li', function(){
var el = $(this);
el.remove();
});
This simple code should remove li items when clicked in the ul with id contacts.
$('#contacts').on('click', 'li', function (event) {
$(event.target).remove()
});
TL;DR:
I use $(..).append(node), but newly added nodes are not considered for inclusion despite them (supposedly) matching jQuery selectors.
Question
I have some code below that uses checkboxes but emulates radio button behavior. In other words, only one checkbox can (validly) be selected at any time. No more than one should be selected.
If you run the example below and click on the first 3 checkboxes, they will behave like radio buttons. Only one will be selected, no matter how many you click.
However, if you Add Point, newly added points will not be considered for the JS even though in theory it should grab them too...
Specifically: You can select the newly added checkbox, and it will be selected in addition to one already selected previously. That is incorrect as only 1 should be selected at any time and all others should be unselected.
What is happening and how can I have newly added nodes be included into jQuery selectors?
$(function() {
//check first box
$("input.duty:first").prop("checked", true);
//clicking unchecked box should check that box
//unchecks all others
$(".duty").on('click', function(event) {
$("input.duty").prop("checked", false);
$(this).prop("checked", true);
});
$("#addCasePoint").on("click", function() {
var newRowIndex = $('#newRowIndex').text();
var template = $('#casePointTemplate').data('template');
template = template.replace(/__index__/g, newRowIndex);
$('#casePointsFieldset').append(template);
$('#newRowIndex').text(++newRowIndex);
return false;
});
//deletes case point
$("#selection").on("click", ".removeCase", function() {
var caseCount = $('#selection .casePointFieldset').length
if (caseCount === 1) return false; //keep at least one row
$(this).closest("fieldset").remove();
return false;
});
});
.casePointFieldset {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="selection">
<fieldset id="casePointsFieldset">
<legend>Case Points</legend>
<div id="pointFieldset">
<fieldset class="casePointFieldset">
<div>
<label><span>Duty:</span> <input name="point[1]" class="duty" value="1" type="checkbox"></label>
</div>
<button class="removeCase">Remove</button>
</fieldset>
<fieldset class="casePointFieldset">
<div>
<label><span>Duty:</span> <input name="point[1]" class="duty" value="1" type="checkbox"></label>
</div>
<button class="removeCase">Remove</button>
</fieldset>
<fieldset class="casePointFieldset">
<div>
<label><span>Duty:</span> <input name="point[1]" class="duty" value="1" type="checkbox"></label>
</div>
<button class="removeCase">Remove</button>
</fieldset>
</div>
<!-- include template -->
<span id="casePointTemplate" data-template="<fieldset class="casePointFieldset"><div><label><span>Duty:</span> <input name="point[__index__]" class="duty" value="1" type="checkbox"></label></div><button class="removeCase">Remove</button></fieldset>">
</span>
</fieldset>
<button id="addCasePoint">Add Point</button>
</form>
The problem is how you're binding to them. The .click function (or .on('click')) basically works like this:
Find all of the currently existing elements which match a selector ($('.your.selector.here'))
Attach an event handler to each of those elements
Notice how I mentioned it binds to ones which already exist? That means it won't bind to newly created ones automatically. However, you can use .on to bind to the parent of those elements then listen for events on a selector. I'll show you what I mean:
$('#addItem').click(function() {
$('.container').append('<button class="item">Item</button>');
});
// Notice that I'm binding to the parent
// then specifying which events from it's children
// I want to listen to (click events from .item elements)
$('.container').on('click', '.item', function() {
console.log("I'm an item");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<button class="item">Item</button>
</div>
<button id="addItem">Add New Item</button>
If you change your on('click' to work like that then you'll have no problems.
Easiest way will be, attaching the event to the document. In the past this was done with the live() method.
$(document).on('click', '.duty', function(event) {
$("input.duty").prop("checked", false);
$(this).prop("checked", true);
});
I am making some template that i will add to my page
I have some input with some number, what i need is when i click on button ADD to add new element to page, and on DELETE to remove that element, here is my code
HTML
<div class="container">
<div class="row box template">
<label class="input box" for="foldername">
<span class="icon-prepend input-index-number">1</span>
<input type="text" class="input-folder-name" placeholder="Please article" />
<button class="btn btn-no-borders button-remove" type="button">
Delete
</button>
</label>
</div>
<div class="row box">
<label class="input" for="foldername">
<span class="icon-prepend input-index-number">1</span>
<input type="text" class="input-folder-name" placeholder="Please enter article" />
</label>
</div>
<div class="row">
<button type="button" class="btn btn-primary button-add">Add article</button>
</div>
</div>
JS
$(document).on("click", ".button-add", function () {
var lastbox = $('.box').length;
var indexNumber = lastbox - 1;
$('.template label span').text(indexNumber);
$('.template').clone()
.show()
.removeClass("template")
.insertBefore('.row:last');
}).on("click", ".button-remove", function () {
$(this).closest('.row').remove();
});
Here is working fiddle
http://jsfiddle.net/52VtD/9531/
What i need is the next, on default in class input-index-number there is some number, when i add new element i want to get that number and add new counted number in that filed.Example if there is in default number 2 next added element must have 3 etc. But also, i have problem when i remove some number i must also reindex all other numbers, like is there 1, 2, 3, 4. When i remove 3, number 4 must become 3 etc. Please take a look at my fiddle what i have for now, and you will see what i need
Just write a function to update the indexes correctly, and call it after you add or delete a row.
Full code:
$(document).on("click", ".button-add", function () {
var lastbox = $('.box').length;
$('.template').clone()
.show()
.removeClass("template")
.insertBefore('.row:last');
updateIndexes();
}).on("click", ".button-remove", function () {
$(this).closest('.row').remove();
updateIndexes();
});
function updateIndexes() {
$('.input-index-number:visible').each(function (index) {
$(this).text(index + 1);
});
}
Forked jsFiddle
You could create a helper method that reindexes the boxes and then call that whenever you add or remove a box.
var reindex = function() {
$('.row.box:not(.template)').each(function(i) {
$(this).find('.input-index-number').text(i + 1);
});
}
It seems like it would be a little more work for the computer when adding a box, but it seems simpler and less error-prone.
$(document).on("click", ".button-add", function () {
var lastbox = $('.box').length;
var t = $('.template').clone()
.removeClass("template")
.insertBefore('.row:last');
$(".input-index-number",t).html($(".input-index-number").length-1);
}).on("click", ".button-remove", function () {
$(this).closest('.row').remove();
$(".input-index-number").each(function(i)
{
$(this).html(i);
});
});
Although you could do away with all those duplicate template divs
http://jsfiddle.net/52VtD/9532/