Hide and Show Elements Based on Date Change from DatePicker - javascript

The following solution works, but I would like to keep adding elements for the entire month.
When I remove the dates that are ="none" the previous dates start stacking on top of each other.
Is there a way to simplify the javascript so I wouldn't have to keep adding each date to the if-else statements to hide and show them?
function selectDate() {
var x = document.getElementById("start").value;
if (x == "2022-03-21") {
document.getElementById("2022-03-21").style.display = "flex";
document.getElementById("2022-03-22").style.display = "none";
document.getElementById("2022-03-23").style.display = "none";
}
else if (x == "2022-03-22") {
document.getElementById("2022-03-22").style.display = "flex";
document.getElementById("2022-03-21").style.display = "none";
document.getElementById("2022-03-23").style.display = "none";
}
else if (x == "2022-03-23") {
document.getElementById("2022-03-23").style.display = "flex";
document.getElementById("2022-03-21").style.display = "none";
document.getElementById("2022-03-22").style.display = "none";
}
}
<section>
<div class="container ">
<div class="row">
<div class="col">
<input type="date" id="start" onchange="selectDate()">
</div>
</div>
<div class="row" id="2022-03-21" style="display: none;">
<div class="col">
<div class="row">
<div class="col">
<h4>1</h4>
</div>
<div class="col">
<h4>2</h4>
</div>
</div>
</div>
</div>
<div class="row" id="2022-03-22" style="display: none;">
<div class="col">
<div class="row">
<div class="col">
<h4>3</h4>
</div>
<div class="col">
<h4>4</h4>
</div>
</div>
</div>
</div>
<div class="row" id="2022-03-23" style="display: none;">
<div class="col">
<div class="row">
<div class="col">
<h4>5</h4>
</div>
<div class="col">
<h4>6</h4>
</div>
</div>
</div>
</div>
</div>
</section>

I'm not sure what you mean by
When I remove the dates that are ="none" the previous dates start stacking on top of each other.
I don't see that happening in your snippet.
That said, you can simplify the code that hides/shows the div, and not have to hard code in the dates.
Give each element that you are wanting to show/hide a common class name, for example output
Select them all in a NodeList collection using document.querySelectorAll('.output')
Then with the .forEach() on that collection, you can loop through each one and change the display to none.
Then find the element that matches the date selected
If it is not null, then you can change the display to 'flex'
Personally I prefer to use document.querySelector() or document.querySelectorAll() method when selecting elements.
However, you'll notice that in step 4 above, I didn't. Since the ID begins with a number, it is better to use document.getElementById() rather than document.querySelector(). You can still do it, but it requires some string manipulation. See this post here: Using querySelector with IDs that are numbers
document.querySelector(`#start`).addEventListener(`change`, function(e) {
// Get every element with the 'output' class &
// loop through each one & change the display to 'none'
document.querySelectorAll(`.output`).forEach(el => el.style.display = `none`);
// get the element that matches the value of the date selected
const dispElm = document.getElementById(this.value);
// if the element exists, then change the display to 'flex'
if (dispElm) {
dispElm.style.display = `flex`;
}
});
<section>
<div class="container">
<div class="row">
<div class="col">
<input type="date" id="start">
</div>
</div>
<div class="row output" id="2022-03-21" style="display: none;">
<div class="col">
<div class="row">
<div class="col">
<h4>1</h4>
</div>
<div class="col">
<h4>2</h4>
</div>
</div>
</div>
</div>
<div class="row output" id="2022-03-22" style="display: none;">
<div class="col">
<div class="row">
<div class="col">
<h4>3</h4>
</div>
<div class="col">
<h4>4</h4>
</div>
</div>
</div>
</div>
<div class="row output" id="2022-03-23" style="display: none;">
<div class="col">
<div class="row">
<div class="col">
<h4>5</h4>
</div>
<div class="col">
<h4>6</h4>
</div>
</div>
</div>
</div>
</div>
</section>

Related

Filter div Content by data-attribute with Checkbox using JQuery

