Downshift remaining IDs after function remove() - javascript

I'm using Javascript and I'm having problems trying to remove several elements.
Each div has a specific ID, like this:
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
<div id='4'></div>
Each div has a button that fires the remove() function
document.getElementById(count).remove()
Count is a variable that is increased whenever I create a new div
The remove() function works, but it creates a gap. IF i remove the div with id=2, then:
<div id='1'></div>
<div id='3'></div>
<div id='4'></div>
But I would like that the remaining IDs could downshift like this:
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
I guess I need a for loop but I can't understand how to make it

Use a class on each element, like this:
<div class="a" id='1'></div>
<div class="a" id='2'></div>
<div class="a" id='3'></div>
<div class="a" id='4'></div>
And call the following function after each removal:
function resetId(){
const list = document.getElementsByClassName("a")
for(let i = 0; i < list.length; i++){
list[i].id = i + 1
}
}
However, it might be better to just not use IDs in this case. By applying the same class to all your elements, there's no need to readjust the numbering, and you can select (or remove) the nth element using:
document.getElementsByClassName("a")[n]

This would probably be best achieved using jquery.
Here is the working code below:
$("div").each(function(i) {
$(this).attr('id', ++i);
});
$("#remove").click(function() {
$("#2").remove();
$("div").each(function(i) {
$(this).attr('id', ++i);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
remove
How it works
First $(this).attr('id', ++i); this line here is used to add a number to div id. Ive repeated it in the remove function [("#remove").click(function()] This is because once a div has been removed the will be a number change.
This in affect is a loop. Without all the lines of code. Which is why i like jquery :)
The div id name is found here after they have been written $("#2").remove(); #2 refers to the <div id="2"> As you would in css.
If you notice, with an inspection the numbers down shift as 1 is removes as per your request.
In order to use jquery you have to link the library. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
A Pure Javascript Version
function resetId(){
var div=document.getElementsByClassName("div")
for(i in div){
div[i].id=i++
}
}
function clicked() {
var elem = document.getElementById("1");
elem.parentNode.removeChild(elem);
resetId();
}
<div class="div" id="0">div</div>
<div class="div" id="1">div</div>
<div class="div" id="2">div</div>
<div class="div" id="3">div</div>
Remove
How it Works
This section here is your loop:
for(i in div){
div[i].id=i++
}
This section quite simply rewrites the numbers 0 - 4 after one has been removed.
The reason it starts from 0, is because in programming we start counting from 0. Hay 0 is a number too guys :).
The i++ Is a basically a mini int [ish] that is increased as the loop counts through how many divs there are.
This var elem = document.getElementById("1"); & this elem.parentNode.removeChild(elem); Is why I find jquery more acceptable in this situation. Its a bit less faf.
Finally resetId(); We have to call the function otherwise it doesn't that anything has changed, because computers are silly and need to be told.
Furter Reading
https://api.jquery.com/
http://www.lucemorker.com/blog/javascript-vs-jquery-quick-overview-and-comparison

Sounds like you should be using classes and referencing elements by index instead. IDs should remain persistent for clarity.
document.getElementsByClassName('my-class')[2].remove();
<div class="my-class" id="thing1">One</div>
<div class="my-class" id="thing2">Two</div>
<div class="my-class" id="thing3">Three</div>
<div class="my-class" id="thing4">Four</div>

Related

JQuery - get first occurence of class travelling upwards anywhere in the DOM

I have several instances of class="reply_count", most embedded inside other elements. I would like a method to traverse upward anywhere in the DOM to get the first instance of, and get the text value.
In the example below, I tried using prevAll, and getting the first of them. However, it does not recognize the one that is within a DIV. That is the one I want to select. I assume prevAll works for the same level elements, but not nested ones?
My actual code is much more complex, but below is just a simple example of the intent.
What is another method of accessing the first occurrence of a class going upwards regardless of where it is and how it is nested in other elements?
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div class="reply_count">15</div>
<div class="reply_count">10</div>
<div><span class="reply_count">5</span></div>
<div id="click" style="cursor: pointer;">Click Here</div>
<div class="reply_count">2</div>
<div class="reply_count">1</div>
<script>
$("#click").click(function(){
value = $(this).prevAll( ".reply_count:first" ).text();
alert(value);
});
</script>
</body>
</html>
The result is: 10. I wanted 5.
You can do something like this:
$(".click").click(function() {
var c = $(this).parent().find(".reply_count").add(this);
var t = $(c).index(this);
var value = $(c).eq((t-1)).text();
console.log(value);
});
Demo I've added multiple <div class="click" so you can see it working just fine.
$(".click").click(function() {
var c = $(this).parent().find(".reply_count").add(this);
var t = $(c).index(this);
var value = $(c).eq((t-1)).text();
console.log(value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="reply_count">15</div>
<div class="reply_count">10</div>
<div>4</div>
<div class="click" style="cursor: pointer;">Click Here</div>
<div><span class="reply_count">5</span></div>
<div class="click" style="cursor: pointer;">Click Here</div>
<div><span class="reply_count">1</span></div>
you can use closest method. It traverses upwards through the ancestors in the DOM tree and returns the closest parent matching your selector

Hide element with same text on the page

I'm trying to hide any text on the page that appears inside a div (with a specific class) more than once. For example, if my page has:
<div class="year"><h3>2015</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"><h3>2017</h3></div>
In this example, I want to use jQuery to check if there is more than one div (with the class of "year") that has the same child h3 text. If so, then hide all except the first, resulting in this:
<div class="year"><h3>2015</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"></div>
<div class="year"></div>
<div class="year"><h3>2017</h3></div>
Any help would be much appreciated! Thanks
What I would recommend doing is grabbing all of the elements with $('.year'), and then setting up an array to store the .innerHTML of each element. You can then loop over the elements, and check if their .innerHTML is in this array. If it's not, it gets added to the array. If it already exists, hide the element:
var elements = $('.year');
var existing_content = [];
for (var i = 0; i < elements.length; i++) {
if (existing_content.indexOf(elements[i].innerHTML) === -1) {
existing_content.push(elements[i].innerHTML);
}
else {
$(elements[i]).hide();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="year"><h3>2015</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"><h3>2016</h3></div>
<div class="year"><h3>2017</h3></div>
Note that this assumes that the .year elements all have identical content. If only part of the .year content is the same, you will need to update the elements selector to be more specific, and target the elements with identical content directly.
Hope this helps! :)

AppendChild a element above a cerain element

So i have a div element which will be filled dynamically with others divs using the appendChild Method, this should display a list. The User is now able to sort that list with the JqueryUI Sortable option.I also added some sortable option attribues like follows:
Options:
$("#NameContainer").sortable("option", "axis", "y");
$("#NameContainer").sortable( "option", "containment", "parent" );
LIST
<div id="NameContainer" class="ui-widget">
<div id="Name_1">John</div>
<div id="Name_2">Jack</div>
<div id="Name_3">Charlie</div>
<div id="Name_4">Sawyer</div>
<div id="Name_5">Yin</div>
<div id="Name_6">Ben</div>
</div>
Now comes my problem. The appendChild always inserts the new div at the bottom of the container but i want to to add some space at the bottom of to the Container Div with a "br" or something like that. I want to add that space to make sure that when the user sorts the last item of that list it will get sorted correctly because the "containment" bounds sometimes wont allow to sort under the last item.
<div id="NameContainer" class="ui-widget">
<div id="Name_1">John</div>
<div id="Name_2">Jack</div>
<div id="Name_3">Charlie</div>
<div id="Name_4">Sawyer</div>
<div id="Name_5">Yin</div>
<div id="Name_6">Ben</div>
<br><!--SPACEHOLDER-->
</div>
So here comes my Question is there away to appendChild above a certain element? Like a "br" "div" or "p"?
Try this instead of appendChild:
Please note I have used random value to add in div as I don't have your dynamic value.
check fiddle: https://jsfiddle.net/dqx9nbcy/
<div id="NameContainer" class="ui-widget">
<div id="divspacer"></div>
</div>
<button id="btn">ADD Element</button>
$(document).ready(function(){
$("#btn").click(function(){
var parentnode = document.getElementById("NameContainer");
var existnode = document.getElementById("divspacer");
var rand = Math.floor((Math.random() * 10) + 1);
var newName = document.createElement("div");
newName.setAttribute("id", rand);
newName.setAttribute("value", rand);
newName.setAttribute("class","ui-widget-content");
newName.innerHTML = rand;
parentnode.insertBefore(newName,existnode);
});
});
refer http://api.jquery.com/appendto/ but you need to make sure that your are targeting right tag.
You can try with this code snippet.
HTML Snippet
<div id="NameContainer" class="ui-widget">
<div id="Name1">Name1</div>
<div id="Name2">Name2</div>
<div id="Name3">Name3</div>
<div id="Name4">Name4</div>
<br>
<br>
</div>
Javascript Snippet
$(document).ready(function(){
$("#btn").click(function(){
var containerDiv= $("#NameContainer");
var childList = containerDiv.children("div");
var newElementid = childList.length;
var newName = document.createElement("div");
newName.setAttribute("id", "Name"+(newElementid+1));
newName.setAttribute("value", "Name"+(newElementid+1));
newName.setAttribute("class","ui-widget-content");
newName.innerHTML = "Name"+(newElementid+1);
$(childList[childList.length-1]).after(newName);
});
});
This is specific to a situation where there are some elements in the initial list. The same can be modified for dynamic list of implementation by validating that childList.length is != 0 before using the same.

Add class with a particular div

I have this div
<div class="newDiv">
It is generating in loop, something like
<div class="newDiv">
<div class = "innerDiv">
SomeCode
</div>
</div>
<div class="newDiv">
<div class = "innerDiv">
SomeCode
</div>
</div>
<div class="newDiv">
<div class = "innerDiv">
SomeCode
</div>
</div>
Now I want to add another class "BrightDiv" with the div that generated at odd places like
with first and third div.
what should I do to add Class "BrightDiv" along with "newDiv" with every div at odd place?
Try this : You can use :odd or :even to select odd / even elements, but it is depend on the index position and not natural number count. So In your case, you want first and third position div i.e. with index= 0 and 2 which is even by index position and hence use :even.
$('div.newDiv:even').addClass('BrightDiv');
DEMO
You can use filter to select only the odd indexed divs
$(".newDiv").filter(function() {
return $(this).index() % 2 == 1;
}).addClass("BrightDiv");
this will give you a solution $("div:even").addClass("BrightDiv");
Ways to achieve this:
CSS:
.newDiv:nth-child(odd) { /*CSS*/ }
or
.newDiv:nth-child(2n-1) { /*CSS*/ }
jQuery:
$('.newDiv:odd').addClass('BrightDiv');

How to "relate" elements

I was wondering how you could "relate" two HTML elements.
For example, let's say a user clicks on a selection item and I want the element "related" to that element disappear.
<div id="game1Selection">I pick team1</div>
<div id="game2Selection">I pick team2</div>
<div id="game1">This is game 1</div>
<div id="game2">This is game 2</div>
What I would want to happen is that when a user selects "game1Selection" that the div "game1" will disappear and the same thing for game2, game3, etc. I know how to do this the long way:
$('#game1Selection').click( function() {
$('#game1').toggleClass('selected');
}); //selected has the attribute display:none
How could I make two of them related so I don't have to write it the long way and just use this
jsBin demo
$('div[id$=Selection]').click(function(){
var myID = this.id.split('Selection')[0];
$('#'+myID).toggleClass('selected');
});
use the ends with selector $ and retrieve the first part of the ID name by splitting the original ID and getting the first ([0]) part of the name (gameN)
a better idea demo
But a far better example would be using this HTML:
<div>
<div class="selection">I pick team1</div>
<div class="selection">I pick team2</div>
</div>
<div class="game">This is game 1</div>
<div class="game">This is game 2</div>
and retrieve the clicked element index() and find the matching element using .eq() :
$('.selection').click(function(){
var i = $(this).index();
$('.game').removeClass('selected').eq(i).addClass('selected');
});
This will allow you to remove the already selected classes and assign it to the index-matching element.
Use classes for like behavior, and grab the number from the id.
<div id="game1Selection" class="selection">I pick team1</div>
<div id="game2Selection" class="selection">I pick team2</div>
<div id="game1" class="game">This is game 1</div>
<div id="game2" class="game">This is game 2</div>
$('.selection').click( function() {
$("#" + this.id.replace("Selection", "")).toggleClass('selected');
$('.game').not(this).removeClass('selected');
});
I prefer to use HTML5's data-* properties to make the association more explicit:
<div class="selector" data-fadetarget="game1">I pick team1</div>
<div class="selector" data-fadetarget="game2">I pick team2</div>
<div id="game1">This is game 1</div>
<div id="game2">This is game 2</div>
JavaScript:
$('.selector').click( function() {
var target = '#' + $(this).data('fadetarget');
$(target).toggleClass('selected');
});
Using this method, the associations are explicit in the markup and won't fail if things are rearranged.

Categories

Resources