AppendChild a element above a cerain element - javascript

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.

Related

Downshift remaining IDs after function remove()

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>

Select span of sibling div jquery

I am using jQuery selectors, and I need to be able to find each span individually that contains a dollar amount. For example, I'd like to find & change the first span to $15 and the third span to $40. I have put in class names in my example, but in my problem I do not know the class names, and I do not know which span the 2nd dollar amount is in. There also could be more or less div's and spans.
This happens to be in a form, and I find the first dollar amount like this:
$("form[action='/cart'] span:contains('$'):first).replaceWith("$15");
I have the following HTML.
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
</div>
Thanks
You can iterate over each span element and check if it's innerHTML contains $ symbol. If so, return all these spans and their position (index).
Once you have their index position, you can modify them as you like.
Note: No jQuery needed in this solution.
Example: You can push every index of each matched span to an array. In this particular case, it would look like var matchedIndexes = [0, 2]. Then basically, if you want to change e.g. the first element - simply use matchedIndexes[0].
var elems = document.getElementsByTagName('span'),
matchedIndexes = [];
Array.from(elems).forEach(function(v,i){
if (/\$/.test(v.innerHTML)){
matchedIndexes.push(i);
}
});
//change html of the first element
elems[matchedIndexes[0]].innerHTML = '$15';
//or change the last matched element
elems[matchedIndexes[matchedIndexes.length-1]].innerHTML = '$99';
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
</div>
why not having an array with values to be updated and query the span which contains '$' and update accordingly?
var ratesToUpdate = [15, 40, 70];
var spans = $("form[action='/cart'] span:contains('$')");
spans.each(function(index, span){
$(span).text('$'+ratesToUpdate[index]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form action="/cart">
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
<div class="kid4">
<span>nothing</span>
</div>
<div class="kid5">
<span>nothing</span>
</div>
<div class="kid5">
<span>$50</span>
</div>
</div>
</form>
I like the answer Kind user gave - but here is my stab at it. I couldn't make it more dynamic as the addition values are not similar (first one is added by 5, third is doubled...)
JSFiddle Here: https://jsfiddle.net/rL36jv8m/
Your HTML
<div class="daddy">
<div class="kid1">
<span>$10</span>
</div>
<div class="kid2">
<span>Nothing to see here</span>
</div>
<div class="kid3">
<span>$20</span>
</div>
</div>
Array of addition values to corresponding divs.
var addValues = [
5,
'',
20
]
Iteration:
$('.daddy').children().each(function(i, o) {
var elem = $(o).find('span');
if (elem.html().indexOf('$') === 0) {
elem.html('$' + (parseInt(elem.html().replace('$', '')) + addValues[i]))
}
})
Hope this helps.
Would this solve your problem?
var values = [15, 40];
$("form[action='/cart'] span:contains('$')").each(
function(index, element)
{
element.value = '$'+ values[index];
});

jQuery take specific div's text

I have a menu where I'd like to retrieve the text within the div so I tried writing something like this
$(".link").click(function() {
var linkValue = $(".link").text();
alert(linkValue);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="menu">
<div class="link">Home</div>
<div class="link">Apartment</div>
<div class="link">Contact</div>
<div class="link">About us</div>
</div>
But it takes all the values of each class. Is it possible to make it take only the div's text I clicked?
Use this inside the click function:
$(".link").click(function(){
var linkValue = $(this).text();
alert(linkValue);
});

targeting a div in an ocean of nested dynamically added divs

I'm using the liferay framework and I need to add a JavaScript detected inline height to a very very specific div in my page. The problem is I need to target it going through an unknown number of dynamically added divs with dynamically added classes and IDs. To complicate this even further, the divs are randomly siblings or nested in each other.
Here's what it looks like:
<div class="known-class">
<div class="unknown dynamicallygenerated"></div>
<div class="unknown dynamicallygenerated">
<div class="unknown dynamicallygenerated">
<div class="unknown dynamicallygenerated"></div>
<div class="unknown dynamicallygenerated">
<div class="DIV-I-WANT-TO-TARGET">this is the div i need to Target with my css/javascript</div>
</div>
</div>
</div>
obviously I can't target it simply with
function resize() {
var heights = window.innerHeight;
jQuery('.DIV-I-WANT-TO-TARGET').css('height', heights + "px");
}
resize();
Because that class is present elsewhere, I would rather target it with something like.
jQuery('.known-class .DIV-I-WANT-TO-TARGET')
Which obviously doesn't work because there's a ton of other divs in the middle and my div is not a child of ".known-class"
I was asking myself if there was any jQuery that could help. Something like:
Catch any div with .DIV-I-WANT-TO-TARGET class that is "generically" inside another div that has .known-class
Is this possible? thanks a lot for your help!
Something like this would work:
// this will target the known-class and find all children with DIV-I-WANT-TO-TARGET
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET');
// this will target the known-class and find the first DIV-I-WANT-TO-TARGET
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET').first();
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET:first');
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET:eq(0)');
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET').eq(0);
You can try in your css file
.known-class div div div div{}
The last div being the DIV-I-WANT-TO-TARGET
Assuming that you are adding the divs starting from the outer to the inner
Assign an equal name plus a number starting from 1
<div class="known-class">
<div class="unknown dynamicallygenerated" id="dynamicdiv1"></div>
<div class="unknown dynamicallygenerated" id="dynamicdiv2">
<div class="unknown dynamicallygenerated" id="dynamicdiv3">
<div class="unknown dynamicallygenerated" id="dynamicdiv4"></div>
<div class="unknown dynamicallygenerated" id="dynamicdiv5">
<div class="DIV-I-WANT-TO-TARGET" id="dynamicdiv6"></div>
</div>
</div>
</div>
The use jQuery [.each][1] to loop through all the divs on the document
$( document.body ).click(function() {
$( "div" ).each(function( i ) {
if ( this.style.color !== "blue" ) {
this.style.color = "blue";
} else {
this.style.color = "";
}
});
});
When you reach the last item in numeric order. (you can use any split function) add the attributes to that div
you need to select last div inside the known-class:
$('.known-class').find('div:last').css('background', 'Red')
OR if you want to select all the .known-class :
$('.known-class').each(function() {$(this).find('div:last').css('background', 'Red')});
Actually your selector works just fine:
$('.known-class .DIV-I-WANT-TO-TARGET')
With a space, selectors will find any descendant.
The search is only limited to direct descendants (immediate children) if you use the > operator.
So $('.known-class > .DIV-I-WANT-TO-TARGET') would not find what you wanted.

Duplicate DIV with input field

Basically I've managed to become stuck yet again trying to duplicate a DIV and it's form elements using jQuery.
Button:
<div class="addNew" id="addSkill">Add Skill <i class="icon-plus"></i></div>
Div and contents I wish to duplicate
<div class="row" id="skiller">
<div class="label">Skill</div>
<div class="input"><input class="lineput" placeholder="Doing stuff."></div>
</div>
I've tried using the clone method, I just can't seem to create a functioning line of code that will duplicate it beneath the first div, and make it ready for PHP multiple data entry.
Thanks!
Something like this would be a start:
$("#addSkill").click(function(e){
e.preventDefault();
var new_skiller = $("#skiller").clone();
new_skiller.attr("id", "skiller-"+$(".row").length);
new_skiller.insertAfter(".row:last");
});
You need to clone and then append() the item inside a div like so:
HTML
<div class="thing">
<div class="row" id="skiller">
<div class="label">Skill</div>
<div class="input"><input class="lineput" placeholder="Doing stuff."></div>
</div>
</div>
<div class="addNew" id="addSkill">Add Skill <i class="icon-plus"></i></div>
jQuery
$(document).ready(function(){
$('#addSkill').click(function(){
var thing = $('#skiller').clone();
$('.thing').append(thing);
});
});
View the jsFiddle Demo....
Note: you'll need to give them seperate names/make it an array to access
Try this. should work. Note: ID can not be duplicated. the following code will duplicate div with id as well.
$(document).ready(function(){
$('#addSkill').click(function(e) {
var skiller = $('#skiller').clone();
$( "#skiller" ).after( skiller );
});
});
Demo:
http://jsfiddle.net/XpN95/

Categories

Resources