efficient way to remove empty div - javascript

I'm using <div contenteditable="true">, when I press enter to newline with empty input, it will generate <div><br></div>.
But I just want to remove it from beginning and at the end.
For example:
<div contenteditable="true">
<div><br></div> i want to remove this
abc
<div><br></div> remain
1234
<div><br></div> i want to remove this
<div><br></div> i want to remove this
</div>
for(var x = item.length - 1 ; x >= 0 ; x--){
if($(item[x]).html() == "<br>"){
$(item[x]).remove();
}else{
break;
}
}
for(var x = 0; x <= item.length-1 ; x++){
if($(item[x]).html() == "<br>"){
$(item[x]).remove();
}else{
break;
}
}
Currently I'm using two looping to remove it, But I'm looking a better way to filter it.
Anyone can guide me?
Thanks.

You can actually achieve it with while loop instead of for loop. You need to store the reference for first and last child of the contenteditable div and manipulate it with while loop. Detailed explanation in comments around the code.
$('.remove').on('click', function() {
var firstChild = $('div[contenteditable] div:first');
var lastChild = $('div[contenteditable] div:last');
//store the reference for first and last child of the contenteditable div
while(firstChild.html()=="<br>")//remove all the element's until firstchild's html!="<br>" i.e. is not empty
{
firstChild.remove();//remove it
firstChild= $('div[contenteditable] div:first'); //again store the reference to new first child after remove
}
//same goes with last child
while(lastChild.html()=="<br>")
{
lastChild.remove();
lastChild= $('div[contenteditable] div:last');
}
})
div[contenteditable] {
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true">
</div>
<button type="button" class="remove">Remove unwanted</button>

If you want to remove a div which is empty..(Your question states that)....
This may help.....
$("div:empty").remove();
This code removes div that are empty...If thats what You wanted this could help

Related

Select div with a text inside in JS

I want to modify a div with a special text inside like this.
<div>
<p>
A global issue
</p>
</div>
How can I get it in JS without using id or class ? And only the div with the text "A global issue".
Is there a way to do it?
To target the div and set it to display: none you can run either:
// Pure JS
document.querySelector("div p").style.display = "none"
// w/jQuery
$('div p').hide();
If there's more then one div p tags in your HTML, you can also search by text using the following:
$('div p:contains("A global issue")').css('display', 'none');
If you want to use simple javascript solution, see snippet below
First, get all divs from page
Second, store your search text in a variable
Third, loop through all divs and find the one containing your text, then you can do whatever you want with it. I added a backgroundColor red to it
var divs = document.querySelectorAll("div");
var myText = "A global issue";
var i;
for (i = 0; i < divs.length; i++) {
if (divs[i].textContent.indexOf(myText) > 0 ) {
divs[i].style.backgroundColor = "red";
}
}
<div>
<p>
A global issue
</p>
<p>
More text here
</p>
</div>
<div>
<p>
Not a good text
</p>
</div>
You can use jquery:
$('div:contains("A global issue")').css('background-color', 'red');
<div>A global issue</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
let i=5;
let divs =Array.from( document.querySelectorAll('div > p')); // it returns array
divs[i].style.display= "none";
Edit:
for(let i=0;i<divs.length;i++){ if(divs[i].textContent==="some text"){ divs[i].style.display="none"; } }
if you want to change parent node do divs[i].parentNode.style.display="none"

How to remove last element using jquery?

Here I'm trying to create a calling pad that reads a maximum of 10 numbers at a time, and displays the numbers as a maximum of 6 numbers in a row. It's working functionally. I want to remove the last number when the user presses the clear button.
I used $("#calling-pad").last().remove(); to try to remove the last number, but it removes the whole contents and doesn't allow to enter a new number. How can I fix it?
var key = 1;
$("#nine").click(function(){
if (p === 1) {
$("#mini-screen").css("display","none");
$("#number-screen").css("display","block");
if (key < 11) {
if ((key % 7) !== 0) {
$("#calling-pad").append("9");
key = key + 1;
}
else {
$("#calling-pad").append("<br>");
$("#calling-pad").append("9");
key = key + 1;
}
}
}
});
$("#inner-icon-one").click(function(){
if (p === 1) {
$("#mini-screen").css("display","none");
$("#number-screen").css("display","block");
if (key > 1) {
if ((key%6) !== 0) {
$("#calling-pad").last().remove();
key = key - 1;
if ( key === 1) {
$("#number-screen").css("display","none");
$("#mini-screen").css("display","block");
}
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="calling-pad"> </span>
You are just appending numbers to a span tag and are not really keeping track of user input.
$("#calling-pad").last().remove();
Is telling jQuery to remove the full contents because you are not inserting any child elements to the calling-pad span.
Therefore you could use an array to keep track of the users numbers or use a counter as I have shown below.
var totalInputs = 0;
$("#insert").on("click", function() {
totalInputs++;
var inputText = $("#input").val();
var id = "calling_" + totalInputs;
$("#calling-pad").append("<span id='" + id + "'>" + inputText + "</span>");
});
$("#remove").on("click", function() {
$("#calling_" + totalInputs).remove();
totalInputs--;
});
span {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="input" />
<button id="insert">Insert</button>
<div id="calling-pad">
</div>
<button id="remove">Remove last element</button>
Problem - Using 'last' instead of ':last-child'
The jQuery last method does not find child elements. Instead, given a collection of elements matching a selector, it filters that collection to include only the last element. Combining this with an id-selector (i.e. $("#element-id").last()) is always redundant, since $("#element-id") only matches a single element, and the resulting jQuery object is always of size 1. If there's only one element, it's always the last one.
Therefore $("#calling-pad").last().remove(); is effectively the same as saying $("#calling-pad").remove();.
Solution
Instead, when you're appending data to the #calling-pad element, ensure they're included as new elements (e.g. wrapped in <span></span> tags):
$('#calling-pad').append("<span>9</span>");
Then, when you want to remove the last element in the #calling-pad, you simply have to do this:
$('#calling-pad > span:last-child').remove();
This finds all span elements that are direct children of the #calling-pad, filters that to only include the last element (using :last-child), and then removes that element.
$("#calling-pad").contents().last().remove();
if ($("#calling-pad").contents().last().is("br")) {
$("#calling-pad").contents().last().remove();
}
As you're dealing with textNodes, you need to use .contents() - the <br> split them up so no need to parse things, and if you're deleting the last node, you need to delete the last break at the same time...
You need one line to remove last comment... no need to count ids ...
here is snippet ... Cheers Man
$("#insert").on("click", function() {
var inputText = $("#input").val();
$("#calling-pad").append("<span>" + inputText + "</br></span>");
});
$("#remove").click(function(){
$("#calling-pad").children("span:last").remove()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="input" />
<button id="insert">Insert</button>
<div id="calling-pad">
</div>
<button id="remove">Remove last one</button>

How to remove a Tag using javascript?

I'm in a bit of a pickle. What I'm trying to achieve is to remove a div IF it is empty and then do what I have to afterwards which is the easy bit. The hard part is trying to remove the empty tags. I'm using DNN and it likes to put in empty tags like p and br. I want to be able to remove them before performing my check. Here is my code so far
$(document).ready(function(){
var element = document.getElementsByTagName("p"); //Need to remove all tags. not just P
element.parentNode.removeChild(element); //Doesn't target which child
if( !$.trim( $('#container2Test').html() ).length ) {
alert("empty");
$('#container2Test').remove();
$('#container3Test').css({'width' : '50%', 'background-color' : '#3F0'});
$('#container3Test').append("This is some content");
}
else{
alert("not empty");
}
});
The html:
<div id="container1Test" style="width:30%; height:10em; background-color:#000;">
</div>
<div id="container2Test" style="width:50%; height:10em; background-color:#666;">
<p></p><br /><p></p>
</div>
<div id="container3Test" style="width:20%; height:10em; background-color:#F66;">
</div>
I've tried many options to try and remove the tags but I've had no such luck :( Please help!
As far as your container2test block goes, try using .text() instead of .html(). This will ignore the empty tags that get inserted and focus only on the text content.
Regarding the piece above it, I'm not quite sure what you're trying to achieve. I don't think it's needed if you implement the change I mentioned earlier.
I think this will be the solution you'll need... Check out that:
var elmsToClear = $('#container1Test, #container2Test, #container3Test');
elmsToClear.each(function(){
while($(this).find('*:empty').remove().length); // recursivly kill all empty elements
if(!$(this).find('*').length){ // if no elements left - kill the parent
alert($(this).attr('id') + ' is empty...');
$(this).remove();
}
else{ // there is something in here...
alert($(this).attr('id') + ' is NOT empty...');
}
});
>>> The JS-Fiddle of the Problem with Solution <<<
Greetings ;)
Notice that getElementsByTagName is plural:
var elements = document.getElementsByTagName("p");
for (var n=0; n < elements.length; n++) {
var element = elements[n];
element.parentNode.removeChild(element); // should work now
}
There is a removeChild() function. So why can't you do something like this:
$('div').each(function(){
if(this.innerHTML == ''){
this.parentNode.removechild(this);
}
});
(Haven't tested this)

javascript to change innerHTML

I want to change content of div "act" using nextSibling of another div.
But result is - undefined.
function inner(){
var abc = document.getElementById("start").nextSibling;
document.getElementById("act").innerHTML = abc.innerHTML;
}
<img id="btnRight" src="img/btnRight.png" onclick="inner()">
<div id="act"><img src="img/home01.jpg"></div>
<div id="store">
<div id="start">
<img src="img/img01.jpg">
</div>
<div>
<img src="img/img02.jpg"> //wanted to place into "act"
</div>
<div id="end">
<img src="img/img03.jpg">
</div>
</div>
Use nextElementSibling, nextSibling could be a text node
function inner(){
var abc = document.getElementById("start").nextElementSibling;
document.getElementById("act").innerHTML = abc.innerHTML;
}
FIDDLE
If you target browser doesn't support nextElementSibling you can traverse the siblings and find the first element node.
function nextElementSibling(element) {
while (element.nextSibling){
element = element.nextSibling;
if (element.nodeType == Node.ELEMENT_NODE){
return element;
}
}
return undefined;
}
FIDDLE
You have to make sure to skip over whitespace when traversing nodes.
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
function inner(){
var abc = next(document.getElementById("start"));
document.getElementById("act").innerHTML = abc.innerHTML;
}
You can see a working example at http://jsfiddle.net/CkCR3/.
The cause of this behaviour is white space between div with id "start" and the following div. So, nextSibling will be text content. You need to do nextSibling twice:
var abc = document.getElementById("start").nextSibling.nextSibling;
Another option is to remove whitespace characters between two divs.
Please change your line of code as per below;
because every next element is check for exists or not ,then get inner html.
function inner() {
var abc = document.getElementById("start");
do {
abc = abc.nextSibling;
} while (abc && abc.nodeType != 1);
document.getElementById("act").innerHTML = abc.innerHTML;
return false;
}
I've made a jsfiddle to demonstrate an easier way.
You'll notice that the act div is red and that the start div is blue. The innerHTML will change when you click the button. Also, a reason that you might see undefined is because the DOM didn't load and so it doesn't have any idea that the divs exist. Next time you should use window.onload = inner(); to make the function run after the DOM has loaded.
This is the jsfiddle: http://jsfiddle.net/yY9Ag/16/
there are two way
first fix the code
nextSibling.nextSibling.innerHTML
or fix the html : remove all \n char
<img id="btnRight" src="img/btnRight.png" onclick="inner()"><div id="act"><img src="img/home01.jpg"></div><div id="store"><div id="start"><img src="img/img01.jpg"></div><div><img src="img/img02.jpg"> //wanted to place into "act"</div><div id="end"><img src="img/img03.jpg"></div></div>​
because div tag's next sibling is empty textNode (it can't see)

Remove parent element after removing last child element

I have a list of elements on a page, for the sake of discussion we can say I have the following:
<div id="group_01">
<div id="entry_1-01">stuff x</div>
<div id="entry_1-02">stuff x</div>
</div>
<div id="group_02">
<div id="entry_2-01">stuff x</div>
<div id="entry_2-02">stuff x</div>
</div>
The delete link calls an Ajax request and deletes the entry, after a succesful Ajax call, the entry div is removed from the page. My question is:
How can I remove the containing group div once all of it's entries have been deleted?
I hope that's a detailed enough question. I feel like this isn't anything new, yet two days of search has resulted in nothing.
Before you delete the child element, get its parent, count the number of children, and then after deleting the child, delete the parent if the child count is zero. Here is a quicky piece of sample code:
function d (x)
{
var e = document.getElementById(x);
var p = e.parentNode;
p.removeChild (e);
if (p.childNodes.length == 0) {
var pp = p.parentNode;
pp.removeChild (p);
}
}
I added onclicks to your divs like this:
<div id="group_01">
<div id="entry_1_01">stuff 11<a onclick="d('entry_1_01');" href="#delete">x</a></div>
<div id="entry_1_02">stuff 12<a onclick="d('entry_1_02');" href="#delete">x</a></div>
</div>
I also changed the link to "#delete". You could tidy this up in various ways.
A function like this should would work:
function removeNodeIfEmpty(node) {
var container = document.getElementById(node);
var nodeCount = 0;
for (i = 0; i < container.childNodes.length, i++) {
if (container.childNodes[i].nodeType == 1) {
nodeCount += 1;
}
}
if (nodeCount < 1) {
container.parentNode.removeChild(node);
}
}
This should account for the whitespace issue.
Assuming you do something like this to remove an entry:
entryDiv.parentNode.removeChild(entryDiv);
then you should be able to use the following code to remove the group div when the last child is removed:
var groupDiv = entryDiv.parentNode;
groupDiv.removeChild(entryDiv);
if (!groupDiv.firstChild) {
groupDiv.parentNode.removeChild(groupDiv);
}
...although you need to watch out for whitespace-only text nodes, if these entries haven't been created directly by script.
Really depends what library you're using
http://docs.jquery.com/Traversing/parent#expr
should be a suitable expression

Categories

Resources