Javascript: Deleting elements that were created with .createElement() - javascript

So when a user presses a button, I am creating elements to make a list appear on the page. However, when they press the button again the new list goes after the previous content, and the old content remains. I need to clear the previous content (which was created with .createElement()), and then insert the fresh content.
This is how I'm making the elements:
I have a <ul id="positiveUL"> in the HTML. And positiveList = document.getElementById('positiveUL')
for(var positive in positives) {
var li = document.createElement('li');
li.innerHTML = positives[positive] + ', ';
positiveList.insertBefore(li, positiveList.firstChild);
}
What I have tried:
.innerHTML = ' ';
I also tried removing childNodes with .removeChild(), but it doesn't work.
Would really appreciate any help or direction to go in. Thanks!

Hopefully I understand you, but before inserting your new content, empty the old content?
while(node.firstChild)
{
node.removeChild(node.firstChild);
}
Where node is your parent node?

Related

Remove parent and all child elements not working

I am developing a plugin for my own usage, and I want to get rid of all the annoying wordpress messages that appear on top including updates, errors, info, etc. Given the obvious fact that the plugin's menu page is generated by php, I tried removing these messages with a php code which according to my research is this:
function remove_core_updates(){
global $wp_version;return(object) array('last_checked'=> time(),'version_checked'=> $wp_version,);
}
add_filter('pre_site_transient_update_core','remove_core_updates');
add_filter('pre_site_transient_update_plugins','remove_core_updates');
add_filter('pre_site_transient_update_themes','remove_core_updates');
I added this at the top of my plugin php file and should remove the notifications, but the error message for some plugins still appear. Apart from this, the code above removes the update notification for all menu pages I access in my dashboard. This I do not want.
As a workaround, I wrote a function which does what I want:
function remove_wp_messages(selector) {
var child = document.querySelector(selector),
parent = child.parentNode,
index = Array.prototype.indexOf.call(parent.children, child);
for (var i = 1; i < Number(index + 1); i++) {
var elements = document.querySelector("#wpbody-content > :nth-child(" + i + ")");
while (elements.firstChild) {
elements.removeChild(elements.firstChild);
elements.style.display = "none";
}
}
}
window.onload = remove_wp_messages("#wpbody-content > link");
Given that the first html element I add to the menu page is a link to an external stylesheet, the javascript function above returns the index of that link and removes all child nodes from the elements up to the link, hence the loop. Here is the issue, I want to not only remove the child elements but the parents as well which would be equivalent to removing the notifications above the content of my plugin. I tried replacing:
elements.style.display = "none";
With this:
elements.remove();
No luck. What I do not understand is, that the parent elements get hidden, but I replace it with remove() it removes my content instead of the notifications. Why? I am open to both php and javascript suggestions.
SOLUTION
According to #PetrSr answer, my code now looks like this:
function remove_wp_messages(selector) {
var child = document.querySelector(selector),
parent = child.parentNode,
index = Array.prototype.indexOf.call(parent.children, child);
for (var i = Number(index); i > 0; i--) {
document.querySelector("#wpbody-content > :nth-child(" + i + ")").remove();
}
}
Pretty straightforward.
Looping through the elements backwards like this should fix your issue:
for (var i = Number(index); i > 0; i--) {
//your code
}
You cannot loop forward when removing DOM elements the way you did, because after removing element1, element2 becomes the first one. If you then remove the second element, you are in fact removing what was originally element3. Etc.

Prevent delete of last div in Javascript

I have a slight problem in a feature I am trying to implement on a web page. I have two images, a plus and a minus sign, when plus is clicked it clones a div which consists of a few text box's. The minus image is meant to delete this div.
At the moment, I cannot seem to find a way to stop the last div from being deleted when I click on the minus. I want to just prevent the last row from being deleted and using an alert to inform the user that it cannot be deleted.
Can anyone give me some insight to this? I've searched on here for a while and found something similar, but it's all done using JQuery which I have no experience with.
Here is the code I am using to try and delete the div's.
function deleteRow1() {
// row-to-clone1 is the name of the row that is being cloned
var div = document.getElementById('row-to-clone1');
if (div) {
div.parentNode.removeChild(div);
}
if ((div).length != 1) {
alert("Cannot delete all rows.").remove();
}
}
When I try do delete the row it displays the alert but still deletes the div. I realise this is probably a very easy fix and my implementation of the above may not be correct, if anyone can help I would appreciate it.
ID of an element must be unique, so use a class to fetch them
function deleteRow1() {
// row-to-clone1 is the name of the row that is being cloned
var divs = document.getElementsByClassName('row-to-clone1');
if (divs.length > 1) {
divs[0].parentNode.removeChild(divs[0]);
} else {
alert("Cannot delete all rows.")
}
}
function add1() {
var div = document.getElementById('row-to-clone1');
if (div) {
var clone = div.cloneNode(true);
delete clone.id;
div.parentNode.appendChild(clone);
}
}
<button onclick="add1()">Add</button>
<button onclick="deleteRow1()">Delete</button>
<div id="row-to-clone1" class="row-to-clone1">div</div>

