Trying to show some element on first render and when user click on Load More will show some more data and this will happen until all element show on each click;
const itemPerPage = 2;
Here is what I had tried with -
document.addEventListener('DOMContentLoaded', () => {
const itemPerPage = 2;
const AllItems = [...document.querySelectorAll('.item')];
const btnLoadMore = document.getElementsByClassName('btn-loadmore')[0];
if (itemPerPage > 0 && AllItems?.length > 0) {
var firstRenderItems = Array.from(AllItems).slice(0, itemPerPage);
if (firstRenderItems?.length > 0) {
firstRenderItems.forEach(element => {
element.style.display = 'block';
});
}
}
if (btnLoadMore && AllItems?.length > itemPerPage) {
btnLoadMore.style.display = 'block';
}
});
.container{
display:block;
padding: 20px;
}
.item{
display: none;
align-items: center;
justify-content: flex-start;
min-height: 70px;
border-bottom: 1px solid #ddd;
}
.btn-loadmore{
display:none;
}
<html>
<head>
</head>
<body>
<div class='container'>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
<div class='item'>Content 1</div>
</div>
<button class='btn-loadmore'>Load More</button>
</body>
</htmL>
Is this what you want?
document.addEventListener('DOMContentLoaded', () => {
let current = 2
const AllItems = [...document.querySelectorAll('.item')]
const btnLoadMore = document.getElementById('btn')
if (AllItems.length > 0) {
let firstRenderItems = Array.from(AllItems).slice(0, current);
if (firstRenderItems.length > 0) {
firstRenderItems.forEach(element => {
element.style.display = 'block'
})
}
}
btnLoadMore.addEventListener('click', () => {
if (AllItems.length > current) {
current++
if(current >= AllItems.length) btnLoadMore.style.display = 'none'
const list = Array.from(AllItems).slice(0, current)
list[current - 1].style.display = 'block'
}
})
})
.container{
display:block;
padding: 20px;
}
.item{
display: none;
align-items: center;
justify-content: flex-start;
min-height: 70px;
border-bottom: 1px solid #ddd;
}
<html>
<head>
</head>
<body>
<div class='container'>
<div class='item'>Content 1</div>
<div class='item'>Content 2</div>
<div class='item'>Content 3</div>
<div class='item'>Content 4</div>
<div class='item'>Content 5</div>
<div class='item'>Content 6</div>
<div class='item'>Content 7</div>
<div class='item'>Content 8</div>
<div class='item'>Content 9</div>
<div class='item'>Content 10</div>
</div>
<button class='btn-loadmore' id='btn'>Load More</button>
</body>
</htmL>
Loads 2 items each time you click load more and hides the button once all items are loaded. I didn't see a reason why the items array couldn't be used to track the remaining hidden items so I used items.splice() instead of counting and comparing length to item count.
var items = [];
const itemPerPage = 2;
var btnLoadMore;
function buttonToggle() {
if (btnLoadMore && items.length) {
btnLoadMore.style.display = 'block';
} else {
btnLoadMore.style.display = 'none';
}
}
function loadMore() {
if (items.length) {
items.splice(0, itemPerPage).forEach(item => {
item.style.display = 'block';
})
}
buttonToggle();
}
document.addEventListener('DOMContentLoaded', () => {
items = [...document.querySelectorAll('.item')];
btnLoadMore = document.querySelector('.btn-loadmore');
if (itemPerPage > 0 && items.length) {
loadMore();
}
});
.container {
display: block;
padding: 20px;
}
.item {
display: none;
align-items: center;
justify-content: flex-start;
min-height: 70px;
border-bottom: 1px solid #ddd;
}
.btn-loadmore {
display: none;
}
<html>
<head>
</head>
<body>
<div class='container'>
<div class='item'>Content 1</div>
<div class='item'>Content 2</div>
<div class='item'>Content 3</div>
<div class='item'>Content 4</div>
<div class='item'>Content 5</div>
<div class='item'>Content 6</div>
<div class='item'>Content 7</div>
<div class='item'>Content 8</div>
<div class='item'>Content 9</div>
<div class='item'>Content 10</div>
<div class='item'>Content 11</div>
<div class='item'>Content 12</div>
<div class='item'>Content 13</div>
<div class='item'>Content 14</div>
<div class='item'>Content 15</div>
</div>
<button class='btn-loadmore' onclick='loadMore()'>Load More</button>
</body>
</htmL>
To show 2 items per page, one needs to add the button onclick handler using something similar to below:
Code Snippet
const itemPerPage = 2;
const AllItems = [];
const loadItems = (currLastItem) => {
AllItems.slice(
currLastItem, currLastItem + itemPerPage
).forEach(
el => el.style.display = 'block'
);
};
document.addEventListener('DOMContentLoaded', () => {
let currLastItem = 0;
[...document.querySelectorAll('.item')].forEach(el => AllItems.push(el));
const btnLoadMore = document.getElementsByClassName('btn-loadmore')[0];
if (AllItems?.length > 0) {
loadItems(currLastItem);
currLastItem += itemPerPage;
}
if (btnLoadMore && currLastItem < AllItems?.length) {
btnLoadMore.style.display = 'block';
btnLoadMore.onclick = () => {
loadItems(currLastItem);
currLastItem += itemPerPage;
if (currLastItem >= AllItems?.length) {
btnLoadMore.style.display = 'none';
}
}
}
});
.container{
display:block;
padding: 20px;
}
.item{
display: none;
align-items: center;
justify-content: flex-start;
min-height: 70px;
border-bottom: 1px solid #ddd;
}
.btn-loadmore{
display:none;
}
<html>
<head>
</head>
<body>
<div class='container'>
<div class='item'>Content 1</div>
<div class='item'>Content 2</div>
<div class='item'>Content 3</div>
<div class='item'>Content 4</div>
<div class='item'>Content 5</div>
<div class='item'>Content 6</div>
<div class='item'>Content 7</div>
<div class='item'>Content 8</div>
<div class='item'>Content 9</div>
<div class='item'>Content 10</div>
<div class='item'>Content 11</div>
<div class='item'>Content 12</div>
<div class='item'>Content 13</div>
<div class='item'>Content 14</div>
<div class='item'>Content 15</div>
</div>
<button class='btn-loadmore'>Load More</button>
</body>
</htmL>
Related
I have the following structure example:
<div class="main">
<div class="image">Image1</div>
<div class="image">Image2</div>
<div class="image">Image3</div>
</div>
<div class="side">
<div class="Banner">Banner1</div>
<div class="Banner">Banner2</div>
<div class="Banner">Banner3</div>
<div class="Banner">Banner4</div>
</div>
I want to make a script that will take each banner and placed under each image.
<div class="main">
<div class="image">Image1</div>
<div class="Banner">Banner1</div>
<div class="image">Image2</div>
<div class="Banner">Banner2</div>
<div class="image">Image3</div>
<div class="Banner">Banner3</div>
<div class="Banner">Banner4</div>
</div>
<div class="side"></div>
Basically there are some images placed one after another and then some banners placed one after another.
Image1
Image2
Image3
Banner1
Banner2
Banner3
Banner4
I need to take each banner and place it under each image so I can have:
Image1
Banner1
Image2
Banner2
Image3
Banner3
Banner4
I cannot change the html to manually placed the banners, I need to use a more advanced script JS and or jquery ..
.content {display:flex; max-width:800px;min-width:300px;gap:20px;margin:auto;}
.main { flex: 70%;}.main2 {max-width:400px;}
.side { flex: 30%; padding:10px;}.img { background:blue;}.banner { background:red;}
.img, .banner { width:100%; min-width:50px; height:50px;display:grid;place-items:center; color: #fff; margin:10px auto;}
<h2>Rearrange content - Place each div (banner) under each image </h2>
<div class="content">
<div class="main">
<div class="img">Image 1</div>
<div class="img">Image 2</div>
<div class="img">Image 3</div>
<div class="img">Image 4</div>
<div class="img">Image 5</div>
<div class="img">Image 6</div>
<p> Multiple DIVs with images ...
<br> ...
</div>
<div class="side">
<div class="banner">Banner1</div>
<div class="banner">Banner2</div>
<div class="banner">Banner3</div>
<div class="banner">Banner4</div>
<div class="banner">Banner5</div>
<div class="banner">Banner6</div>
<div class="banner">Banner7</div>
<div class="banner">Banner8</div>
<div class="banner">Banner9</div>
<div class="banner">Banner10</div>
</div>
</div>
<hr>
<h2> This is how it should look </h2>
<div class="main2">
<div class="img">Image 1</div>
<div class="banner">Banner1</div>
<div class="img">Image 2</div>
<div class="banner">Banner2</div>
<div class="img">Image 3</div>
<div class="banner">Banner3</div>
<div class="img">Image 4</div>
<div class="banner">Banner4</div>
<div class="img">Image 5</div>
<div class="banner">Banner5</div>
<div class="img">Image 6</div>
<div class="banner">Banner6</div>
<div class="banner">Banner7</div>
<div class="banner">Banner8</div>
<div class="banner">Banner9</div>
<div class="banner">Banner10</div>
</div>
To do what you require you can loop through the .banner elements and use their index to place them underneath the related .img element by their indexes using insertAfter(). Something like this:
let $imgs = $('.content .main .img');
$('.content .side .banner').each((i, el) => $(el).insertAfter($imgs[i]));
.content {
display: flex;
max-width: 800px;
min-width: 300px;
gap: 20px;
margin: auto;
}
.main {
flex: 70%;
}
.img,
.banner {
width: 100%;
min-width: 50px;
height: 50px;
display: grid;
place-items: center;
color: #fff;
margin: 10px auto;
}
.img {
background: blue;
}
.banner {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="content">
<div class="main">
<div class="img">Image 1</div>
<div class="img">Image 2</div>
<div class="img">Image 3</div>
<div class="img">Image 4</div>
<div class="img">Image 5</div>
<div class="img">Image 6</div>
</div>
<div class="side">
<div class="banner">Banner1</div>
<div class="banner">Banner2</div>
<div class="banner">Banner3</div>
<div class="banner">Banner4</div>
<div class="banner">Banner5</div>
<div class="banner">Banner6</div>
</div>
</div>
Well, to answer my own question, it was hard for me since I don't know JS that well.
I managed to make something that also randomizes the banners and I've used jquery.
jQuery("#btn").click(function() {
var cards = jQuery(".side .banner");
for(var i = 0; i < cards.length; i++){
var target = Math.floor(Math.random() * cards.length -1) + 1;
var target2 = Math.floor(Math.random() * cards.length -1) +1;
cards.eq(target).before(cards.eq(target2));
}
cards = jQuery(".side .banner");
var images = jQuery(".content.desk .img");
if (cards.length < images.length) {
for (var i=0; i<cards.length; i++) {
images.eq(i).after(cards.eq(i));
}
} else {
for (var i=0; i<images.length; i++) {
images.eq(i).after(cards.eq(i))
}
for (var i=images.length; i<cards.length; i++){
cards.eq(i-1).after(cards.eq(i));
}
}
});
body {
max-width:1250px;
margin:auto;
}
h1, h2, h3, h4 {
text-align:center;
}
.content {
display:flex;
max-width:800px;
min-width:300px;
gap:20px;
margin:auto;
}
.main {
flex: 70%;
}
.side {
flex: 30%;
background: lightblue;
padding:10px;
}
.img {
background:blue;
}
.banner {
background:red;
}
.img, .banner {
width:100%;
min-width:50px;
height:50px;
display:grid;
place-items: center;
color: #fff;
margin:10px auto;
}
<body>
<h1>Rearrange content</h1>
<div class="content desk">
<div class="main">
<button id="btn">Click to reorder and randomize</button>
<div class="img">Image 1</div>
<div class="img">Image 2</div>
<div class="img">Image 3</div>
<div class="img">Image 4</div>
<div class="img">Image 5</div>
<div class="img">Image 6</div>
<div class="img">Image 7</div>
<div class="img">Image 8</div>
<div class="img">Image 9</div>
<div class="img">Image 10</div>
<div class="img">Image 11</div>
<div class="img">Image 12</div>
<div class="img">Image 13</div>
</div>
<div class="side">
<div class="banner">Banner1</div>
<div class="banner">Banner2</div>
<div class="banner">Banner3</div>
<div class="banner">Banner4</div>
<div class="banner">Banner5</div>
<div class="banner">Banner6</div>
<div class="banner">Banner7</div>
<div class="banner">Banner8</div>
<div class="banner">Banner9</div>
<div class="banner">Banner10</div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
</body>
Edit:
Here's another method that's a bit more concise.
const main = document.querySelectorAll('.main .img');
const side = document.querySelectorAll('.side .banner');
let offset;
side.forEach((banner, idx) => {
const img = main[idx] || offset;
img.insertAdjacentElement('afterend', banner);
offset = banner;
});
.content { display: flex }
.main, .side { flex-grow: 1 }
.content,
.main2 {
font-family: sans-serif;
line-height: 2;
color: white;
}
.img { background-color: red; margin: 3px;}
.banner { background-color: blue; margin: 3px;}
<div class="body">
<h2>Rearrange content - Place each div (banner) under each image </h2>
<div class="content">
<div class="main">
<div class="img">Image 1</div>
<div class="img">Image 2</div>
<div class="img">Image 3</div>
<div class="img">Image 4</div>
<div class="img">Image 5</div>
<div class="img">Image 6</div>
</div>
<div class="side">
<div class="banner">Banner1</div>
<div class="banner">Banner2</div>
<div class="banner">Banner3</div>
<div class="banner">Banner4</div>
<div class="banner">Banner5</div>
<div class="banner">Banner6</div>
<div class="banner">Banner7</div>
<div class="banner">Banner8</div>
<div class="banner">Banner9</div>
<div class="banner">Banner10</div>
</div>
</div>
</div>
Original:
You need to loop over the elements and then merge/combine the arrays as you are looping. There are multiple ways this can be done. Here's one way (with comments) that uses reduce to combine the elements.
If you're starting out with JS, I would suggest using a simple for loop to start off.
When you run the code snippet below, the original will be in Red. Clicking the button will merge the elements, append them, and display them in Green.
Good luck!
// I've wrapped this in a function so I can call it.
function rearrange() {
// First I'm going to query all the divs with 'img' class
// From that, I'll call 'Array.from' to create an array.
const images = Array.from(document.querySelectorAll('.img'));
// Similar to above, but for all the 'banner' divs.
const banners = Array.from(document.querySelectorAll('.banner'));
// This is my loop. I'm using .reduce, but for/while/.forEach/etc
// would all have worked.
// I'm going to loop over the images and push image/banner into
// a new container
const container = images.reduce(function (el, image) {
// get the first "banner" div
const banner = banners.shift();
// append the image div, first
el.appendChild(image);
// if a banner exists, append that
if (banner) {
el.appendChild(banner);
}
// as this is a reducer, i return my accumulator of divs
return el;
}, document.createElement('div'));
// As image/banner could differ in length, push any additional
// banner divs to the container
if (banners.length > 0) {
banners.forEach(banner => container.appendChild(banner));
}
// Add the new class name
container.classList.add('main2');
// Finally, append to body
document.querySelector('.body').appendChild(container);
}
// My event handler to run
document.querySelector('#rearrange').addEventListener('click', rearrange);
.content { display: flex }
.main, .side { flex-grow: 1 }
.content,
.main2 {
font-family: sans-serif;
line-height: 2;
color: white;
}
.img { background-color: red; margin: 3px;}
.banner { background-color: blue; margin: 3px;}
<div class="body">
<button id="rearrange">Click here to re-arrange</button>
<h2>Rearrange content - Place each div (banner) under each image </h2>
<div class="content">
<div class="main">
<div class="img">Image 1</div>
<div class="img">Image 2</div>
<div class="img">Image 3</div>
<div class="img">Image 4</div>
<div class="img">Image 5</div>
<div class="img">Image 6</div>
</div>
<div class="side">
<div class="banner">Banner1</div>
<div class="banner">Banner2</div>
<div class="banner">Banner3</div>
<div class="banner">Banner4</div>
<div class="banner">Banner5</div>
<div class="banner">Banner6</div>
<div class="banner">Banner7</div>
<div class="banner">Banner8</div>
<div class="banner">Banner9</div>
<div class="banner">Banner10</div>
</div>
</div>
<h2>Rearranged:</h2>
<hr />
</div>
I have a bunch of inline-block divs on my web page,
<div class="container">
<div class="text">Text 1</div>
<div class="text">Text 2</div>
<div class="text">Text 3</div>
<div class="text">Text 4</div>
<div class="text">Text 5</div>
<div class="text">Text 6</div>
<div class="text">Text 7</div>
</div>
and they wrap around like this:
I want to be able to delete the first row of them, that is in this case 1-5. But if I scale this to where only 1-3 are in the first row, I would only like to delete those. (you get it)
I don't have any clue what kind of javascript can be applied for this particular use case, but for simplicity, heres the JSFiddle. I would rather not use JQuery.
If the width of each item is the same, you can get the width of container, divide by the width of each item (to determine the number of items in each row), then delete that many items from the start.
const item = document.querySelector('.text');
const itemWidth = item.offsetWidth + 2 * parseFloat(window.getComputedStyle(item).getPropertyValue("margin"));
const containerWidth = document.querySelector('.container').offsetWidth;
const itemsInFirstRow = Math.floor(containerWidth / itemWidth);
document.querySelectorAll('.text').forEach((e,i) => {
if(i < itemsInFirstRow) e.remove()
})
.text {
height: 50px;
width: 50px;
background-color: red;
display: inline-block;
margin: 5px;
color: white;
text-align: center;
}
.container{
width:200px;
}
<div class="container">
<div class="text">Text 1</div>
<div class="text">Text 2</div>
<div class="text">Text 3</div>
<div class="text">Text 4</div>
<div class="text">Text 5</div>
<div class="text">Text 6</div>
<div class="text">Text 7</div>
</div>
I have this fiddle that I'm working on, and I can't figure out how to show (toggle) the content inside the black block I made + in the same time toggle "+" and "-" signs for the CLICKED div..
Structure example:
$('.column_column > div > div').hide();
$('.column_column h4').click(function(e){
e.preventDefault();
// hide all span
var $this = $(this).parent().find('div');
$(".column_column > div > div").not($this).hide();
// here is what I want to do
$this.toggle();
});
.sp_appear {
background: black;
color: #FFF;
display: block;
float: left;
width: 100%;
min-height: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="column_column">
<div class="column_attr">
<h4 href="">element1
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 1</div>
</div>
</div>
<div class="column_column">
<div class="column_attr">
<h4 href="">element2
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 2</div>
</div>
</div>
<div class="column_column">
<div class="column_attr">
<h4 href="">element3
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 3</div>
</div>
</div>
<div class="column_column">
<div class="column_attr">
<h4 href="">element4
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 4</div>
</div>
</div>
<div class="sp_appear"></div>
Can someone please help? Attaching the code - https://jsfiddle.net/kp9d0vfb/
Is this what you want?
$('.column_column > div > div').hide();
$('.column_column h4').click(function(e){
e.preventDefault();
// hide all span
var $this = $(this).parent().find('div');
$(".column_column > div > div").not($this).hide();
// here is what I want to do
$this.toggle();
$(this).find("span").text(($(this).find("span").text() == "-") ? "+" : "-");
});
.sp_appear {
background: black;
color: #FFF;
display: block;
float: left;
width: 100%;
min-height: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="column_column">
<div class="column_attr">
<h4 href="">element1
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 1</div>
</div>
</div>
<div class="column_column">
<div class="column_attr">
<h4 href="">element2
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 2</div>
</div>
</div>
<div class="column_column">
<div class="column_attr">
<h4 href="">element3
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 3</div>
</div>
</div>
<div class="column_column">
<div class="column_attr">
<h4 href="">element4
<span class="sp_toggle_icon">+</span>
</h4>
<div>content 4</div>
</div>
</div>
<div class="sp_appear"></div>
Can you pls take a look at this demo and let me know how I can remove .d-none class from element which located between two given numbers? Foe example I just want to show .box which are between 1 to 6 and hide all other boxes
$("button").on("click", function(e) {
var id = $(this).attr('id');
if (id == 1) {
$('.box').addClass('d-none');
// Now only display boxes from 1 to 6
}
if (id == 2) {
$('.box').addClass('d-none');
// Now only display boxes from 10 to 26
}
if (id == 3) {
$('.box').addClass('d-none');
// Now only display boxes from 12 to 36
}
});
.box {
background: gold;
height: 60px;
width: 60px;
color: black;
text-align: center;
line-height: 50px;
float: left;
margin: 2px;
}
.d-none {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="1">1 - 6</button>
<button id="2">10 - 26</button>
<button id="3">12 - 36</button>
<br />
<div class="box">0</div>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
<div class="box">17</div>
<div class="box">18</div>
<div class="box">19</div>
<div class="box">20</div>
<div class="box">21</div>
<div class="box">22</div>
<div class="box">23</div>
<div class="box">24</div>
<div class="box">25</div>
<div class="box">26</div>
<div class="box">27</div>
<div class="box">28</div>
<div class="box">29</div>
<div class="box">30</div>
<div class="box">31</div>
<div class="box">32</div>
<div class="box">33</div>
<div class="box">34</div>
<div class="box">35</div>
<div class="box">36</div>
<div class="box">37</div>
<div class="box">38</div>
<div class="box">39</div>
<div class="box">40</div>
You can do it easily using jquery slice() method. The slice() method helps us to reduce the set of matched elements to a subset specified by a range of indices, which is exactly we need here.
$("button").on("click", function(e) {
var id = $(this).attr('id');
$('.box').addClass('d-none');
if (id == 1) {
$('.box').slice(1,7).removeClass('d-none');
// Now only display boxes from 1 to 6
}
if (id == 2) {
$('.box').slice(10,27).removeClass('d-none');
// Now only display boxes from 10 to 26
}
if (id == 3) {
$('.box').slice(12,37).removeClass('d-none');
// Now only display boxes from 12 to 36
}
});
.box {
background: gold;
height: 60px;
width: 60px;
color: black;
text-align: center;
line-height: 50px;
float: left;
margin: 2px;
}
.d-none {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="1">1 - 6</button>
<button id="2">10 - 26</button>
<button id="3">12 - 36</button>
<br />
<div class="box">0</div>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
<div class="box">17</div>
<div class="box">18</div>
<div class="box">19</div>
<div class="box">20</div>
<div class="box">21</div>
<div class="box">22</div>
<div class="box">23</div>
<div class="box">24</div>
<div class="box">25</div>
<div class="box">26</div>
<div class="box">27</div>
<div class="box">28</div>
<div class="box">29</div>
<div class="box">30</div>
<div class="box">31</div>
<div class="box">32</div>
<div class="box">33</div>
<div class="box">34</div>
<div class="box">35</div>
<div class="box">36</div>
<div class="box">37</div>
<div class="box">38</div>
<div class="box">39</div>
<div class="box">40</div>
An additional solution if you have to check for the <div> content:
$("button").on("click", function(e) {
var id = parseInt($(this).attr('id')); // get button id to decide
// if you need to determine the range directly from the button content
// you should here extract the start and end value and use it
// afterwards for the if. In this case you can omit fixed ranges and
// the switch statement.
// var start = parseInt($(this).html().split(" - ")[0]);
// var end = parseInt($(this).html().split(" - ")[1]);
$('.box').addClass('d-none'); // hide all divs
var func = function() {
var val = parseInt($(this).html()); // get div content value
// use the button start and end values instead of the switch below
// if(val >= start && val <= end) {
// $(this).removeClass('d-none');
// }
switch(id) {
case 1:
if(val >= 1 && val <= 6) { // show only ids for button 1
$(this).removeClass('d-none');
}
break;
case 2:
if(val >= 10 && val <= 26) { // show only ids for button 2
$(this).removeClass('d-none');
}
break;
case 3:
if(val >= 12 && val <= 36) { // show only ids for button 3
$(this).removeClass('d-none');
}
break;
}
};
$('.box').each(func);
});
.box {
background: gold;
height: 60px;
width: 60px;
color: black;
text-align: center;
line-height: 50px;
float: left;
margin: 2px;
}
.d-none {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="1">1 - 6</button>
<button id="2">10 - 26</button>
<button id="3">12 - 36</button>
<br />
<div class="box">0</div>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
<div class="box">17</div>
<div class="box">18</div>
<div class="box">19</div>
<div class="box">20</div>
<div class="box">21</div>
<div class="box">22</div>
<div class="box">23</div>
<div class="box">24</div>
<div class="box">25</div>
<div class="box">26</div>
<div class="box">27</div>
<div class="box">28</div>
<div class="box">29</div>
<div class="box">30</div>
<div class="box">31</div>
<div class="box">32</div>
<div class="box">33</div>
<div class="box">34</div>
<div class="box">35</div>
<div class="box">36</div>
<div class="box">37</div>
<div class="box">38</div>
<div class="box">39</div>
<div class="box">40</div>
Explanation in the code!
In plain es20xx
{
// helper to determine if number is between min and max
const between = (number, min, max) => number >= min && number <= max;
document.addEventListener("click", showSelection);
function showSelection(evt) {
// act only if clicked element contains [data-between] ('event delegation')
if (evt.target.dataset.between) {
// determine min and max based on [data-between]
const minMax = evt.target.dataset.between.split(",").map(Number);
[...document.querySelectorAll(".box")]
.forEach(box => {
// determine what to do with box.classList based on
// number between min and max
const addOrRemove = between(+box.textContent, minMax[0], minMax[1]) ?
"remove" : "add";
// do it
box.classList[addOrRemove]("d-none");
});
}
}
}
.box {
background: gold;
height: 60px;
width: 60px;
color: black;
text-align: center;
line-height: 50px;
float: left;
margin: 2px;
}
.d-none {
display: none;
}
<button data-between="1,6">1 - 6</button>
<button data-between="10,26">10 - 26</button>
<button data-between="12,36">12 - 36</button>
<button data-between="0,40">all</button>
<br>
<div class="box">0</div>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
<div class="box">17</div>
<div class="box">18</div>
<div class="box">19</div>
<div class="box">20</div>
<div class="box">21</div>
<div class="box">22</div>
<div class="box">23</div>
<div class="box">24</div>
<div class="box">25</div>
<div class="box">26</div>
<div class="box">27</div>
<div class="box">28</div>
<div class="box">29</div>
<div class="box">30</div>
<div class="box">31</div>
<div class="box">32</div>
<div class="box">33</div>
<div class="box">34</div>
<div class="box">35</div>
<div class="box">36</div>
<div class="box">37</div>
<div class="box">38</div>
<div class="box">39</div>
<div class="box">40</div>
Use .removeClass() on the elements along with slice().
Call your selector, then slice the elements index adding the elements you wish to show and then removeClass('d-none').
Also, get the values of your elements attr('id'), slice that info and grab the actual values set in the buttons. Adjust key value starting at 0 with -1 and it is more dynamic.
$("button").on("click", function(e) {
var id = $(this).attr('id');
var opt1 = $('#1').text().split(' - ');
var opt2 = $('#2').text().split(' - ');
var opt3 = $('#3').text().split(' - ');
if (id == 1) {
$('.box').addClass('d-none');
$('.box').slice(opt1[0]-1,opt1[1]).removeClass('d-none');
}
if (id == 2) {
$('.box').addClass('d-none');
$('.box').slice(opt2[0]-1,opt2[1]).removeClass('d-none');
}
if (id == 3) {
$('.box').addClass('d-none');
$('.box').slice(opt3[0]-1,opt3[1]).removeClass('d-none');
}
if (id == 4) {
$('.box').removeClass('d-none');
}
});
.box {
background: gold;
height: 60px;
width: 60px;
color: black;
text-align: center;
line-height: 50px;
float: left;
margin: 2px;
}
.d-none {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="1">1 - 6</button>
<button id="2">10 - 26</button>
<button id="3">12 - 36</button>
<button id="4">Show All</button>
<br />
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
<div class="box">17</div>
<div class="box">18</div>
<div class="box">19</div>
<div class="box">20</div>
<div class="box">21</div>
<div class="box">22</div>
<div class="box">23</div>
<div class="box">24</div>
<div class="box">25</div>
<div class="box">26</div>
<div class="box">27</div>
<div class="box">28</div>
<div class="box">29</div>
<div class="box">30</div>
<div class="box">31</div>
<div class="box">32</div>
<div class="box">33</div>
<div class="box">34</div>
<div class="box">35</div>
<div class="box">36</div>
<div class="box">37</div>
<div class="box">38</div>
<div class="box">39</div>
<div class="box">40</div>
I've got a list of elements and I want to group them with div starting with the first element and ends with BREAK class then start a new group after the class BREAK.
So the code below,
<div class="test">Test 0</div>
<div class="test">Test 1</div>
<div class="break">Break 0</div>
<div class="test">Test 2</div>
<div class="test">Test 3</div>
<div class="break">Break 1</div>
<div class="test">Test 4</div>
<div class="test">Test 5</div>
<div class="test">Test 6</div>
Would become,
<div>
<div class="group">
<div class="test">Test 0</div>
<div class="test">Test 1</div>
<div class="break">Break 0</div>
</div>
<div class="group">
<div class="test">Test 2</div>
<div class="test">Test 3</div>
<div class="break">Break 1</div>
</div>
<div class="group">
<div class="test">Test 4</div>
<div class="test">Test 5</div>
<div class="test">Test 6</div>
<div class="break">Add last break element</div>
</div>
<div>
And append a div element in the last group.
Any ideas? Thanks in advance.
I'd probably go with simple: Loop through them with a container you add to, add a new container every time you see break:
var div;
$("selector for the divs").each(function() {
if (!div) {
div = $("<div>").insertBefore(this);
}
div.append(this);
if ($(this).hasClass("break")) {
div = undefined;
}
});
if (div) {
$("<div>last break</div>").addClass("break").appendTo(div);
}
Example (I added a wrapper class so we could see the effect when adding):
$("#go").click(function() {
var div;
$("#container > div").each(function() {
if (!div) {
div = $("<div>").addClass("wrapper").insertBefore(this);
}
div.append(this);
if ($(this).hasClass("break")) {
div = undefined;
}
});
if (div) {
$("<div>last break</div>").addClass("break").appendTo(div);
}
});
.test {
color: blue;
}
.break {
color: red;
}
.wrapper {
border: 1px solid #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="go" value="Go">
<div id="container">
<div class="test">Test 0</div>
<div class="test">Test 1</div>
<div class="break">Break 0</div>
<div class="test">Test 2</div>
<div class="test">Test 3</div>
<div class="break">Break 1</div>
<div class="test">Test 4</div>
<div class="test">Test 5</div>
<div class="test">Test 6</div>
</div>
I think you can also do something like this: first you insert one more .break to all .test parent container, then using wrapAll method wrap groups properly:
$('.test').parent().append('<div class="break">Break 2</div>').
find('.test + .break').each(function() {
$(this).prevUntil('.break, .group').add(this).wrapAll('<div class="group"></div>');
});
.group {
padding: 3px;
background: #BFECBE;
margin-bottom: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="test">Test 0</div>
<div class="test">Test 1</div>
<div class="break">Break 0</div>
<div class="test">Test 2</div>
<div class="test">Test 3</div>
<div class="break">Break 1</div>
<div class="test">Test 4</div>
<div class="test">Test 5</div>
<div class="test">Test 6</div>
</div>
this code is working fine,you can check the fiddle and demo here as well
$("div.test").each(function() {
if (!$(this).nextAll(".break").length)
$(".test").last().after('<div class="break">Add last break element</div>');
if (!$(this).parents(".group").length)
$(this).add($(this).nextUntil('.break+.test').andSelf()).wrapAll('<div class="group" />');
});
.group {
background: red;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Test 0</div>
<div class="test">Test 1</div>
<div class="break">Break 0</div>
<div class="test">Test 2</div>
<div class="test">Test 3</div>
<div class="break">Break 1</div>
<div class="test">Test 4</div>
<div class="test">Test 5</div>
<div class="test">Test 6</div>
});
Fiddle Demo