Dependent dropdown filter - javascript

Repeating the question by following the tips of the people and the site. Sorry I didn't do it right last time.
My dilemma is as follows:
I have a custom filter with four categories, all have to be visible, but one is dependent on the other. When I select a "Categoria / Category" filter option, the next "Largura / Width" filter will receive the default values for that category, otherwise it will be blank. And so it will be, when selecting a "Largura" option, the "Perfil" filter will show the preset Largura selected options
I had managed to do with select but the customization has to be this and I am having difficulty and come to help, preferably with Javascript
If you want to see the complete project, here in codepen:
https://codepen.io/KaioRocha/pen/RwbRzWR
Snippet:
// Open Box Categoria
function abrirFiltroCategoria() {
var x = document.querySelector(".box__categoria");
if (x.style.display == 'none' || x.style.display == '') {
x.style.display = "flex";
} else {
x.style.display = "none";
}
}
// Open Box Largura
function abrirFiltroLargura() {
var x = document.querySelector(".box__largura");
if (x.style.display == 'none' || x.style.display == '') {
x.style.display = "flex";
} else {
x.style.display = "none";
}
}
// Open Box Perfil
function abrirFiltroPerfil() {
var x = document.querySelector(".box__perfil");
if (x.style.display == 'none' || x.style.display == '') {
x.style.display = "flex";
} else {
x.style.display = "none";
}
}
// Open Box Aro
function abrirFiltroAro() {
var x = document.querySelector(".box__aro");
if (x.style.display == 'none' || x.style.display == '') {
x.style.display = "flex";
} else {
x.style.display = "none";
}
}
// Get the option from categoria and show
function mostrarValueCategoria(el) {
document.querySelector('.valueCategoria').innerText = el.value;
}
// Get the option from categoria and show
function mostrarValueLargura(el) {
document.querySelector('.valueLargura').innerHTML = el.value;
}
// Get the option from categoria and show
function mostrarValuePerfil(el) {
document.querySelector('.valuePerfil').innerHTML = el.value;
}
// Get the option from categoria and show
function mostrarValueAro(el) {
document.querySelector('.valueAro').innerHTML = el.value;
}
<div class="container-fluid p-0">
<div class="filters">
<div class="container" style="display: flex; justify-content: space-between">
<div class="ui-group">
<span>Categoria</span>
<div class="selecionar" onclick="abrirFiltroCategoria()">
<p class="valueCategoria">Selecionar categoria</p>
</div>
<div class="button-group js-radio-button-group box__categoria" data-filter-group="color">
<button id="categoria_carro" class="button" data-filter=".red" value="Passeio" onclick="mostrarValueCategoria(this)">Passeio
</button>
<button class="button" data-filter=".blue" value="SUV/Pickup/4x4" onclick="mostrarValueCategoria(this)">SUV/Pickup/4x4
</button>
<button class="button" data-filter=".yellow" value="Van e Utilitário" onclick="mostrarValueCategoria(this)">Van e Utilitário
</button>
<button class="button" data-filter=".yellow" value="Caminhão e Carga" onclick="mostrarValueCategoria(this)">Caminhão e Carga
</button>
</div>
</div>
<div class="ui-group">
<span>Largura</span>
<div class="selecionar" onclick="abrirFiltroLargura()">
<p class="valueLargura">Selecionar largura</p>
</div>
<div class="button-group js-radio-button-group box__largura" data-filter-group="size" id="largura_carro">
<button class="button is-checked" data-filter="" value="500" onclick="mostrarValueLargura(this)">
500
</button>
<button class="button" data-filter=".small" value="505" onclick="mostrarValueLargura(this)">505
</button>
<button class="button" data-filter=".wide" value="510" onclick="mostrarValueLargura(this)">510
</button>
<button class="button" data-filter=".big" value="515" onclick="mostrarValueLargura(this)">515
</button>
</div>
</div>
<div class="ui-group">
<span>PERFIL</span>
<div class="selecionar" onclick="abrirFiltroPerfil()">
<p class="valuePerfil">Selecionar perfil</p>
</div>
<div class="button-group js-radio-button-group box__perfil" data-filter-group="shape">
<button class="button is-checked" data-filter="" value="01" onclick="mostrarValuePerfil(this)">01
</button>
<button class="button" data-filter=".round" value="02" onclick="mostrarValuePerfil(this)">02
</button>
<button class="button" data-filter=".square" value="03" onclick="mostrarValuePerfil(this)">03
</button>
</div>
</div>
<div class="ui-group">
<span>ARO</span>
<div class="selecionar" onclick="abrirFiltroAro()">
<p class="valueAro">Selecionar aro</p>
</div>
<div class="button-group js-radio-button-group box__aro" data-filter-group="shape">
<button class="button is-checked" data-filter="" value="04" onclick="mostrarValueAro(this)">04
</button>
<button class="button" data-filter=".round" value="05" onclick="mostrarValueAro(this)">05</button>
<button class="button" data-filter=".square" value="06" onclick="mostrarValueAro(this)">06</button>
</div>
</div>
</div>
</div>