I have a list of cards inside a div with class name .cards-list
and I want to to filter those cards by data-attribute using checkbox
I tried the following jQuery code but it is not working, after checking checkbox all my cards are hidden and not showing again when I uncheck it
HTML
<!-- FILTER CHECKBOX -->
<div class="form-check">
<input class="cardCheckBox" type="checkbox" value="foo">
</div>
<div class="form-check">
<input class="cardCheckBox" type="checkbox" value="xyz">
</div>
<!-- CARDS LIST I WANT TO FILTER -->
<div class="cards-list mt-2">
<div class="card" data-category="foo">
<div class="card-body">
<h2>card title</h2>
</div>
</div>
<div class="card" data-category="xyz">
<div class="card-body">
<h2>card title</h2>
</div>
</div>
<div class="card" data-category="foo">
<div class="card-body">
<h2>card title</h2>
</div>
</div>
</div>
jQuery
$(".cardCheckBox").change(function () {
var value = $(this).val();
if (this.checked) {
$(".cards-list.card").filter(function () {
$(this).toggle($(this).data("category") == value);
});
} else {
$(this).toggle($(this).data("category") == value);
}
});
Explanation in code:
// Cache your elements
const $cards = $("[data-category]");
const $cardsCkb = $(".cardCheckBox");
$cardsCkb.on("change", function() {
// Create an Array of checked values
const checkedArr = $cardsCkb.filter(":checked").get().map(el => el.value);
// Show all and exit if no filter is active
if (!checkedArr.length) return $cards.removeClass("is-hidden");
// Finally, use jQuery's .toggleClass() and JS's Array.prototype.includes()
$cards.each(function() {
const category = $(this).data("category");
$(this).toggleClass("is-hidden", !checkedArr.includes(category));
});
});
.card.is-hidden {
display: none;
}
<!-- FILTER CHECKBOX -->
<div class="form-check">
<label><input class="cardCheckBox" type="checkbox" value="foo"> foo</label>
</div>
<div class="form-check">
<label><input class="cardCheckBox" type="checkbox" value="xyz"> xyz</label>
</div>
<!-- CARDS LIST I WANT TO FILTER -->
<div class="cards-list mt-2">
<div class="card" data-category="foo">
<div class="card-body">
<h2>foo 1</h2>
</div>
</div>
<div class="card" data-category="xyz">
<div class="card-body">
<h2>xyz 1</h2>
</div>
</div>
<div class="card" data-category="foo">
<div class="card-body">
<h2>foo 2</h2>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
You made couple of mistakes.
You need this.checked == true in your if statement. this.checked gives you true and false, you need to specify what are you looking for.
Also no need for filter, you can do filtering in your element selector (witch was also not targeting right):
$(".cards-list .card[data-category="+value+"]")
if you put .cards-list.card together it means they are next to each other, in your case .card is inside .cards-list.
$(".cardCheckBox").change(function () {
var value = $(this).val();
//console.log(value);
if (this.checked == true) {
//console.log(true);
$(".cards-list .card[data-category="+value+"]").hide();
}else{
$(".cards-list .card[data-category="+value+"]").show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- FILTER CHECKBOX -->
<div class="form-check">
<input class="cardCheckBox" type="checkbox" value="foo">
</div>
<div class="form-check">
<input class="cardCheckBox" type="checkbox" value="xyz">
</div>
<!-- CARDS LIST I WANT TO FILTER -->
<div class="cards-list mt-2">
<div class="card" data-category="foo">
<div class="card-body">
<h2>card title foo</h2>
</div>
</div>
<div class="card" data-category="xyz">
<div class="card-body">
<h2>card title xyz</h2>
</div>
</div>
<div class="card" data-category="foo">
<div class="card-body">
<h2>card title foo</h2>
</div>
</div>
</div>

Get a specific text value of an element when there is multiple elements with the same class names and attribute names

<div class="my-attributes">
<div class="row">
<div class="SameClass"><strong>Condition</strong></div>
<div class="SameClass-value" itemprop="condition">New</div>
</div>
<div class="row">
<div class="SameClass"><strong>Color</strong></div>
<div class="SameClass-value" itemprop="color">Black</div>
</div>
<div class="row">
<div class="SameClass"><strong>Availability</strong></div>
<div class="SameClass-value" itemprop="avail">In Stock</div>
</div>
<div class="row">
<div class="SameClass"><strong>Quantity</strong></div>
**<div class="SameClass-value" itemprop="qty"> 5 </div>**
</div>
<div class="row">
<div class="SameClass"><strong>Price</strong></div>
<div class="SameClass-value" itemprop="price">250</div>
</div>
I have multiple divs that has the same class and 'itemprop' attribute and I need to be able to create a function that will return the Quantity (which in the example above is '5')
the catch here is that the structure you see above changes in other pages. In the example above, the Condition and the Color shows but on other pages those do not appear which means the structure changes except the class name and the attribute value of the 'itemprop'. See below:
<div class="my-attributes">
<div class="row">
<div class="SameClass"><strong>Availability</strong></div>
<div class="SameClass-value" itemprop="avail">In Stock</div>
</div>
<div class="row">
<div class="SameClass"><strong>Quantity</strong></div>
**<div class="SameClass-value" itemprop="qty"> 5 </div>**
</div>
<div class="row">
<div class="SameClass"><strong>Price</strong></div>
<div class="SameClass-value" itemprop="price">250</div>
</div>
How do I get the Quantity into a JavaScript function and return the value of 5? Without having to edit the code of the site itself?
I have been playing with this but I am sure this is completely and utterly incorrect.
function () {
var x = document.getElementsByClassName("SameClass").getAttribute("itemprop");
if (x = 'price')
{
var a = document.getElementsByClassName("SameClass").getAttribute("itemprop").innerText;
return a;
}
}
The following might work for you:
function getQty() {
var arr=document.getElementsByClassName("SameClass-value");
for(var i=0;i<arr.length;i++)
if (arr[i].getAttribute("itemprop") == 'qty') return arr[i].innerHTML;
}
Or, even shorter, you can do
function getQty() {
return document.getElementsByClassName("SameClass-value")
.find(d=>d.getAttribute("itemprop") == 'qty').innerHTML;
}
Sorry for the repeated edits. It's been a long day for me today and I was trying to quickly put something together on my little smartphone.
If the classes don't change, you can select all the relevant elements then get the value from the one you need.
function getQty() {
var qty;
document.querySelectorAll("div.SameClass-value").forEach(function(element) {
if (element.getAttribute("itemprop") === "qty") {
qty = element.innerText;
}
});
return qty;
}
console.log(getQty());
<div class="my-attributes">
<div class="row">
<div class="SameClass"><strong>Condition</strong></div>
<div class="SameClass-value" itemprop="condition">New</div>
</div>
<div class="row">
<div class="SameClass"><strong>Color</strong></div>
<div class="SameClass-value" itemprop="color">Black</div>
</div>
<div class="row">
<div class="SameClass"><strong>Availability</strong></div>
<div class="SameClass-value" itemprop="avail">In Stock</div>
</div>
<div class="row">
<div class="SameClass"><strong>Quantity</strong></div>
<div class="SameClass-value" itemprop="qty"> 5 </div>
</div>
<div class="row">
<div class="SameClass"><strong>Price</strong></div>
<div class="SameClass-value" itemprop="price">250</div>
</div>
</div>

finding index of element sitewide

I have been trying to find out how to do a sitewide search for an elements index of a certain class. Doesn't have to sitewide, but i has to be usuable for an ancestor div.
My markup is the following:
<div class="custom-woo-gallery">
<div class="row">
<div class="gallery-item"></div>
<div class="gallery-item"></div>
<div class="gallery-item"></div>
</div>
<div class="row">
<div class="gallery-item"></div>
<div class="gallery-item"></div>
<div class="gallery-item"></div>
</div>
<div class="row">
<div class="gallery-item"></div>
<div class="gallery-item"></div>
<div class="gallery-item"></div>
</div>
<div class="row">
<div class="gallery-item"></div>
<div class="gallery-item"></div>
<div class="gallery-item"></div>
</div>
<div class="row">
<div class="gallery-item"></div>
<div class="gallery-item"></div>
<div class="gallery-item"></div>
</div>
</div>
Basically a .gallery-item element is clicked and i need to find out how many .gallery-item elements preceeds it in the common ancestor .custom-woo-gallery.
I have the following code, which is functional. But I'm guessing theres more simple way to do this. I just can't seem to find anything on google other than index() and eq() which only seems to work inside the same parent div.
function getPrev(){
var count = 0;
$(clicked).parent().prevUntil().each(function(){
count = count + $(this).children().length;
})
var self = $(clicked).prevUntil().length;
return count + self;
}
Try this solution. If you have only one custom-woo-gallery, you can get the index of the current clicked gallery-item's index via jQuery#index. And you can find how many how many .gallery-item elements precedes it.
Actually the index of the clicked div is the number of his previous .gallery-items.
const galleryItems = $('.gallery-item');
$('.gallery-item').on('click', function(){
console.log(galleryItems.index($(this)));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="custom-woo-gallery">
<div class="row">
<div class="gallery-item">1</div>
<div class="gallery-item">2</div>
<div class="gallery-item">3</div>
</div>
<div class="row">
<div class="gallery-item">4</div>
<div class="gallery-item">5</div>
<div class="gallery-item">6</div>
</div>
<div class="row">
<div class="gallery-item">7</div>
<div class="gallery-item">8</div>
<div class="gallery-item">9</div>
</div>
<div class="row">
<div class="gallery-item">10</div>
<div class="gallery-item">11</div>
<div class="gallery-item">12</div>
</div>
<div class="row">
<div class="gallery-item">13</div>
<div class="gallery-item">14</div>
<div class="gallery-item">15</div>
</div>
</div>

Dom Navigation using Javascript

How can i access 3rd Element(H2) starting with the parent element "id="services-list".
Iam currently accessing using the below method.Is there a better way to do apart from the below. Please see i need purely Javascript.
var z = document.querySelectorAll('section[id="services-list"]');
z[0].firstElementChild.firstElementChild.firstElementChild.textContent
<section id="services-list" class="section container ">
<div class="row">
<div class="col-12 col-md-10 col-lg-6 offset-md-1">
<h2 class="section__title">Services</h2>
</div>
</div>
</section>
Regards,
Sree
let el = document.getElementById("services-list").getElementsByTagName("h2")[0];
console.log(el);
or with getElementsByClassName (but EI8- doesn't support getElementsByClassName)
let el = document.getElementById("services-list").getElementsByClassName("section__title")[0];
console.log(el);
getElementById("") to get the section.
Starting from this DOM element you can now call getElementsByClassName("") to find the h2 element
const elem = document.getElementById("services-list").getElementsByClassName("section__title")[0];
console.log(elem);
<section id="services-list" class="section container ">
<div class="row">
<div class="col-12 col-md-10 col-lg-6 offset-md-1">
<h2 class="section__title">Services</h2>
</div>
</div>
</section>
You can use complicated selectors to achieve your goal
var z = document.querySelectorAll('section[id="services-list"] .section__title');
console.log (z[0].textContent)
<section id="services-list" class="section container ">
<div class="row">
<div class="col-12 col-md-10 col-lg-6 offset-md-1">
<h2 class="section__title">Services</h2>
</div>
</div>
</section>
If you want to learn how to select elements in a shorter way:
var z = window['services-list'] // you id is unique, so we can use shorter way to select it
.querySelector('h2'); // you have only one h2 inside, so we also can do is shorter
console.log (z.textContent)
<section id="services-list" class="section container ">
<div class="row">
<div class="col-12 col-md-10 col-lg-6 offset-md-1">
<h2 class="section__title">Services</h2>
</div>
</div>
</section>

Hidding/showing divs with javascript with timer

This site has saved me a milion times, but now i am trying to make something similar to the header section of this site, and can't quite get it to work. I would like someone to help me with the following:
Here is my example code :
<div class="container">
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div id="first" class="cube color1"></div>
<div id="second" class="cube color3" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color2"></div>
<div id="second" class="cube color1" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color3"></div>
<div id="second" class="cube color2" style="display: none;"></div>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div id="first" class="cube color3"></div>
<div id="second" class="cube color2" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color2"></div>
<div id="second" class="cube color1" style="display: none;"></div>
</div>
<div class="col-md-4">
<div id="first" class="cube color1"></div>
<div id="second" class="cube color3" style="display: none;"></div>
</div>
</div>
</div>
The javascript :
<script>
setInterval(hide, 2000);
function switchDivs()
{
var first = document.getElementById("first");
var second = document.getElementById("second");
}
function hide() {
document.getElementById("first").style.display="none";
document.getElementById("second").style.display="block";
}
function show() {
document.getElementById("first").style.display="block";
document.getElementById("second").style.display="none";
}
</script>
link to jsfiddle
I dont understand first why it doesnt change all the "first" divs into "second", it changes only the first div. Than the next question is how to make that action repeat over time, preferably more like random timer for each one of the 6 positions/boxes.
Shortly: I need divs with id="first" to be swapped with divs with id="second" , after like 5-10 seconds delay after loading the page. Than after the same delay, i need them to switch back to showing only divs with id="first" and so on... (something like setInterval function).
setInterval(function() { $(".color-blocks .col-md-4").each(function() { $(this).children().toggle(); }); }, 2000);
a simple line of code could be helpful, and in a simpler way.
working fiddle : https://jsfiddle.net/65k788u6/3/
while you use ids, those should be unique, so instead use toggle() in order to make it look simpler.
sorry, I don't have 50 rep to leave a comment. Is the problem is that you have multiple elements with the same ID? getElementById() seems to be returning the first instance that's true and not further with the same ID. I would recommend using getelementsbyclassname() and using classes instead of ID's to describe groups of elements. Updated the fiddle to show it done this way. version 4.
Your HTML is invalid. The ID attribute on any element should always be unique within the context of the entire page.
Instead of .getElementById, which selects only one item (and only by its ID attribute) you can use .querySelectorAll to get all elements that match a given CSS query selector (or .querySelector to get a single element).
I recommend using setTimeout instead of setInterval as a general best practice.
var rows = document.querySelectorAll(".col-md-4");
var indices = getIndices(rows);
setTimeout(flipRows, 5000);
function getIndices() {
var arr = [];
for (var i = 0, len = rows.length; i < len; i++) {
arr.push(i);
}
return arr;
}
function flipRows() {
if (indices.length == 0) {
indices = getIndices();
}
var index = Math.random() * indices.length >>> 0;
var randomRow = rows[indices[index]];
indices.splice(index, 1);
flipRow(randomRow);
setTimeout(flipRows, 5000); // run again in 5 seconds
}
function flipRow(row) {
var first = row.querySelector(".first");
var second = row.querySelector(".second");
if (first.style.display === "none") {
first.style.display = "block";
second.style.display = "none";
} else {
first.style.display = "none";
second.style.display = "block";
}
}
.color1 { background-color: pink;}
.color2 { background-color: lightblue;}
.color3 { background-color: lightgreen;}
<div class="container">
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div class="first cube color1">first</div>
<div class="second cube color3" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color2">first</div>
<div class="second cube color1" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color3">first</div>
<div class="second cube color2" style="display: none;">second</div>
</div>
</div>
<div class="row" style="padding-top: 50px;">
<div class="col-md-4">
<div class="first cube color3">first</div>
<div class="second cube color2" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color2">first</div>
<div class="second cube color1" style="display: none;">second</div>
</div>
<div class="col-md-4">
<div class="first cube color1">first</div>
<div class="second cube color3" style="display: none;">second</div>
</div>
</div>
</div>

Categories

Resources