Add attribute to a parent element - javascript

I have a javascript variable (ex: myElement), that holds a div with class name myClass like shown below.
<div>
<div class="myClass">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
<div class="myClass">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
</div>
I want to add an attribute (ex: data-index) to the div having class 'myClass' through jascsript or jQuery so that it could look like this:
<div>
<div class="myClass" data-index="index1">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
<div class="myClass" data-index="index2">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
</div>
How can you achieve this?
Please note: I have this div in a javascript variable called myElement and the following code
myElement.attr('data-index','index')
does not work.
Update:
I could try like First appending the div stored in variable myElement to the DOM, then add the attribute:
$('div.myClass').attr('data-index','index');
but the problem is in the DOM I have like 100s of div with the class myClass.

well, the better way is you create the attributes while you are creating HTML.
But you can do what you want using jquery iterate function (Jquery.each): http://api.jquery.com/jquery.each/
var myElements = $('div.myClass'),
i = 0;
$.each( myElements , function( i ) {
$(this).attr('data-index','index'+(i+1));
});

Try this:
var newAttr = document.createAttribute("data-index");
newAttr.value = "[What you want the index to be]";
// Will set data-index for first .myClass in newElement
newElement.getElementsByClassName("myClass")[0].setAttributeNode(newAttr);
// Will set data-index for every .myClass in newElement
newElement.getElementsByClassName("myClass").map(function(node) {
node.setAttributeNode(newAttr)
});

Related

Click on parent to open it's child inside collection(vanilla JS)

I am new to javascript, which is why I hope I could get an advise of how to make the following using vanilla JS.
I have structure
<div class="parent">
<div class="child">Some content</div>
</div>
<div class="parent">
<div class="child">Some content</div>
</div>
<div class="parent">
<div class="child">Some content</div>
</div>
<div class="parent">
<div class="child">Some content</div>
</div>
What I want is to be able to click on each parent to open only it's own child. Could someone give an idea how that could be done with vanilla js? I assume this should be done using collections in JS. But I have no idea how to connect each parent and each child with each other. Would be grateful for any advise.
It works like this (see comments in code):
// Iterate over a collection of elements with class 'parent'
for (const parent of document.querySelectorAll('.parent')) {
// to each parent, add a click listener
parent.addEventListener('click', function(clickEvent) {
// check if the element clicked was the parent and not a click bubbling up from a child
if (clickEvent.target === parent) {
// find the child contained
const child = parent.querySelector('.child');
// toggle the visibility using the hidden property
child.hidden = !child.hidden;
}
})
}
.parent::before { content: "parent, click here to toggle child"; }
<div class="parent">
<div class="child" hidden>Some content 1</div>
</div>
<div class="parent">
<div class="child" hidden>Some content 2</div>
</div>
<div class="parent">
<div class="child" hidden>Some content 3</div>
</div>
<div class="parent">
<div class="child" hidden>Some content 4</div>
</div>
Also note that HTML offers an element with this functionality already:
<details>
<div>Some content 1</div>
</details>
<details>
<div>Some content 2</div>
</details>
<details>
<div>Some content 3</div>
</details>
<details>
<div>Some content 4</div>
</details>
first, need to get elements with class "parent"
with a for loop bind addEventListener of onclick function
in function find child div element with class "child "
then show the child element
var elements = document.getElementsByClassName("parent");
var myFunction = function() {
var childNode = this.querySelector('.child');
childNode.style.display = "block";
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction, false);
}
.child{
display:none;
}
<div class="parent">p1
<div class="child">p1 Some content</div>
</div>
<div class="parent">p2
<div class="child">p2 Some content</div>
</div>
<div class="parent">p3
<div class="child">p3 Some content</div>
</div>
<div class="parent">p4
<div class="child">p4 Some content</div>
</div>

How to get innerHTML of div, which contains a div?

I'm a wondering how I can get innerHTML of div when it contains a div element and a text. My code looks like this:
var outer = document.getElementById("outer").childNodes;
outer.forEach(function(e) {
console.log(e.innerHTML);
});
<div id="outer">
<div class="item">
<div class="icon"></div>
Hello
</div>
</div>
As you can see, innerHTML is getting the child div and the text, but I only want the text. Is it possible to make it without splitting or something?
I would put Hello in a separate container if you can.
var outer = document.getElementById("outer");
var firstItem = outer.children[0];
var text = firstItem.querySelector('.text').innerHTML;
console.log(text);
<div id="outer">
<div class="item">
<div class="icon"></div>
<span class="text">Hello</span>
</div>
</div>
That way you have more control over it if you want to add more content

FadeOut all id's with the same name

This is my HTML:
<div class="content-box" id="enabled_add">
<h2 class="title">hallo</h2>
<div class="content-box-heading-orange"></div>
<div class="content-box-content">
Hallo
</div>
</div>
<div class="content-box" id="enabled_add">
<h2 class="title">hallo2</h2>
<div class="content-box-heading-orange"></div>
<div class="content-box-content">
Hallo2
</div>
</div>
This is my JS
$('#usernav_close').click(function(){
setTimeout(function(){
$('#enabled_add').fadeOut('slow');
});
});
I want to get all of the content-boxes with the id enabled_add to FadeOut.
But my problem is that only the first element is selected.
ids must be unique. If you try to reuse an id, only the first will be found/updated by jQuery. You want to use a class here.
<div class="content-box enabled_add">
<h2 class="title">hallo</h2>
<div class="content-box-heading-orange"></div>
<div class="content-box-content">
Hallo
</div>
</div>
<div class="content-box enabled_add">
<h2 class="title">hallo2</h2>
<div class="content-box-heading-orange"></div>
<div class="content-box-content">
Hallo2
</div>
</div>
$('#usernav_close').click(function(){
setTimeout(function(){
$('.enabled_add').fadeOut('slow');
});
});
The id attribute is supposed to be unique to an element on a page. You aren't supposed to use the same id twice in one document.
The difference between ids and classes
You can however give an element more than one class.
<div class="content-box enabled_add">
That would mean your selector would read
$('.enabled_add')