Related

How to optimize code that shows one block and hides others?

I have 3 blocks, when opening one, all should hide. I wrote the simplest code (I'm a beginner), I understand that it can and should be optimized. How can I do that?
I'm thinking of using "if else" construction, but not sure how to do it correctly.
function openLink(){
document.getElementsByClassName('open_link')[0].style.display = 'block';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
function openImages(){
document.getElementsByClassName('open_images')[0].style.display = 'block';
document.getElementsByClassName('open_link')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
function openVideo(){
document.getElementsByClassName('open_video')[0].style.display = 'block';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_link')[0].style.display = 'none';
}
function closeForm(){
document.getElementsByClassName('open_link')[0].style.display = 'none';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
<a onclick="openLink()" href='#'>One</a>
<a onclick="openVideo()" href='#'>Two</a>
<a onclick="openImages()" href='#'>Three</a>
<div class="open_link" style="display: none;">
<button onclick="closeForm()">Save 1</button>
<button onclick="closeForm()">Close 1</button>
</div>
<div class="open_video" style="display: none;">
<button onclick="closeForm()">Save 2</button>
<button onclick="closeForm()" >Close 2</button>
</div>
<form class="open_images" style="display: none;">
<input onclick="closeForm()" value="Upload 3"/>
<button onclick="closeForm()" >Close 3</button>
</form>
Delegate
Here is a start
const content = document.getElementById("content");
document.getElementById("nav").addEventListener("click", function(e) {
const tgt = e.target;
const id = tgt.dataset.id;
[...content.querySelectorAll("div")].forEach(div => {
if (div.id !== id) div.classList.add("hide");
})
document.getElementById(id).classList.remove("hide");
})
content.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("close")) {
tgt.closest("div").classList.add("hide")
}
})
.hide {
display: none;
}
<div id="nav">
<a data-id="link" href='#'>One</a>
<a data-id="video" href='#'>Two</a>
<a data-id="images" href='#'>Three</a>
</div>
<div id="content">
<div id="link" class="hide">
<button type="button" id="save1">Save 1</button>
<button type="button" class="close">Close 1</button>
</div>
<div id="video" class="hide">
<button type="button" id="save2">Save 2</button>
<button type="button" class="close">Close 2</button>
</div>
<div id="images" class="hide">
<form>
<input id="upload" value="Upload 3" />
<button type="button" class="close">Close 3</button>
</form>
</div>
</div>
You can sum up some of your redundant code into one function and pass parameters to it.
function openAndClose(classBlock, classNone, classNone1) {
document.getElementsByClassName(classBlock)[0].style.display = 'block';
document.getElementsByClassName(classNone)[0].style.display = 'none';
document.getElementsByClassName(classNone1)[0].style.display = 'none'
}
function closeForm(){
document.getElementsByClassName('open_link')[0].style.display = 'none';
document.getElementsByClassName('open_images')[0].style.display = 'none';
document.getElementsByClassName('open_video')[0].style.display = 'none';
}
<a onclick="openAndClose('open_link', 'open_images', 'open_video')" href='#'>One</a>
<a onclick="openAndClose('open_video', 'open_images', 'open_link')" href='#'>Two</a>
<a onclick="openAndClose('open_images', 'open_link', 'open_video')" href='#'>Three</a>
<div class="open_link" style="display: none;">
<button onclick="closeForm()">Save 1</button>
<button onclick="closeForm()">Close 1</button>
</div>
<div class="open_video" style="display: none;">
<button onclick="closeForm()">Save 2</button>
<button onclick="closeForm()" >Close 2</button>
</div>
<form class="open_images" style="display: none;">
<input onclick="closeForm()" value="Upload 3"/>
<button onclick="closeForm()" >Close 3</button>
</form>
Try this but with your own ids and classes
.open are the div to open
id of the target is id of your div, you did this with classes
document.querySelectorAll(".open").forEach(div => {
div.onclick = (e) => {
switch (e.target.id) {
case "open_link":
openLink()
break;
case "open_video":
openVideo()
break;
case "open_images":
openImages()
break;
}
}
})

How to change button caption when div tag is visible using Javascript

I have this Javascript and HTML
<div class="col-lg-12">
<button type="button" onclick="myFunction()" class="btn btn-block btn-success"><i class="fas fa-search"></i> View Result</button>
</div>
<div id="myDIV" style="display:none">
This is my DIV element.
</div>
<script type="text/javascript">
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
By default, myDiv div tag is hidden. Then when the button is clicked it becomes visible, when it's clicked again it hides the div.
But beyond this, what I want is that when the div tag is visible the button caption should be
Hide Result
and when the div tag is hidden, the button caption should be
View Result
How do I modify ny current code to achieve this?
Thanks
Just surround the button caption in a <span> tag with an id :
<div class="col-lg-12">
<button type="button" onclick="myFunction()" class="btn btn-block btn-success">
<i class="fas fa-search"></i>
<span id="button-caption">View Result</span>
</button>
</div>
And update the caption at the same time as you update the div visibility :
function myFunction() {
var x = document.getElementById("myDIV");
var y = document.getElementById("button-caption");
if (x.style.display === "none") {
y.innerHTML = "Hide Results";
x.style.display = "block";
} else {
y.innerHTML = "Show Results";
x.style.display = "none";
}
}
First of all, give your button an ID.
<button id="myButton" type="button" onclick="myFunction()" class="btn btn-block btn-success"><i class="fas fa-search"></i> View Result</button>
After that, in myFunction(), simply apply document.getElementById("myButton").innerHTML = "New caption here" wherever you want to change the caption.
You can change the textContent of the button when you show/hide the div
function myFunction() {
var x = document.getElementById("myDIV");
var y = document.getElementById("btn");
if (x.style.display === "none") {
x.style.display = "block";
y.textContent = "Hide Result";
} else {
x.style.display = "none";
y.textContent = "View Result";
}
}
<div class="col-lg-12">
<button id="btn" type="button" onclick="myFunction()" class="btn btn-block btn-success"><i class="fas fa-search"></i> View Result</button>
</div>
<div id="myDIV" style="display:none">
This is my DIV element.
</div>

how to toggle different divs with javascript

function toggleB(){
var b1 = document.getElementById("1");
var b2 = document.getElementById("2");
var b3 = document.getElementById("3");
if (b1.style.display === "none"){
b1.style.display = "none";
} else {
b1.style.display = "block";
}
if (b2.style.display === "none"){
b2.style.display = "none";
} else {
b2.style.display = "block";
}
if (b3.style.display === "none"){
b3.style.display = "none";
} else {
b3.style.display = "block";
}
}
<!DOCTYPE html>
<html>
<script src="script.js"></script>
<body>
<div id="imgBtns">
<div id="b1">
<input onclick="toggleB" type="image" src="/">
B1
</div>
<div id="b2">
<input onclick="toggleB" type="image" src="/">
B2
</div>
<div id="b3">
<input onclick="toggleB" type="image" src="/">
B3
</div>
</div>
<div class="main">
<div id="mainText">
<p>This should be displayed first without b1,b2,b3 showing</p>
</div>
<div id="button1">
<p>you clicked b1</p>
</div>
<div id="button2">
<p>you clicked b2</p>
</div>
<div id="button3">
<p>you clicked b3</p>
</div>
</div>
</body>
</html>
I want the javascript function to be able toggle between showing divs(b1,b2,b3) by clicking their image button or a tag. Once an img input button or a tag is clicked it should remove the "mainText" and only show the clicked div to the user. The mainText div should be removed and be replaced with the corresponding button div that is clicked.
function toggleB{
var b1 = document.getElementById("1");
var b2 = document.getElementById("2");
var b3 = document.getElementById("3");
if (b1.style.display === "none"){
b1.style.display = "none";
} else {
b1.style.display = "block";
}
if (b2.style.display === "none"){
b2.style.display = "none";
} else {
b2.style.display = "block";
}
if (b3.style.display === "none"){
b3.style.display = "none";
} else {
b3.style.display = "block";
}
}
<!DOCTYPE html>
<html>
<script src="script.js"></script>
<body>
<div id="imgBtns">
<div id="b1">
<input onclick="toggleB" type="image" src="/">
B1
</div>
<div id="b2">
<input onclick="toggleB" type="image" src="/">
B2
</div>
<div id="b3">
<input onclick="toggleB" type="image" src="/">
B3
</div>
</div>
<div class="main">
<div id="mainText">
<p>This should be displayed first without b1,b2,b3 showing</p>
</div>
<div id="1">
<p>you clicked b1</p>
</div>
<div id="2">
<p>you clicked b2</p>
</div>
<div id="3">
<p>you clicked b3</p>
</div>
</div>
</body>
</html>
function toggleB{
var b1 = document.getElementById("1");
var b2 = document.getElementById("2");
var b3 = document.getElementById("3");
if (b1.style.display === "none"){
b1.style.display = "none";
} else {
b1.style.display = "block";
}
if (b2.style.display === "none"){
b2.style.display = "none";
} else {
b2.style.display = "block";
}
if (b3.style.display === "none"){
b3.style.display = "none";
} else {
b3.style.display = "block";
}
}
<!DOCTYPE html>
<html>
<script src="script.js"></script>
<body>
<div id="imgBtns">
<div id="b1">
<input onclick="toggleB" type="image" src="/">
b1
</div>
<div id="b2">
<input onclick="toggleB" type="image" src="/">
b2
</div>
<div id="b3">
<input onclick="toggleB" type="image" src="/">
b3
</div>
</div>
<div class="main">
<div id="mainText">
<p>This should be displayed first without b1,b2,b3 showing</p>
</div>
<div id="1">
<p>b1</p>
</div>
<div id="2">
<p>b2</p>
</div>
<div id="3">
<p>b3</p>
</div>
</div>
</body>
</html>
You whole concept is far too complicated.
Instead, put the id of the div to toggle into a data-toggles-Attribute. Then dynamically select that div and toggle the hidden attribute.
A simplified example:
const buttons = document.querySelectorAll('[data-toggles]');
buttons.forEach(button => button.addEventListener('click', (event) => {
const toggleDiv = document.getElementById(button.dataset.toggles);
toggleDiv.toggleAttribute('hidden');
}));
.toggle-divs>div[id] {
background-color: #a00;
color: white;
margin: 10px;
text-align: center;
width: 200px;
}
.toggle-divs>div[id]::before {
content: "#"attr(id)" here";
}
<div class="toggle-buttons">
<button data-toggles="foo">toggle #foo</button>
<button data-toggles="bar">toggle #bar</button>
<button data-toggles="baz">toggle #baz</button>
</div>
<div class="toggle-divs">
Below here is the toggle divs:
<div id="foo" hidden></div>
<div id="bar" hidden></div>
<div id="baz" hidden></div>
</div>

Display none if child and parent element have the same class

I have these menus around my horizontal scrolling site.
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section
The goal is to filter them based if the button classes have the same class as the ones in the section. If they have the same class (in this example 'fun-stuff') then that button will display:none.
My jQuery. I feel I'm close or totally over-complicating it.
jQuery(document).ready(function($) {
var theList = $('.nav-list button');
var i;
for (i=0; i < theList.length; i++){
var theButtons = '"' + theList[i].className + '"';
var parentClassName = theList[i].closest('section').className;
// tried this one. Was close i believe but no dice
if(theButtons = theList[i].closest('section').hasClass('"' + theButtons + '"') ){
// display that button as none
}
// tried this as well and for each button got 'no' in the console
if( $(theList[i].closest('section') ).hasClass(theButtons) ){
console.log('yes');
} else {
console.log ('no');
}
}
});
Yes you overdid it somewhat
$(function() {
$("button").each(function() {
var $parent = $(this).closest("section"), // the section wrapping the button
same = $parent.hasClass($(this).attr("class")); // parent has this button's class too
$(this).toggle(!same); // hide if the same (show if not)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
If you have more than one class on the button and you want to hide if one of them matches
$(function() {
$("button").each(function() {
var bList = this.classList,
parentList = $(this).closest("section")[0].classList, // the DOM element's classList
same = [...parentList] // convert to iterable
.filter(ele => bList.contains(ele)) // look up parent class in button classList
.length>0; // found?
$(this).toggle(!same);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff bla">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can turn the section classes into a regular array, then filter and hide the buttons.
jQuery(document).ready(function($) {
var classes = $('#slide-1').attr("class").split(/\s+/);
classes.forEach(function (cls) {
$('.nav-list button').filter('.' + cls).hide()
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can do this pretty easily with vanilla Javascript:
const classNames = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach((el) => {
if(classNames.contains(el.classList)){
el.style.display = "none";
}
});
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
Edit: Done with two lines of code:
const classList = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach(el => el.style.display = classList.contains(el.classList) ? "none": "initial");
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>

HTML buttons, toggle when button clicked and toggle all other buttons (collapse info)

I am new to HTML-CSS. I have created some buttons and I am able to click on them and they will display more information. However I also want that when a button is clicked all the other buttons 'collapse' the information they were showing. I have tried looking it up and played around with the code but haven't managed to do it. Would appreciate some help!
function thirdP() {
var x = document.getElementById("Project3");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function secondP() {
var x = document.getElementById("Project2");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function firstP() {
var x = document.getElementById("Project1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<ul>
<button class="button" onclick="firstP">1st Project</button>
<div id="Project1" style="display:none" align="right">Information about the first project...</div>
</ul>
<ul>
<button class="button" onclick="secondP">2nd Project</button>
<div id="Project2" style="display:none" align="right">Information about the second project...</div>
</ul>
<ul>
<button class="button" onclick="thirdP">2nd Project</button>
<div id="Project3" style="display:none" align="right">Information about the second project...</div>
I know that probably this is very inefficient as I am writing the same Javascript function for every button. I haven't been able to create a single function that would work for all id's.
On clicking the button simply loop through all the elements whose id starts with Project to set display = "none" by using Document.querySelectorAll() and Array.prototype.forEach(). Then show only the nextElementSibling of the clicked button. Try the following:
function project(btn) {
document.querySelectorAll('[id^="Project"]').forEach(div => div.style.display = "none");
btn.nextElementSibling.style.display = "block";
}
<ul>
<button class="button" onclick="project(this)">1st Project</button>
<div id="Project1" style="display: none;" align="right">Information about the first project...</div>
</ul>
<ul>
<button class="button" onclick="project(this)">2nd Project</button>
<div id="Project2" style="display: none;" align="right">Information about the second project...</div>
</ul>
<ul>
<button class="button" onclick="project(this)">3rd Project</button>
<div id="Project3" style="display: none;" align="right">Information about the third project...</div>
</ul>
The reason for not toggling is brackets. You never used brackets for function in onclick.
Example :
onclick="firstP()"
I modified your code. Once check it. You can use one function to manipulate toggle for all id's, for that you need to pass id variable to a function like i did.
<ul>
<button class="button" onclick="firstP(1)">1st Project</button>
<div id="Project1" style="display:none" align="right">Information about the first project...</div>
<script>
function firstP(elementId) {
var x = document.getElementById('Project'+elementId);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
</ul>
<ul>
<button class="button" onclick="firstP(2)">2nd Project</button>
<div id="Project2" style="display:none" align="right">Information about the second project...</div>
<!-- <script>
function secondP() {
var x = document.getElementById("Project2");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script> -->
</ul>
<ul>
<button class="button" onclick="firstP(3)">2nd Project</button>
<div id="Project3" style="display:none" align="right">Information about the second project...</div>
<!-- <script>
function thirdP() {
var x = document.getElementById("Project3");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script> -->
</ul>
I figured out this solution, there is many other. If you think this is helpful.. cheers :D
function showDiv() {
var x = document.querySelectorAll(".info-div");
x.forEach(item => {
item.style.display = 'none';
});
event.target.nextElementSibling.style.display = 'block'
}
<ul>
<button class="button" onclick="showDiv()">1st Project</button>
<div class="info-div" style="display:none" align="right">Information about the first project...</div>
</ul>
<ul>
<button class="button" onclick="showDiv()">2nd Project</button>
<div class="info-div" style="display:none" align="right">Information about the second project...</div>
</ul>
<ul>
<button class="button" onclick="showDiv()">3rd Project</button>
<div class="info-div" style="display:none" align="right">Information about the third project...</div>

Categories

Resources