Remove items one at a time using JQuery - javascript

I am trying to create a to-do list using HTML/CSS, Javascript and JQuery. The problem I have occurs when I try to delete an item off the list. Here is the Javascript.
$(document).ready(function(){
$('#add').click(function(){
if($('#input').val() != '')
$('.container').append('<p class="todo">'+$('#input').val()+'</p><span class="del">&times</span><br/>');
});
$(document).on('click','.del',function(){
$(this).click(function(){
$('.todo').hide();
});
});
});
The HTML
<body>
<h1 class="header">To-Do List</h1>
<hr/>
<br/>
<input type="text" id="input"/>
<button id="add">Add</button>
<br/>
<br/>
<div class="container">
</div>
</body>
What the above does is it removes all of the dynamically generated todo [paragraph] elements when a single del element [an x] is clicked. I am asking how to change the code so clicking the del element removes the todo element that it was generated with. I understand I can use ids but I feel that is too cumbersome. Thanks for the help.

You can use .prev() to hide only the immediate previous sibling .todo paragraph of clicked .del:
$('.container').on('click','.del',function(){
$(this).prev().hide();
});
Also take note that you don't need to use .click() event for .del any more since you've already using event delegation to attach the click event to them as well as using closest static parent for delegated event instead of $(document).

Try this jQuery, this also hides the 'x':
$(document).on('click','.del',function(){
$(this).hide();
$(this).prev().hide();
});

Related

Remove dynamically created elements (with separate delete button) using jquery