Create a div inside div with same class name

I have the following structure of my HTML code:
<div id="bb-bookblock" class="bb-bookblock">
<div class="bb-item">
<div class="bb-custom-side">
Hello
</div>
<div class="bb-custom-side">
<button id="add">Click Here to add The page</button>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is first page</p>
</div>
<div class="bb-custom-side">
<p>Hello</p>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is second Page</p>
</div>
<div class="bb-custom-side">
<p>This is last page</p>
</div>
</div>
</div>
When I click on button with id=add I want to create the a new div after the last bb-item div with same two div inside it having class name bb-custom-side.
I know how to create the div using createElement and it a class, but I don't know how to create the sub div inside that newly created div. Can I associate with the last child or similar concept?
So after click event I want my HTML to be something like this:
<div id="bb-bookblock" class="bb-bookblock">
<div class="bb-item">
<div class="bb-custom-side">
Hello
</div>
<div class="bb-custom-side">
<button id="add">Click Here to add The page</button>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is first page</p>
</div>
<div class="bb-custom-side">
<p>Hello</p>
</div>
</div>
<div class="bb-item">
<div class="bb-custom-side">
<p>This is second Page</p>
</div>
<div class="bb-custom-side">
<p>This is last page</p>
</div>
</div>
<--Newly created div-->
<div class="bb-item">
<div class="bb-custom-side">
new div
</div>
<div class="bb-custom-side">
new div 2
</div>
</div>
</div>
Use clone() to create copy of div elements and append it to main div:
$("#add").click(function(){
var clonedDiv = $(".bb-item:last").clone();
clonedDiv = clonedDiv.find("div.bb-custom-side p").text("This is third Page");
$("#bb-bookblock").append(clonedDiv);
});
DEMO FIDDLE
NOTE: I just updated text for last div (This is third Page). You have to put it in loop to increase number.
Try this.
$('#add').on('click',function(){
$('.bb-item').eq(1).append($('.bb-item:last-child').html());
});
OR
$('#add').click(function(){
$('.bb-item').eq(1).append($('.bb-item:last-child').html());
});
Working Demo
You can try this.
$(document).ready(function () {
$("#add").click(function () {
$("#bb-bookblock").append('<div class="bb-item"><div class="bb-custom-side"> new div</div><div class="bb-custom-side">new div 2</div></div>');
});
});
DEMO
This may not appeal to everyone, but, personally, I tend to like "blank slates" for my cloning.
If it were me, I would do this:
var $baseItem = $("<div></div>").addClass("bb-item");
var $baseCustomSide = $("<div></div>").addClass("bb-custom-side");
$("#add").click(function(){
var $newItem = $baseItem.clone();
$newItem.append($baseCustomSide.clone().html("your_first_content_here"));
$newItem.append($baseCustomSide.clone().html("your_second_content_here"));
$("#bb-bookblock").append($newItem);
});
Unless there is a really good reason to reuse an existing element, I find you end up having to be a lot more complex to "scrub" the existing content from the clone . . . using a blank template always seems more clean to me.

Is there a way to wrapAll() but ignore one element?

If you have the following code:
<div class="parent">
<div class="1"></div>
<div class="2"></div>
<div class="3"></div>
<div class="4"></div>
<div class="5"></div>
</div>
How can I wrap a new div around div with class 2,3,4,5 so it looks like this:
<div class="parent">
<div class="1"></div>
<div class="sub">
<div class="2"></div>
<div class="3"></div>
<div class="4"></div>
<div class="5"></div>
</div>
</div>
wrapAll on the parent would wrap everything with a new div, is there a way to make it ignore the first div?
Use gt(0) to select all but the first one div(direct descendant) and wrapAll. This will select all divs with index greater than 0 present under .parent div.
$('.parent > div:gt(0)').wrapAll('<div class="sub">');
Fiddle
See :gt()
Output:
<div class="parent">
<div class="1">1</div>
<div class="sub">
<div class="2">2</div>
<div class="3">3</div>
<div class="4">4</div>
<div class="5">5</div>
</div>
</div>
Use the not() filter or the :not() selector.
$('.parent div').not('.1').wrapAll('<div class="sub">');
Or alternatively:
$('.parent div:not(.1)').wrapAll('<div class="sub">');
You can also use div:first-child in place of .1 if you always want to ignore the first element.
If the element you want to keep out is not necessarily the first, you could use:
$(".parent div").not("div.1").wrapAll("<div class='sub'>");
Although, this will re-order your divs so that the wrap comes first, and the unwrapped element comes last. Not a problem when it's the first element, but if it's the third, for example, the output would be:
<div class='sub'>
<div class="1"></div>
<div class="2"></div>
<div class="4"></div>
<div class="5"></div>
</div>
<div class="3"></div>
Example:
http://jsfiddle.net/tomtheman5/3TL4M/
edit: Just saw #Corion's answer... This is essentially the same, but with some more information. I'll leave it up.

Categories