Appending Div Elements within a Cloned Object - javascript

I simply just want to add some data to the "employeeId" div element within a cloned object and can't figure out the proper syntax to do so.
Here is some of the layout of the original object:
<div id="container">
<div id="reimbursement">
<div class="row">
<div class="col">
Employee ID:
<div id="employeeId">
</div>
And here is the JavaScript that was used to create the clone:
let reimbursement = document.getElementById("reimbursement");
let reimbursementClone = reimbursement.cloneNode(true);
document.getElementById("container").appendChild(reimbursementClone);

Simply use querySelector to get the element from the new clone and add the relevant data to it:
let reimbursement = document.getElementById("reimbursement");
let reimbursementClone = reimbursement.cloneNode(true);
document.getElementById("container").appendChild(reimbursementClone);
reimbursementClone.querySelector("#employeeId").innerText = "something";
<div id="container">
<div id="reimbursement">
<div class="row">
<div class="col">
Employee ID:
<div id="employeeId">
</div>
</div>
</div>
</div>
Although the above code would work, your cloning causes multiple instances of the same id which is invalid. You should change the employeeId to a class and pass a class selector to reimbursementClone.querySelector.

Related

Remove elements with same data-id

I have a pattern like that:
<section>
<div data-id="39"></div>
<div data-id="31"></div>
<div data-id="57"></div>
<div data-id="10"></div>
<div data-id="27"></div>
<div data-id="5"></div>
<div data-id="89"></div>
</section>
That contains some data that are live updated via AJAX. Sometimes, it may happen to receive from the server a data updated with the same id of another one in the section, and since it's the same id, I need to remove the old data to avoid multiple datas and keep just the updated one.
For example, I receive an update with data-id 27 and I insert at the top:
<section>
<div data-id="27"></div>
<div data-id="39"></div>
<div data-id="31"></div>
<div data-id="57"></div>
<div data-id="10"></div>
<div data-id="27"></div>
<div data-id="5"></div>
<div data-id="89"></div>
</section>
After inserted it, how can I do a check that if 27 is already available in the section (so the last iteration), remove it from the section? Basically removing all the data with the same id and keep just the one at the top.
Not very inspired at the moment but with the amount of info you game us i made this example with jquery. It can be done also just with plain javaScript if needed
$('div').each(function() {
dataId = $(this).data('id');
otherDataId = $(this).siblings().data('id');
if (otherDataId === dataId) {
$(this).hide()
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<div data-id="27">27</div>
<div data-id="39">1</div>
<div data-id="31">2</div>
<div data-id="57">3</div>
<div data-id="10">4</div>
<div data-id="27">27</div>
<div data-id="5">5</div>
<div data-id="89">6</div>
</section>
You could also try creating a function to remove the element with the specific data-id value you want like this:
const removeItems = (number) => {
let elements = document.querySelectorAll(`div[data-id="${number}"]`);
elements.forEach((e) => { e.remove() });
};
And then to remove elements with data-id=27 you can do: removeItems(27);.
Take a look:
const removeItems = (number) => {
let elements = document.querySelectorAll(`div[data-id="${number}"]`);
elements.forEach((e) => { e.remove() });
};
removeItems(27);
<section>
<div data-id="27">27</div>
<div data-id="39">39</div>
<div data-id="31">31</div>
<div data-id="57">57</div>
<div data-id="10">10</div>
<div data-id="27">27</div>
<div data-id="5">5</div>
<div data-id="89">89</div>
</section>
document.querySelector(`[data-id=${myDataId}]`).remove();

Fetch and append element at last using jQuery

I have a div parent element with class .carousel-inner. Within this parent div, there are some children elements. I want to take its 2nd (child) element and append that element at last. I am getting and appending second element like this.
var a = $(".carousel-inner").children()[1];
$(".carousel-inner").append(a);
Now as I append this element, it removes this element from second position and append at the last. I want to keep this element a the second position as well. How can I do it?
using clone() after you find the element. and make another variable
var a = $(".carousel-inner").children()[1],
b = $(a).clone();
$(".carousel-inner").append(b);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel-inner">
<div class="child">
a
</div>
<div class="child">
this clones
</div>
<div class="child">
c
</div>
</div>
OR clone the element just before appending like so :
var a = $(".carousel-inner").children()[1]
$(a).clone().appendTo('.carousel-inner');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel-inner">
<div class="child">
a
</div>
<div class="child">
this clones
</div>
<div class="child">
c
</div>
</div>
Use .clone()
$(a).clone().appendTo('.carousel-inner');
Use clone();
var a = $(".test").children()[1];
a = $(a).clone();
$(".carousel-inner").append(a);
Clone is the good way to achieve what you want :
var a = $(".carousel-inner").children().eq(1);
a.clone().appendTo('.carousel-inner');
you are receiving an error because $(".carousel-inner").children()[1] get the DOM object and $(".carousel-inner").children().eq(1) get the Jquery object
and clone is defined only on jquery object.
use clone function like beolw
$("p").clone().appendTo("body");
You Can Do this way also.
var a = $(".carousel-inner").children().eq(1).prop('outerHTML');
$(".carousel-inner").append(a);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel-inner">
<div class"first-child">First</div>
<div class"second-child">Second</div>
<div class"third-child">Third</div>
<div class"fourth-child">Fourth</div>
</div>

Simplify the html element into js

I am making bunch of elements that look like the same
I have
<div id="e1" class="e1">
<div class=box>
<div class='b1'></div>
<div class='b2'></div>
<div class='b3'></div>
<div class='b4'></div>
</div>
<div class='e11'></div>
<div class='e12'></div>
<div class='e13'></div>
<div class='e14'></div>
<div class='e15'></div>
...more elements
<div>
<div id="e2" class="e2">
<div class=box>
<div class='b1'></div>
<div class='b2'></div>
<div class='b3'></div>
<div class='b4'></div>
</div>
<div class='e11'></div>
<div class='e12'></div>
<div class='e13'></div>
<div class='e14'></div>
<div class='e15'></div>
...more elements
<div>
They are almost the same and I have several e3 and e4 div...
MY question is if there are anyways to reduce the codes and create them in js with an object (or better approach).
Would anyone gives me a hint? Thanks a lot!
jsFiddle Demo
You are going to need to get some iteration parameters, and then make a function which iterates based on those parameters to create these html elements. The primary way do create an html element is
document.createElement("tagname");
and then you are going to need to append them in the order you wish. Once they are done, you can append them to an element on the screen. Avoid appending inside of a loop. Even if you create a lot of elements, they will render quickly if they are only appended onto the screen once instead of each time an element is created.
Here is a simple example:
<div id="contentZone"></div>
<script>
var c = document.getElementById("contentZone");
var content = document.createElement("div");
for( var i = 0; i < 3; i++ ){
var d = document.createElement("div");
d.innerHTML = i + ") Hello :D";
content.appendChild(d);
}
c.appendChild(content);
</script>

jQuery UI sortable’s serialize method excludes one item

I am using jQuery UI sortable for a list of elements on a page whose order I want to save in the database every time it’s changed.
However, I’m experiencing a weird bug (it seems to me like one): both the serialize and toArray methods always exclude one item from the produced serialised string (or array). That always is the item being currently dragged. Which means the order is never actually tracked properly.
Here’s an example of my javascript:
$('.setContent').sortable({change:
function(event, ui) {
// Serialise the new order
var newOrder = $('.setContent').sortable('serialize');
// Add the current set id and the action name
newOrder += '&setId='+currentSet+'&action=usrStuff:changeCardsOrder';
// Send the data to the server
$.post('ajax.php', newOrder);
}
});
And the HTML:
<div class="setContent>
<div class="cardSmall" id="card_5">
<div class="hanzi">俄国</div>
<div class="meaning">Russia</div>
</div>
<div class="cardSmall" id="card_4">
<div class="hanzi">韩国</div>
<div class="meaning">Korea</div>
</div>
<div class="cardSmall" id="card_6">
<div class="hanzi">中国</div>
<div class="meaning">China</div>
</div>
<div class="cardSmall" id="card_12">
<div class="hanzi">日本</div>
<div class="meaning">Japan</div>
</div>
<div class="cardSmall" id="card_13">
<div class="hanzi">德国</div>
<div class="meaning">Germany</div>
</div>
<div class="cardSmall" id="card_17">
<div class="hanzi">巴西</div>
<div class="meaning">Brasil</div>
</div>
<div class="cardSmall" id="card_14">
<div class="hanzi">法国</div>
<div class="meaning">France</div>
</div>
<div class="cardSmall" id="card_19">
<div class="hanzi">美国</div>
<div class="meaning">America</div>
</div>
<div class="cardSmall" id="card_16">
<div class="hanzi">英国</div>
<div class="meaning">England</div>
</div>
</div>
So, in this case, there are nine items in the list. But the sortable method will only return information about eight.
So how do I fix this?
You probably want the update event, not the change event.
change fires during sorting whenever the ordering of the items in the DOM changes, even if the user hasn't let go of the item they're moving. update fires after the user has changed the order of the sortable elements.

Get elements just 1 level below the current element by javascript

I need to access the DOM tree and get the elements just 1 level below the current element.
Read the following code:
<div id="node">
<div id="a">
<div id="aa">
<div id="ab">
<div id="aba"></div>
</div>
</div>
</div>
<div id="b">
<div id="ba">
<div id="bb">
<div id="bba"></div>
</div>
</div>
</div>
<div id="c">
<div id="ca">
<div id="cb">
<div id="cba"></div>
</div>
</div>
</div>
</div>
I want to get the 3 elements "a", "b", "c" under "node". What should I do?
var nodes = node.getElementsByTagName("div") <---- I get all the divs but not the 3 divs I need.
var nodes = node.childNodes; <---- works in IE, but FF contains Text Node
Does anyone know how to solve the problem?
You could use a function that rules out all non-element nodes:
function getChildNodes(node) {
var children = new Array();
for(var child in node.childNodes) {
if(node.childNodes[child].nodeType == 1) {
children.push(child);
}
}
return children;
}
I'd highly recommend you look at JQuery. The task you're looking to do is straightforward in pure Javascript, but if you're doing any additional DOM traversal, JQuery is going to save you countless hours of frustration. Not only that but it works across all browsers and has a very good "document ready" method.
Your problem solved with JQuery looks like:
$(document).ready(function() {
var children = $("#node").children();
});
It looks for any element with an id of "node" then returns its children. In this case, children is a JQuery collection that can be iterated over using a for loop. Additionally you could iterate over them using the each() command.
This is simplier than you think:
var nodes = node.querySelector("node > div");
Try this (late answer, but can be useful for others):
var list;
list=document.getElementById("node").querySelectorAll("#node>div");
Universal selectors can do the trick:
var subNodes = document.querySelectorAll("#node > *");
Query parts:
#node is unique container selector
> next slector should be applied only on childs
* universal selector that match every tag but not text
Can I use universal selector
In my opinion the easiest way to do this is to add a class name to the
first level child nodes:
<div id="node">
<div id="a" class="level_1">
<div id="aa">
<div id="ab">
<div id="aba"></div>
</div>
</div>
</div>
<div id="b" class="level_1">
<div id="ba">
<div id="bb">
<div id="bba"></div>
</div>
</div>
</div>
<div id="c" class="level_1">
<div id="ca">
<div id="cb">
<div id="cba"></div>
</div>
</div>
</div>
</div>
and then to use the method getElementsByClassName, so in this case:
document.getElementById('node').getElementsByClassName('level_1');
I think node.childNodes is the right place to start. You could (to make it work with FF too), test the nodeName (and possibly nodeType) of all child nodes you get, to skip text nodes.
Also you might have a look at some javascript library like prototype, which provide a lot of useful functions.
I've added some text so we can see that it is working, and JavaScript that will add "added!" to the bottom of each of the divs at the base:
var cDiv = document.querySelectorAll('body > div > div'), i;
for (i = 0; i < cDiv.length; i++)
{
cDiv[i].appendChild(document.createTextNode('added!'));
}
<div id="node">
<div id="a">a
<div id="aa">aa
<div id="ab">ab
<div id="aba">aba</div>
</div>
</div>
</div>
<div id="b">b
<div id="ba">ba
<div id="bb">bb
<div id="bba">bba</div>
</div>
</div>
</div>
<div id="c">c
<div id="ca">ca
<div id="cb">cb
<div id="cba">cba</div>
</div>
</div>
</div>
</div>

Categories