I'm trying to delete dynamically created elements each with their own delete button. This is the element that gets added with every button click. When the delete button of an element gets clicked I want that specific element to be deleted.
I use the following code to append the element:
$("#addsitem").click(function () {
$("#holdsitems").append('myFunction');
});
This is how I try to remove it:
$("#item").on("click", "#deleteitem", function() {
$("#item").remove();
});
I can only delete the elements that haven't been added.
This is all the relevant HTML code (myFunction) of the element:
<div id="item" class="itemdiv">
<form>
<div>
<div id="deleteitem">
<input type="button" name="Delete Button" value="Delete">
</div>
</div>
</form>
</div>
I'm rather new to jQuery and this is giving me headaches. Would appreciate it lots if someone could help me out!
You can use classes and the command .closest("selector") where this moves up the DOM tree until it finds the first element that matches that selector, you can then remove this.
You shouldn't be adding an id dynamically, unless you are adding an indices so that they are unique.
Demo
// Add new item on click of add button
$("#addsItem").click(function(event) {
// Stop submission of form - this is not necessary if you take it out of the form
event.preventDefault();
// Append new form item
$("#holdsitems").append('<div class="item-wrapper"><button type="button" class="deleteItem" >Delete</button></div>');
});
// Add DYNAMIC click event to class .deleteItem
$(document).on("click", ".deleteItem", function() {
// Move up DOM tree until first incidence of .item-wrapper and remove
$(this).closest(".item-wrapper").remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="item" class="itemdiv">
<form>
<div id="holdsitems">
<button id="addsItem">Add Item</button>
<div class="item-wrapper">
<button type="button" class="deleteItem">Delete</button>
</div>
</div>
</form>
</div>

Closest() in jQuery doesn't work when at the same level

Problem:
I want (after clicking on a button - this part is OK) to select the closest element with a class .my-textarea, but the using of prev() is not always possible, because the code is dynamic. Could you help?
Details:
I have this HTML code:
<div class="row">
<div class="label">Description:</div>
<textarea class="my-textarea" name="my-textarea" rows="8" cols="40"></textarea>
<button type="button" class="my-submit" name="my-submit">Save</button>
</div>
And my JS code (in on button with class "my-submit" click event) is:
var text = $(this).closest('.my-textarea').val();
But it's not working. I am getting undefined.
If I tried:-
var text = $(this).prev().val();
I will get the text of the text-area, but as I've mentioned, my code is dynamic and the order and number of elements will change. So, prev() is out of option.
Any idea how to make closest() work?
I always select parent and than search for child with class. That way your element can be placed virtually anywhere in parent.
$(this).parent().find('.my-textarea').val();
Need to Use siblings() instead of closest():-
$('.my-submit').click(function(e){
e.preventDefault();
var text = $(this).siblings('textarea').val();
console.log(text);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="label">Description:</div>
<textarea class="my-textarea" name="my-textarea" rows="8" cols="40"></textarea>
<button type="button" class="my-submit" name="my-submit">Save</button>
</div>
You need to refer it using class
closest will traverse up the DOM tree to look for the element, while in this case textarea is sibling of the button.
$('.my-submit').click(function(){
var text = $(this).siblings('.my-textarea').val();
alert(text)
})
DEMO

Track changes to particular div without using onclick functionality

I am using jquery to implement some functionality that is repeated multiple place in the same jsp. I want to re-use the same jquery code again. Can anyone let me know how can I achieve that? Hope the below code snippet explain what I really want to achieve.
<div id="1" class="a">
//implement the some functionality to all the
elements that below to this class and id="1"
</div>
<div id="2" class="a">
//implement the similar functionality that is happening
int above div to all the elements that below to this class and id="2"
</div>
<div id="3" class="a">
//implement the similar functionality that is happening
int above div to all the elements that below to this class and id="2"
</div>
<script type="text/javascript">
//Re-usable code goes here that applies for class type 2 and tracks id 1,2,3 differently.
</script>
Edit
I want to use datatable at multiple places in the same html page and at each instance of the datatable used, I want to do similar customization using Jquery.
https://datatables.net/examples/
I think this is what you're after. When any element with id 1,2 or 3 is clicked, then it will execute the same function.
$(document).on('click', '#1, #2, #3', function (e) {
console.log(e.target); // This is the element that was clicked
alert('Clicked')
});
https://jsfiddle.net/cnLvk3o1/1/
If you want to select by class like A.Wolff has mentioned below. You can use this instead.
$(document).on('click', '.a', function (e) {
console.log(e.target); // This is the element that was clicked
alert('Clicked')
});

jquery traversal question

Given:
<div>
<div id="div1">
<input type="radio" .. />
</div>
<div id="div2">
</div>
<div id="div3">
<button type="button">a button</button>
</div>
</div>
So, I am currently in the context of the <input> via its click event. I need to traverse this (using parent / children somehow) to select the button in div3 (without using a class, id etc) and enable/disable it. Any ideas?
Without any information about the logical relation between the elements, I can only make assumptions.
If the structure will remain exactly the same, then:
$(this).parent().next().next().find('button').attr('disabled', true);
If the target div is always the last element in the container, then:
$(this).parent().siblings(':last').find('button').attr('disabled', true);
If there is only ever one <button> in the container, then:
$(this).parents().eq(1).find('button').attr('disabled', true);
$('input').click(function() {
$(this).parent().parent().find('button').attr('disabled', 'disabled');
});
Though I highly recommend using some sort of class/ID to help out because DOM traversal can be brittle.
you can try this :
$('#div1 > input').click(function(){
$('#div3 > button').attr('disabled','disabled')
})
If the Html hierarchy never changes, then this will work.
$().ready(function(){
$('input').click(function(){
var elm = $(this).parent().parent().find('div').eq(2).find('button');
});
});

jQuery parameters

I'm reading data from a database and adding it to a table to be displayed on a webpage. The table that this data is added to lies inside a panel. To view this table I would have to use this Javascript to expand the panel:
<script type="text/javascript">
$(document).ready(function(){
$(".flip").click(function(){
$(".panel").slideToggle("slow");
});
});
</script>
To see where the class names flip and panel come from see below:
<div class="panel">
<table>
...
</table>
</div>
<p class="flip" onmouseover="this.style.color='red';this.style.cursor='hand'" onmouseout="this.style.color='black';this.style.cursor='pointer'"> VIEW TABLE </p>
Now, since I'm reading data from the database iteratively, the number of item in there could be anything.
How do I do this such that each has it's own identity, so that when I click on "VIEW TABLE" then each responds on its own. At the moment when I click on one, all expand and vice-versa, obviously because the share a common class name. I've tried to make sure that the class name be the entry id, but certain things break.
add to the element you want to fire the click event and send a refrence to it for example
the div will have on click event will look like this
<div onclick="MyFunction(this);"> </div>
in the function body recieve the object then reach to the element you want
function MyFunction(sender)
{
$(sender).//now you have the element and could reach to the parent or the child as you want
}
Use .prev() for your layout:
<script type="text/javascript">
$(function() {
$(".flip").live("click", function(){
$(this).prev(".panel").slideToggle("slow");
});
});
</script>
This will select the previous class="panel" to the class="flip" you clicked and slideToggle it. Also, since you may have any number of these handlers that will be the same, I suggest you use .live() like my example above, using 1 event handler instead of n event handlers.
Can you assign a new id for each 'panel' based on something in the db, or just with a sequential number? If so, then you could try this:
<div class="panel" id="panel_1">
<table>
...
</table>
</div>
<p class="flip" onClick="$(".panel_1").slideToggle("slow"); " ... >
<div class="panel" id="panel_2">
</div>
<p class="flip" onClick="$(".panel_2").slideToggle("slow"); " ... >
etc.
Making this assumption: You saying you have a new <div... for each new <p... and that the mouse over (or click) of the <p> should show the cooresponding <div>.
Try using this: for cooresponding instances.
$('.flip').click(function()
{
$('.panel').eq($(this).index()).slideToggle("slow");
});

Categories