How to remove appended elements one by one using javascript - javascript

I'm trying to remove the appended elements one by one using javascript. I know how to remove the whole list but I want to remove the appended one by one on every time when I click on remove button which I don't know how to solve it till now.
here is a quick demo of what's happening when I click remove button:-
http://jsfiddle.net/0ojjt9Lu/
javascript code:-
$(window).on('pageinit', function() {
$(document).ready(function(){
$("#Sadd").click(function() {
var lastId = $("#modules h1").length;
var $newLabel = $("#module-1-label").clone();
var $newSc = $("#module-1-scredit").clone();
var $newSgrade = $("#module-1-sgrade").clone();
$newLabel.html("<h1>Module " + (lastId+1) + ":</h1>");
$newSc.find("label").attr("for", "Sc"+(lastId+1));
$newSc.find("input").attr("name", "Sc"+(lastId+1)).attr("id", "Sc"+(lastId+1));
$newSgrade.find("label").attr("for", "Sgrade"+(lastId+1));
$newSgrade.find("select").attr("name", "Sgrade"+(lastId+1)).attr("id", "Sgrade"+(lastId+1));
$("#modules").append($newLabel, $newSc, $newSgrade);
$("#Sremove").click(function() {
$("#module-1-label").last().remove()
$("#module-1-scredit").last().remove()
$("#module-1-sgrade").last().remove()
});
});
});
});
Update:- I'm able to remove items that were appended but that includes Module 1 and it's removing in reverse order
e.g:- 8 modules (1,2,3, etc) it will remove first 1 and 6 then it will remove 7 then 8

You bind the click event for remove module button, every time add the module. So please bind the click event once.
Use below code.
$(document).ready(function(){
$("#Sadd").click(function() {
var lastId = $("#modules h1").length;
var $newLabel = $("#module-1-label").clone();
var $newSc = $("#module-1-scredit").clone();
var $newSgrade = $("#module-1-sgrade").clone();
$newLabel.html("<h1>Module " + (lastId+1) + ":</h1>");
$newSc.find("label").attr("for", "Sc"+(lastId+1));
$newSc.find("input").attr("name", "Sc"+(lastId+1)).attr("id", "Sc"+(lastId+1));
$newSgrade.find("label").attr("for", "Sgrade"+(lastId+1));
$newSgrade.find("select").attr("name", "Sgrade"+(lastId+1)).attr("id", "Sgrade"+(lastId+1));
$("#modules").append($newLabel, $newSc, $newSgrade);
});
$("#Sremove").click(function() {
var lastId = $("#modules h1").length;
if(lastId > 5){
var lastLi = $("#modules h1").last().closest("li");
var lastLi2 = lastLi.next("li");
var lastLi3 = lastLi2.next("li");
lastLi.remove();
lastLi2.remove();
lastLi3.remove();
}
});
});
Fiddle
Hope this will help you.

Hi Shihab Now used to this Jquery code
.last() and .closest() jquery code
$("#Sremove").click(function() {
var lastLi = $("#modules li").last();
var lastLi2 = lastLi.closest();
var lastLi3 = lastLi2.closest();
lastLi.remove();
lastLi2.remove();
lastLi3.remove();
});
Demo
Updated Demo

Related

Why Does That JS Code Not Work For Anything Except The First Class On The Page?

The following JS code turns on/off the in-site search, but there is a .search-button button in 2 places on the page, first one works but second one does not work. If I add more, they also do not work. Can I get this code to run on all classes on the page that contain a .search-button?
var wHeight = window.innerHeight;
var sb = document.querySelector(".search-button");
var closeSB = document.querySelector(".search-close");
var SearchOverlay = document.body;
var searchBar = document.querySelector(".search-bar");
// Show
searchBar.style.top=wHeight/2 +'px';
console.log(wHeight);
window.addEventListener("resize", function() {
console.log(wHeight);
wHeight = window.innerHeight;
searchBar.style.top=wHeight/2 + 'px';
}, true);
document.addEventListener("click", function() {
sb.onclick = function() {
console.log("Opened Search for Element: ");
SearchOverlay.classList.add("show-search");
};
// Hide
closeSB.onclick = function() {
console.log("Closed Search for Element: " + closeSB);
SearchOverlay.classList.remove("show-search");
};
}, true);
It's because you're using document.querySelector() which returns the first element matching your query. For more details check https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector.
To query all elements with same class you need to use document.querySelectorAll() which returns all elements matching as an array. Then, you can use the array forEach() function to iterate over all elements and add event function for all.
var sb = document.querySelectorAll(".search-button");
sb.forEach(el => el.onclick = function(e) {
console.log("Opened Search for Element: ");
SearchOverlay.classList.add("show-search");
});
Update: You can also simplify your

Multiple lists and buttons but text input not saving in correct list

