Wrap divs depends on their classes with pure JavaScript - javascript

I have the next code:
<div class="components_container">
<div class="first_group">Element 1</div>
<div class="first_group">Element 2</div>
<div class="first_group">Element 3</div>
<div class="second_group">Element 4</div>
<div class="second_group">Element 5</div>
<div class="second_group">Element 6</div>
</div>
And I would like to wrap both groups in different div tags, like this:
<div class="components_container">
<div class="group1">
<div class="first_group">Element 1</div>
<div class="first_group">Element 2</div>
<div class="first_group">Element 3</div>
</div>
<div class="group2">
<div class="second_group">Element 4</div>
<div class="second_group">Element 5</div>
<div class="second_group">Element 6</div>
</div>
</div>

To do what you are trying to accomplish, you can do this in pure javascript:
Get a reference to the container (this code implies that you have only one element with that class):
var container = document.querySelector(".components_container");
Create the two external divs, add the classes and append them to the container:
var first_cont = document.createElement("div");
var second_cont = document.createElement("div");
first_cont.classList.add("group1");
second_cont.classList.add("group2");
container.appendChild(first_cont);
container.appendChild(second_cont);
Get the divs with a specific class and change their parent (remove child / append child):
var first_elements = container.querySelectorAll(".first_group");
var second_elements = container.querySelectorAll(".second_group");
for (el of first_elements) {
container.removeChild(el);
first_cont.appendChild(el);
}
for (el of second_elements) {
container.removeChild(el);
second_cont.appendChild(el);
}
This will do what you want, but please, next time try to add some more information, like some context, the steps that you tried or where are you finding difficulties :)

Related

select a next element with a specific class in JS

Well, I have n elements with the class "class_one"
and certain other elements with the class "class_two".
These elements are nested and in some cases there are other elements in that nest, what I need is to select the next element with a specific class.
let class_one = document.querySelectorAll('.class_one');
class_one.forEach(element => {
element.addEventListener('click',()=>{
console.log("From this element, the next one containing the class class_two");
})
});
<div class="class_one">
click 1
</div>
<div class="class_two">elemento 1</div>
<div class="class_one">
click 2
</div>
<div class="class_four"></div>
<div class="class_two">elemento 2</div>
<div class="class_one">
click 3
</div>
<div class="class_six"></div>
<div class="class_two">elemento 3</div>
<div class="class_one">
click 4
</div>
<div class="class_five">click 5</div>
<div class="class_two">elemento 4</div>
<div class="class_one">
click 6
</div>
<div class="class_two"></div>
Personally, I would like an answer without using Jquery, but all are welcome.

Select any element with class '' in JS

how can I extract the text-value of an element with class 'test' f.e. based on the numbering?
Here is an example:
console.log($('ex.test')[3].text())
Thx in advance
Either use .eq() that will return an element from the index of it or use a CSS selector like :nth-child().
console.log($('.test').eq(3).text());
console.log($('.test:nth-child(4)').text());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="test">div 1</div>
<div class="test">div 2</div>
<div class="test">div 3</div>
<div class="test">div 4</div>
</div>

Reverse order only of divs with same class inside other divs