nestedsortable dynamic item not collapsing

I am using this nested sortable plugin mjsarfatti.com/sandbox/nestedSortable and the only issue I have so far is when I dynamically add an item to the "tree", I am not able to expand or collapse the item(s). I am just using the sample code so far, and adding to that.
How I am adding the items dynamically:
$('#new-button').on('click', function() {
var nextId = $('ol.sortable').nestedSortable('nextId');
var $li = $("<li id=\"list_" + nextId + "\"><div><span class=\"disclose\"><span></span>
</span>New Item</div>");
$li.addClass('mjs-nestedSortable-leaf');
$('ol.sortable').append($li);
})
When I add these new items to the tree, they work just fine - I can move them throughout the tree, make them children, etc.
However, when I try to collapse a new item that I have made a parent - there is no response.
I am sure I just haven't added the correct event handler somewhere, but I can't fin where that is happening. I have even triggered a destroy() and _create() of the tree after I add the new item(s), hoping that would "re-configure" all the items again. However, no luck there.
Can anyone tell me how I can properly hook up these new dynamically created items so they will be treated as other items in the tree?
Thanks!
Ok, after 2 days of looking at this, I was able to solve the issue. It is funny - the code I had been looking for was directly above the new code that I had entered. (Right under my nose.) Thanks to the kind people here for introducing me to: Visual Event - that greatly helped me to track down where the events were being created in the first place!
$('#new-button').on('click', function() {
var nextId = $('ol.sortable').nestedSortable('nextId');
//Begin creating dynamic list item
var $li = $("<li id=\"list_" + nextId + "\">");
var $lidiv = $("<div></div>");
var $disli = $("<span class=\"disclose\"><span></span></span>");
$li.addClass('mjs-nestedSortable-leaf');
//Assign event listener to newly created disclose span tag above
$disli.on('click', function() {
$(this).closest('li').toggleClass('mjs-nestedSortable-collapsed').toggleClass('mjs-nestedSortable-expanded');
});
//Now actually start to append to DOM
$lidiv.append($disli);
$lidiv.append("New List Item " + nextId);
$li.append($lidiv);
$('ol.sortable').append($li);
})
Hopefully, this will help someone.
Here is a working copy in case you want to see it in action.

JavaScript insertBefore not updating - needs double or treble click

This is driving me nuts, a simple script to swap two nodes in a two node ul:
// Html
<input type="button" onclick="swapItems()" value="Swap Items" />
//JavaScript
function swapItems() {
var ul2 = document.getElementById("ul2");
var first = ul2.firstChild;
var last = ul2.lastChild;
ul2.insertBefore(last, first);
}
It works but I have to either double click or triple click the button to see the changed list.
If you look at the childNodes of ul2 it will become apparent. The first child of ul2 is a blank text node, so is the last child. The reason you have to click a few times is that you are moving blank text nodes around. You can't see it on the web page, but if you use a web inspector you should be able to pick it up.
You could change the code to:
function swapItems() {
var ul2 = document.getElementById("ul2");
var liChildren = ul2.getElementsByTagName('li');
var first = ul2.liChildren[0];
var last = ul2.liChildren[liChildren.length - 1];
ul2.insertBefore(last, first);
}
That should work as you wanted.
Remove the whitespaces in #ul2. Whitespaces are also considered as children nodes.

I cannot append a child element to a list

I used to be able to append a child to a list dynamical but now for some reason the JavaScript functions stop working. Also the error console does not throw any errors and I have place several alert('') methods in between the code to make sure that the method is actually running. this is what I used to have and it used to work perfectly fine:
var o = document.getElementById('searchResults');
var li = document.createElement('li'); //creates a list item tag
//if counter is even then highlight the cell different than an odd one
if ((counter) % 2 == 0) {
li.setAttribute('class', 'par');
} else {
li.setAttribute('class', 'non');
}
// I copied the inner html from a row that was displaying. I got rid of the dynamic variables
// just so it is a little easier to understand.
li.innerHTML = "<label class='list3p1'>testing</label><label class='list3p2'>testing2</label><label class='list3p3'>2:23</label>";
o.appendChild(li);
this function was working but as I added other tables to index.php this functions stopped working. Moreover I have used this similar method in other pages. Also other methods are working and that is the only function that does not seem to work.
It had to do with the visibility. It took me a long time to find. I had the id of the table repeated and the visibility of the other table was hidden therefore I was adding items to a hidden table. sorry for the fool question.

Categories

Resources