I'm trying to create multiple lists on the same page with multiple "Add" buttons.
Entering text in text field 1 and clicking button1 should only add things into list1 (Monday). But button1 is adding text from text field 2 into the last loaded JS which is list2 (Tuesday). There are 8 lists in total I'm only trying to get the first 2 lists working atm.
Here's the JSFiddle: https://jsfiddle.net/sarwech/vrn5s2ns/4/
This looks like there isn't proper closure and I've considered creating separate, local functions but I'm not too sure...
The below worked when I only wanted to add items into each list:
document.getElementById("add1").onclick = function() {
var node = document.createElement("Li");
var text = document.getElementById("user_input1").value;
var textnode=document.createTextNode(text);
node.appendChild(textnode);
document.getElementById("list_item1").appendChild(node);
localStorage.setItem('monday', JSON.stringify(list_item1));
show();
return false; }
document.getElementById("add2").onclick = function() {
var node = document.createElement("Li");
var text = document.getElementById("user_input2").value;
var textnode=document.createTextNode(text);
node.appendChild(textnode);
document.getElementById("list_item2").appendChild(node); }
Appreciate any help!
This happens because you have two add function definitions. Because of hoisting the latter definition will suppress the former one. That's why you are actually binding tuesday click handler to both tuesday's and monday's add buttons.
You should consider rewriting your code to a reusable component, something like
function DayMeals(id, title) {
var self = this;
this.id = id;
this.$el = document.createElement('div');
this.$el.classList.add('row');
this.$el.innerHTML = '<h4>' + title + '</h4><input type="text"/><button>Add</button><ol></ol>';
this.$list = this.$el.querySelector('ol');
this.$input = this.$el.querySelector('input');
this.$addButton = this.$el.querySelector('button');
this.meals = this.getFromStorage();
this.updateView();
this.$addButton.addEventListener('click', function() {
self.add(self.$input.value);
});
this.$el.addEventListener('click', function(e) {
if (e.target.dataset.remove) {
self.remove(e.target.dataset.remove)
}
});
}
DayMeals.prototype.getFromStorage = function() {
var storage = localStorage.getItem(this.id);
return storage ? JSON.parse(storage) : [];
};
DayMeals.prototype.putToStorage = function() {
localStorage.setItem(this.id, JSON.stringify(this.meals));
};
DayMeals.prototype.add = function(meal) {
this.meals.push(meal);
this.putToStorage();
this.updateView();
};
DayMeals.prototype.remove = function(index) {
this.meals.splice(index, 1);
this.putToStorage();
this.updateView();
};
DayMeals.prototype.updateView = function() {
var listContent = '';
this.meals.forEach(function(meal, i) {
listContent += '<li>' + meal + '<button data-remove="' + i + '">x</button></li>';
});
this.$list.innerHTML = listContent;
};
fiddle
You have two functions named 'add', and last one is overriding first one. Name them properly, i.e. mondayAdd, tuesdayAdd. Same thing goes for other functions that share the same name: 'show', 'remove'.

jQuery show new element after dom change

I found many ways to operate on new elements after DOM change but all works with events. I just want on click hide element 1 than replace it with 2 with display:none and show it.
My code so far:
/*
* EDIT COMMENT
*/
jQuery(document).on('click',options.targets.container+' '+options.targets.comment_edit, function(e){
e.preventDefault();
var target = e.target;
target = jQuery(target).parent();
var comment_content = jQuery(target).find('.comment_content');
var comment_content = jQuery(comment_content).text();
jQuery(target).find('.comment_content').hide(400,function(){
jQuery(target).find('.comment_content').replaceWith('<textarea style="display:none" class="'+options.targets.comment_edit_form.replace('.','')+'">'+comment_content+'</textarea>');
//not working
jQuery(target).delay(400).find(options.targets.comment_edit_form.replace('.','')).show(400)
console.log(jQuery(target).find(options.targets.comment_edit_form.replace('.','')))
});
})
I want to show new element just after i do replacing.
Problems are 2:
1: I can't get new element with jquery because it is added;
2: I can't display it after other function is done.
Here's how I created an element:
var dialogDiv = document.createElement("div");
$("body").append(dialogDiv);
$(dialogDiv).html('<p>' + text + '</p>');
Search element after insertion.
Modify your code as
jQuery(document).on('click',options.targets.container+' '+options.targets.comment_edit, function(e){
e.preventDefault();
var target = e.target;
target = jQuery(target).parent();
var comment_content = jQuery(target).find('.comment_content');
var comment_content = jQuery(comment_content).text();
jQuery(target).find('.comment_content').hide(400,function(){
jQuery(target).find('.comment_content').replaceWith('<textarea style="display:none" class="'+options.targets.comment_edit_form.replace('.','')+'">'+comment_content+'</textarea>');
//show after ( put your code here )
jQuery(target).find('textarea').show();
});
})
http://jsbin.com/pirinocuku/edit?html,js,output
What i did wrong was
jQuery(target).find(options.targets.comment_edit_form.replace('.','')).show(400)
options.targets.comment_edit_form is class and i remove . from it so it couldnt find an element;
Changed to:
jQuery(document).on('click',options.targets.container+' '+options.targets.comment_edit, function(e){
e.preventDefault();
var target = e.target;
target = jQuery(target).parent();
var comment_content = jQuery(target).find('.comment_content');
var comment_content = jQuery(comment_content).text();
jQuery(target).find('.comment_content').hide(400,function(){
jQuery(target).find('.comment_content').replaceWith('<textarea style="display:none" class="'+options.targets.comment_edit_form.replace('.','')+'">'+comment_content+'</textarea>');
jQuery(target).find(options.targets.comment_edit_form.replace('.','')).show(400)
});
})
My bad, sorry guys