My problem is here: http://jsfiddle.net/9vhobdw7/2/
<div class="c-container">
<div>Container 4
<div>my div 4</div>
<div class="item">4</div>
</div>
<br>
<div>Container 3
<div>my div 3</div>
<div class="item">3</div>
</div>
<br>
<div>Container 2
<div>my div 2</div>
<div class="item">2</div>
</div>
<br>
<div>Container 1
<div>my div 1</div>
<div class="item">1</div>
</div>
</div>
I'd like to have only the divs with class="item" in reverse order, from bottom to top. Other divs need to be the same. Like this:
<div class="c-container">
<div>Container 4
<div>my div 4</div>
<div class="item">1</div>
</div>
<br>
<div>Container 3
<div>my div 3</div>
<div class="item">2</div>
</div>
<br>
<div>Container 2
<div>my div 2</div>
<div class="item">3</div>
</div>
<br>
<div>Container 1
<div>my div 1</div>
<div class="item">4</div>
</div>
</div>
Actually in the divs class="item" I have a call from divs from external URL with function load:eq(n).
I've tried with CSS, .each().reverse(), Array, replaceWith() and more functions but nothing, have no significant result.
Edit, add task.
Now, if the task includes more classes, with divs inside to reverse as
<div class="c-container">
<div>Container 6
<div>my div 6</div>
<div class="item2">3</div>
</div>
<br>
<div>Container 5
<div>my div 5</div>
<div class="item1">1</div>
</div>
<br>
<div>Container 4
<div>my div 4</div>
<div class="item2">2</div>
</div>
<br>
<div>Container 3
<div>my div 3</div>
<div class="item2">1</div>
</div>
<br>
<div>Container 2
<div>my div 2</div>
<div class="item1">2</div>
</div>
<br>
<div>Container 1
<div>my div 1</div>
<div class="item1">3</div>
</div>
</div>
I have to duplicate the function changing the variables names and classes names? I've tried this
const children1 = document.querySelectorAll('.c-container .item1');
const reverse1 = [...children1].reverse();
children1.forEach((item, i) => item.outerHTML = reverse1[i].outerHTML);
const children2 = document.querySelectorAll('.c-container .item2');
const reverse2 = [...children2].reverse();
children2.forEach((item, i) => item.outerHTML = reverse2[i].outerHTML);
which works, but it seems redundant.
Here's a solution, not really swapping divs, just swapping content:
var items=document.getElementsByClassName("item");
var length=items.length;
for(var i=0; i<Math.floor(length/2); i++) {
var temp=items[i].innerHTML;
items[i].innerHTML=items[length-i-1].innerHTML;
items[length-i-1].innerHTML=temp;
}
items and length are helper vars.
innerHTML can be replaced with innerText.
etc...
Edit: fixed with Math.floor(length/2). (There's an extra swap when length is odd...)
You can replace innerHtml for div with class item:
$(document).ready(function() {
var listItems = Array.from(document.getElementsByClassName('item')).map(i=>i.cloneNode(true))
Array.from(document.getElementsByClassName('item')).forEach((item,index)=>{
item.innerHTML = listItems[listItems.length-index-1].innerHTML
})
});
See full example in the playground: http://jsfiddle.net/denisstukalov/7uhmzbct/23/
You shouldnt be trying to reverse the divs... You are trying to reverse what those divs display. So, you can build an array of the contents of the "item" divs themselves. Then reverse the order of that array and then replace the innerHTML of your "item" divs.
Example below... it is not the most effecient code because it iterates over your list twice... but for the purposes of showing what you need to do to accomplish what it sounds like you're wanting, I think its more illustrative.
function reverseItemContents() {
var itemDivs = document.getElementsByClassName("item");
var contentList = [];
var index;
for (index = 0; index < itemDivs.length; index++) {
contentList.push(itemDivs[index].innerHTML);
}
contentList.reverse();
for (index = 0; index < itemDivs.length; index++) {
itemDivs[index].innerHTML = contentList[index];
}
}
<button onClick="reverseItemContents()">Reverse Content</button>
<div class="c-container">
<br>
<div>Container 4
<div>my div 4</div>
<div class="item"><img src="https://upload.wikimedia.org/wikipedia/commons/1/16/Eo_circle_blue-grey_white_number-4.svg" width="130"></div>
</div>
<br>
<div>Container 3
<div>my div 3</div>
<div class="item"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/NYCS-bull-trans-3.svg/1024px-NYCS-bull-trans-3.svg.png" width="130"></div>
</div>
<br>
<div>Container 2
<div>my div 2</div>
<div class="item">
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d8/Icon_2_red.svg" width="130"></div>
</div>
<br>
<div>Container 1
<div>my div 1</div>
<div class="item"><img src="https://upload.wikimedia.org/wikipedia/commons/f/f4/Icon_1_%28set_orange%29.png" width="130"></div>
</div>
</div>
My method would be to simply select them all, reverse the array, and then overwrite the original items. Using outerHTML means that more than just the divs' contents will be swapped.
function reverse(selector) {
const children = document.querySelectorAll(selector);
const reversed = [...children].reverse();
children.forEach((item, i) => item.outerHTML = reversed[i].outerHTML);
}
<div class="c-container">
<div>Container 4
<div>my div 4</div>
<div class="item" style="background-color: tomato;">4</div>
</div>
<br>
<div>Container 3
<div>my div 3</div>
<div class="item" style="background-color: orange;">3</div>
</div>
<br>
<div>Container 2
<div>my div 2</div>
<div class="item" style="background-color: yellow;">2</div>
</div>
<br>
<div>Container 1
<div>my div 1</div>
<div class="item" style="background-color: lightgreen;">1</div>
</div>
</div>
<button onclick="reverse('.c-container .item')">Reverse</button>
I don't really see a need to add all the extra complexity proposed by the other answers. Using an arugment will allow you to re-use the function for other sets of nodes.

How can I access third div when clicked only by class in Jquery or Javascript

I have four div of same class, but I want to access each div when clicked only by class name for any further action only by java script/Jquery
<div class="myclass">something</div>
<div class="myclass">something 2</div>
<div class="myclass">something 4</div>
<div class="myclass">something 3</div>
Try using jquery class selector with on click handler
$(function() {
$('.myclass').on('click', function() {
alert($(this).text());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="myclass">something</div>
<div class="myclass">something 2</div>
<div class="myclass">something 4</div>
<div class="myclass">something 3</div>
You can use the following jquery:
$(".myclass").click(function(e)
{
var div = this;
});

How can I hide elements in my list and add a 'show more' feature?

I'm using javascript to build a list of results. I have a for-loop that iterates over some data and creates a mydata div, and adds that to the results div. Let's pretend it looks something like this:
<div id="results">
<div class="mydata">data 1</div>
<div class="mydata">data 2</div>
...
<div class="mydata">data 20</div>
</div>
What I want to do is only display 5 results at a time, and should the user wish to see more, they can click a show next 5 or show more button (or something similar). Any ideas?
Just to clarify, every time the user clicks "show more" I want to 'unhide' the next 5 elements, not ALL the remaining elements. So each click reveals more elements until all are displayed.
You can use the gt() and lt() selectors along with :visible pretty well here.
The following will show the next 5 results on clicking and removes the link once all items are visible.
$('.mydata:gt(4)').hide().last().after(
$('<a />').attr('href','#').text('Show more').click(function(){
var a = this;
$('.mydata:not(:visible):lt(5)').fadeIn(function(){
if ($('.mydata:not(:visible)').length == 0) $(a).remove();
}); return false;
})
);
working example: http://jsfiddle.net/niklasvh/nTv7D/
Regardless of what other people are suggesting here, I would not hide the elements using CSS, but do it in JS instead, because if a user has JS disabled and you hide the elements using CSS, he won't get them visible. However, if he has JS disabled, they will never get hidden, nor will that button appear etc, so it has a full noscript fallback in place + search engines don't like hidden content (but they won't know its hidden if you do it on DOM load).
My solution is here: jsFiddle.
You can put this link somewhere:
show more
and use the following code:
var limit = 5;
var per_page = 5;
jQuery('#results > div.mydata:gt('+(limit-1)+')').hide();
if (jQuery('#results > div.mydata').length <= limit) {
jQuery('#results-show-more').hide();
};
jQuery('#results-show-more').bind('click', function(event){
event.preventDefault();
limit += per_page;
jQuery('#results > div.mydata:lt('+(limit)+')').show();
if (jQuery('#results > div.mydata').length <= limit) {
jQuery(this).hide();
}
});
where limit is your current number of results displayed and per_page is number of results shown with each click on "show more". The link disappears if all the results are displayed. See how it works on jsFiddle.
You can create a CSS class like:
.hiddenData { display: none }
and attach it to any quantity of divs that exceeds 5.
After that make handlers for adding/deleting this class from the needed quantity of divs.
jQuery for class removing:
$(".hiddenData").removeClass("hiddenData")
Create a class with something like:
.hidden_class{
display: none;
}
Add this class to all the mydata div's that you dont want seen.
when the user click the button, remove it from the next 5 div's.
repeat everytime the user clicks the "read more" button
This should work...Let me know how it goes
<script type="text/javascript">
function ShowHide(id) { $("#" + id).toggle(); }
</script>
<div id="results">
<div class="mydata">data 1</div>
<div class="mydata">data 2</div>
<div class="mydata">data 3</div>
<div class="mydata">data 4</div>
<div class="mydata">data 5</div>
<div style="clear:both" onclick="ShowHide('grp6')">More</div>
<div id="grp6" style="display:none">
<div class="mydata">data 6</div>
<div class="mydata">data 7</div>
<div class="mydata">data 8</div>
<div class="mydata">data 9</div>
<div class="mydata">data 10</div>
</div>
<div style="clear:both" onclick="ShowHide('grp11')">More</div>
<div id="grp11" style="display:none">
<div class="mydata">data 11</div>
<div class="mydata">data 12</div>
<div class="mydata">data 13</div>
<div class="mydata">data 14</div>
<div class="mydata">data 15</div>
</div>
</div>
In your forloop, you also have to add these divs hidden container
<div style="clear:both" onclick="ShowHide('grp6')">More</div>
<div id="grp6" style="display:none">
You get the idea.
Here you have:
<style>
/*This hides all items initially*/
.mydata{
display: none;
}
</style>
Now the script
<script>
var currentPage = 1; //Global var that stores the current page
var itemsPerPage = 5;
//This function shows a specific 'page'
function showPage(page){
$("#results .mydata").each(function(i, elem){
if(i >= (page-1)*itemsPerPage && i < page*itemsPerPage) //If item is in page, show it
$(this).show();
else
$(this).hide();
});
$("#currentPage").text(currentPage);
}
$(document).ready(function(){
showPage(currentPage);
$("#next").click(function(){
showPage(++currentPage);
});
$("#prev").click(function(){
showPage(--currentPage);
});
});
</script>
And a sample html:
<div id="results">
<div class="mydata">data 1</div>
<div class="mydata">data 2</div>
<div class="mydata">data 3</div>
<div class="mydata">data 4</div>
<div class="mydata">data 5</div>
<div class="mydata">data 6</div>
<div class="mydata">data 7</div>
<div class="mydata">data 8</div>
<div class="mydata">data 9</div>
<div class="mydata">data 10</div>
<div class="mydata">data 11</div>
<div class="mydata">data 12</div>
</div>
Previous
<span id="currentPage"></span>
Next
The only thing remaining is to validate fot not going to a page lower than 1 and higher than the total. But that will be easy.
EDIT: Here you have it running: http://jsfiddle.net/U8Q4Z/
Hope this helps. Cheers.

Categories

Resources