grouping nodeList elements into separate Groups - javascript

I have following nodeList
['<div class="item">1</div>', '<div class="item">2</div>', '<div class="item">3</div>', '<div class="item">4</div>']
and following function which accepts the number of element for a group and generates group of elements wrapped by divs
function groupElms (nOfElms) {
var count = 0;
[].forEach.call(nL, function (item) {
count++;
});
}
lets say noOfElms is 2 then the function should generate Elements like this
<div>
<div class="item">1</div>
<div class="item">2</div>
</div>
<div>
<div class="item">3</div>
<div class="item">4</div>
</div>
if noOfElms is 3 it should be like
<div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div>
<div class="item">4</div>
</div>
I dont understand how to achieve this. Please Could someone help me with this.

You can simply loop through your items and place every N of them into a created wrapper like this:
function groupNodes(list, groupBy)
{
var list = [].slice.call(list);
var parent = list[0].parentElement;
for (var i = 0; i < list.length; i += groupBy)
{
var lastWrapper = document.createElement('div');
lastWrapper.className = 'wrapper';
parent.appendChild(lastWrapper);
[].forEach.call(list.slice(i, i + groupBy), function(x) {
lastWrapper.appendChild(x);
});
}
}
groupNodes(document.getElementsByClassName('item'), 3);
.wrapper {
border: 2px solid black;
}
<div id="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>
Note that it is supposed that all of these items are siblings. Otherwise, they all will be moved to the parent of the first item.
It can be done even easier using jQuery .wrap() function:
function groupNodes(selector, groupBy)
{
var $list = $(selector);
for (var i = 0; i < $list.length; i += groupBy)
$list.slice(i, i + groupBy).wrapAll('<div class="wrapper"></div>');
}
groupNodes('.item', 3);
.wrapper {
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
</div>

use the following
lets say
var a = ['<div class="item">1</div>', '<div class="item">2</div>', '<div class="item">3</div>', '<div class="item">4</div>'];
then function should be written like the following
function groupElms (nOfElms) {
var count = 1;
a.forEach(function (item) {
if(count == 1) {
var tempDiv = document.createElement("div");
}
tempDiv.appendChild(item);
if(count == nOfElms) {
document.body.appendChild(tempDiv);
delete tempDiv;
count=1;
}
count++;
});
}

Related

How to toggle/switch the classes between three or more divs in a sequence?

How can I easily toggle/switch the classes between three or more divs in a sequence by click?
Example html:
<div class="box">Box 1</div>
<div class="box active">Box 2</div>
<div class="box">Box 3</div>
<div class="next">Next</div>
<div class="back">Back</div>
This way just works with two:
$(".next, .back").click(function(){
$(".box").toggleClass("active");
});
Simply to check if nth-child has the active class and loop.
$(".next").click(function(){
$(".box").each( function(i, j) {
if( $(this).hasClass('active') ) {
$(this).removeClass('active');
$(".box:nth-child("+(((i+1)%$(".box").length)+1)+")").addClass('active');
return false;
}
});
});
$(".back").click(function(){
$(".box").each( function(i, j) {
if( $(this).hasClass('active') ) {
$(this).removeClass('active');
$(".box:nth-child("+(((i-1)+$(".box").length)%$(".box").length+1)+")").addClass('active');
return false;
}
});
});
.active {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="box">Box 1</div>
<div class="box active">Box 2</div>
<div class="box">Box 3</div>
<div class="back">Back</div>
<div class="next">Next</div>
</div>
This is pretty generic
$(".nav").on("click", function() {
var dir = $(this).is(".next") ? 1 : -1; // which direction are we going?
var active = $(".box.active").index() - 1;
var $boxes = $(".box");
active += (1 * dir);
if (active < 0) active = $boxes.length - 1; // wrap
else if (active >= $boxes.length) active = 0;
$(".box").removeClass("active");
$(".box").eq(active).addClass("active");
});
.active {
color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">Box 1</div>
<div class="box active">Box 2</div>
<div class="box">Box 3</div>
<br/>
<div class="nav back">Back</div>
<div class="nav next">Next</div>
I've created another solution that gets the button's ID (which I've added) and uses that to dictate where to go.
var box = $('.box');
var maxBoxes = box.length;
$("#nextBtn, #backBtn").click(function() {
var getBtn = $(this).get(0).id,
activeBox = $('.box.active'),
position = activeBox.index();
activeBox.removeClass('active');
if (getBtn === 'nextBtn') {
(position == maxBoxes) ? box.eq(0).addClass('active'): activeBox.next().addClass('active');
} else {
(position === 1) ? box.last().addClass('active'): activeBox.prev().addClass('active');
}
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box active">Box 3</div>
<div id="nextBtn" class="next">Next</div>
<div id="backBtn" class="back">Back</div>
I think that the following should be efficient, because it will not do unnecessary checks.
var last = $(".active")
function toggle(dir){
var future = last[dir]();
if(!(future.length && future.hasClass('box'))) {
return;
}
last.toggleClass("active")
last = future
last.toggleClass("active");
}
$(".next").click(toggle.bind(void 0, 'next'));
$(".back").click(toggle.bind(void 0, 'prev'));

How can I toggle a class to various items?

I just want to toggle a class from various items. I mean, I have 5 divs with .item class inside a div with .container class. Can I toggle a new class to those 5 .items? Maybe with a loop?
I was trying to do it but it seems that the loop goes infinite.
This is what I tried:
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<button onclick="myFunction()"></button>
</div>
<script>
function myFunction () {
var x = document.getElementsByClassName("item");
for (i=0; i<x.length; i+1) {
x[i].classList.toggle('new-class');
}
}
</script>
I expect something like this at the end (maybe with some loop in JS):
<div class="container">
<div class="item new-class"></div>
<div class="item new-class"></div>
<div class="item new-class"></div>
<div class="item new-class"></div>
<div class="item new-class"></div>
</div>
You can do it by using the for loop and the classList.add() method.
function myFunction() {
var items = document.querySelectorAll('.item');
for(var i = 0; i < items.length; i++) {
items[i].classList.add('new-class');
}
}

How can I sort divs with javascript

I would like to sort a few divs in ascending order based on their data-id. How can I do that?
<div class="container" data-id="1000">
<div id="H1"></div>
<div id="sub">sub 1</div>
<div id="sub">sub 2</div>
</div>
<div class="container" data-id="3000">
<div id="H1"></div>
<div id="sub"></div>
<div id="sub"></div>
</div>
<div class="container" data-id="2000">
<div id="H1"></div>
<div id="sub"></div>
<div id="sub"></div>
</div>
I've found the solution to my problem a while ago:
function sortOut() {
// get the classname chapcontainer
var classname = document.getElementsByClassName('container');
// create a variable and put the classes it into an array.
var divs = [];
for (var i = 0; i < classname.length; ++i) {
divs.push(classname[i]);
}
// Sort the divs based on data-id.
divs.sort(function(a, b) {
return +a.getAttribute("data-id") - +b.getAttribute("data-id");
});
};
divs.sort does the trick. More info about this function can be found here:
https://www.w3schools.com/jsref/jsref_sort.asp

Toggle a class on and off between two elements

I have this html:
<div class="container">
<div id="element-1" class="element-show"></div>
<div id="element-2"></div>
</div>
I want class element-show to hide from element-1 and show in element-2 and vice versa; called from one function in jQuery.
Any way I can do this properly?
will something like that be OK?
$("button").on("click", function(e){
$('.container').children("div").toggleClass("element-show");
})
.element-show{
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="element-1" class="element-show">x</div>
<div id="element-2">y</div>
</div>
<button>Toggle class</button>
You can achieve that by doing this:
function getClass() {
var children_container = document.getElementsByClassName("container")[0].children;
for (var i = 0; i < children_container.length; i++) {
if ($(children_container[i]).hasClass('element-show')) {
$(children_container[i]).removeClass();
if (i == "0") {
$(children_container[1]).addClass("element-show");
break;
} else if (i == "1") {
$(children_container[0]).addClass("element-show");
break;
}
}
};
};
getClass();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="element-1" class="element-show"></div>
<div id="element-2"></div>
</div>
If you have more than 2 elements and you want to add the class on rest of them and remove it from the element which already has that class, then you can achieve that by doing this (this function will also work for the case you mentioned too):
function getClass() {
var children_container = document.getElementsByClassName("container")[0].children;
var class_elem;
for (var i = 0; i < children_container.length; i++) {
if ($(children_container[i]).hasClass('element-show')) {
class_elem = i;
$(children_container[i]).removeClass();
i = 0;
}
if (class_elem != undefined) {
if (i != class_elem) {
$(children_container[i]).addClass('element-show');
}
};
};
};
getClass();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="element-0"></div>
<div id="element-1" class="element-show"></div>
<div id="element-2"></div>
<div id="element-3"></div>
<div id="element-4"></div>
</div>

Add new row every set number of children

I am trying to add a new row every 2 childrens and place 2 new childrens inside a new row each time.
The starting html:
<div class="row_1"></div>
After the first run i get:
<div class="newRow">
<div class="span6" id="content"></div>
</div>
<div class="row_1"></div>
But as I keep adding I get:
<div class="newRow">
<div class="span6">...</div>
<div class="span6" id="content">...</div>
<div class="span6" id="content"></div> <== Empty extra div
</div>
<div class="newRow"></div> <== Empty extra div
<div class="row_1"></div>
Expected result would be
<div class="newRow">
<div class="span6">...</div>
<div class="span6" id="content">...</div>
</div>
<div class="newRow">
<div class="span6">...</div>
<div class="span6">...</div>
</div>
<div class="row_1"></div>
The following is the jQuery I am using
$(".nav li a").on("click", function(e) {
$('#content').removeAttr('id');
var $row = $(".row_1");
var $rowNew = $('.newRow');
if($rowNew.length < 2){
$('<div id="content" class="span6"></div>').appendTo('.newRow');
}
if ($rowNew.children().length > 2) {
$('<div class="row-fluid new"></div>').insertBefore($row);
}
else {
$('<div class="row-fluid new"></div>').insertBefore($row);
$('<div id="content" class="span6"></div>').appendTo('.newRow');
}
});
"Eventually I solved it with":
$(".nav li a").on("click", function(e) {
$('#content').removeAttr('id');
var $row = $(".span9");
var $rowNew = $('.new');
if ($rowNew.children().length > 1) {
$(".span9 div").removeClass("new");
$('<div class="row-fluid new"></div>').prependTo($row);
}
if ($(".new").length == 0) {
$('<div class="row-fluid new"></div>').prependTo($row);
$('<div id="content" class="span6"></div>').appendTo('.new');
} else {
$('<div id="content" class="span6"></div>').appendTo('.new');
}
});

Categories