JQuery: for condition is not able to complete due to .replaceWith manipulation

I am trying to get a line of JQuery script to read every paragraph string found in a div and split that paragraph every time there is a ','. My issues is that I am unable to POST all of the array at once, so the replaceWith function only outputs the first value of the array because the rest of the array is deleted when the for condition returns to increment to myArray[1].
Is there anyway for me to post every value in the 'array of splits' to separate html elements without leaving the initial string and/or turning every created element a child of the previous element?
DEMO
http://jsfiddle.net/ry25Q/
HTML
<div class="data">
<i>days_of_week</i>
<p>mon,tue,wed,thur,fri,sat,sun</p>
</div>
<div>
<input type="button" class="btnClick Button" value="Click" />
</div>
JS CODE
$(function () {
$('.btnClick').click(function () {
var data = $('.data p').text();
var splitter = data.split(',');
for (var i = 0; i < splitter.length; i++) {
$(".data p").replaceWith("<span class='dataseg'>" + splitter[i] + "</span>")
}
});
});
You don't need a loop. Since you're only replacing one p element, just call .replaceWith() once with the full HTML string you're inserting.
DEMO: http://jsfiddle.net/Vfk4e/
$(function () {
$('.btnClick').click(function () {
var p = $('.data p');
var splitter = p.text().split(',');
var open = "<span class='dataseg'>";
var close = "</span>"
p.replaceWith(open + splitter.join(close + open) + close)
});
});
Can't you just add $('.data p').text(''); before your for statement? This will clear the contents,t hen your .append from your fiddle will work just fine.
$(function () {
$('.btnClick').click(function () {
var data = $('.data p').text();
var splitter = data.split(',');
$('.data p').text('');
for (var i = 0; i < splitter.length; i++) {
$(".data p").append("<span class='dataseg'>" + splitter[i] + "</span>")
}
});
});
Try to create a variable for the span element you wish to replace the <p> element with. Then inside of your for loop, sequentially add your data to the span element. After the loop, close your span and then call replaceWith() with the span variable.
$(function () {
$('.btnClick').click(function () {
var data = $('.data p').text();
var splitter = data.split(',');
var daySpan = "<span class='dataseg'>";
for (var i = 0; i < splitter.length; i++) {
daySpan += splitter[i];
}
daySpan += "</span>";
$(".data p").replaceWith( daySpan );
});
});
Demo: http://codepen.io/imajedi4ever/pen/kpzCD/?editors=101

Jquery script freezing browser but working

i'm trying to make a live search for my mobile website, I don't want to query the database every time a user type a letter so I created a ordered list with all the names that can be searched for and i'm looping through it with jquery, problem is that I have 3300 names and it's freezing the browser when it searches through them, can anyone give me a tip about better ways to do it? here is my code:
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
}
$('#pacientes_hint').html(html);
});
Use the jQuery autocomplete version. You can load an array with all your names and pass it in to autocomplete, which will work on the fly.
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
You could change your each to:
var text = $("ol.pacientes li:contains(\""+filter.toUpperCase()+"\")").map(function() {
return $(this).text();
}).join(' ');
$('#pacientes_hint').text(text);
Besides being shorter, the only improvement will be setting the contents of $('#pacientes_hint') only at the end, which could help.
Let me know if you need a more creative solution.
First of all, you could move #pacientes_hint outside the each function.
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
} // end if
}); // end each
$('#pacientes_hint').html(html);
Then, you can define ol.pacientes as a variable before the keyup handler, so it doesn't look for it everytime and in the each function, search inside the variable:
$(document).ready(function(){
var pacientes_list = $("ol.pacientes");
var pacientes_hint = $("#pacientes_hint");
$("input#search").keyup(function(){
...
$("li", $(pacientes_list)).each(function(){ // search in the container
...
}); // end each
$(pacientes_hint).html(html);

Categories