Close dropdown on click - javascript

const dropdownBtns = document.querySelectorAll('.dropdown-btn');
const dropdownLists = document.querySelectorAll('.dropdown-list');
dropdownBtns.forEach(function(dropdownBtn) {
dropdownBtn.addEventListener('click', function() {
dropdownLists.forEach(function(dropdownList) {
if (dropdownList !== this.nextElementSibling) {
dropdownList.style.display = 'none';
}
});
this.nextElementSibling.style.display = this.nextElementSibling.style.display === 'block' ? 'none' : 'block';
});
});
.container {
display: flex;
gap: 50px;
}
.dropdown-list {
display: none;
}
<div class="container">
<div class="dropdown">
<button class="dropdown-btn">Dropdown 1</button>
<ul class="dropdown-list">
<li><input type="checkbox" id="item-1"> <label for="item-1">Item 1</label></li>
<li><input type="checkbox" id="item-2"> <label for="item-2">Item 2</label></li>
<li><input type="checkbox" id="item-3"> <label for="item-3">Item 3</label></li>
</ul>
</div>
<div class="dropdown">
<button class="dropdown-btn">Dropdown 2</button>
<ul class="dropdown-list">
<li><input type="checkbox" id="item-4"> <label for="item-4">Item 4</label></li>
<li><input type="checkbox" id="item-5"> <label for="item-5">Item 5</label></li>
<li><input type="checkbox" id="item-6"> <label for="item-6">Item 6</label></li>
</ul>
</div>
</div>
Having a list of dropdowns I'd like to close other dropdown list if one is clicked and close itself if its already open. First part is working however button isn't closing the currently open dropdown list.

Target instead your parent .dropdown wrappers, toggle a class like is-active, style in CSS accordingly.
Use Element.classList and the respective .toggle() and .remove() prototype methods:
const elsDD = document.querySelectorAll('.dropdown')
elsDD.forEach(elDD => {
elDD.querySelector(".dropdown-btn").addEventListener("click", () => {
elsDD.forEach(el => {
el.classList[el === elDD ? "toggle" : "remove"]("is-active");
});
});
});
.container {
display: flex;
gap: 50px;
}
.dropdown .dropdown-list {
display: none;
}
.dropdown.is-active .dropdown-list {
display: initial;
}
<div class="container">
<div class="dropdown">
<button class="dropdown-btn">Dropdown 1</button>
<ul class="dropdown-list">
<li><label><input type="checkbox" name="c1" value="1">Item 1</label></li>
<li><label><input type="checkbox" name="c1" value="2">Item 2</label></li>
<li><label><input type="checkbox" name="c1" value="3">Item 3</label></li>
</ul>
</div>
<div class="dropdown">
<button class="dropdown-btn">Dropdown 2</button>
<ul class="dropdown-list">
<li><label><input type="checkbox" name="c2" value="4"> Item 4</label></li>
<li><label><input type="checkbox" name="c2" value="5"> Item 5</label></li>
<li><label><input type="checkbox" name="c2" value="6"> Item 6</label></li>
</ul>
</div>
</div>
The above solution is pretty slick since you can style as "active" not only the .dropdown wrapper, but also any child element by just descending from the parent: .dropdown.is-active .dropdown-btn { background: gold; }. You get the point.

Related

Javascript enable html when input checkbox checked

What should be the condition for: If i click the check box then the items for that particular brand is triggered?
Here I want to print the values for the item selected
The current code is showing Cannot read properties of null (reading 'addEventListener')
let filterBrand = document.getElementById("filter-brands");
filterBrand.addEventListener("change", function() {
if (filterBrand.value == "Amana") {
document.querySelector(".item-list").innerHTML = "";
for (let i = 0; i < productData.length; i++) {
console.log("hello");
}
}
});
<h5>Filter By Brand</h5>
<ul id="filter-brands">
<li>
<input type="checkbox" id="Amana" value="Amana" />
<label for="Amana">Amana</label>
</li>
<li>
<input type="checkbox" id="Frigidaire" value="Frigidaire" />
<label for="Frigidaire">Frigidaire</label>
</li>
<li>
<input type="checkbox" id="GE" value="GE" />
<label for="GE">GE</label>
</li>
<li>
<input type="checkbox" id="Insignia" value="Insignia" />
<label for="Insignia">Insignia</label>
</li>
<li>
<input type="checkbox" id="LG" value="LG" />
<label for="LG">LG</label>
</li>
<li>
<input type="checkbox" id="Samsung" value="Samsung" />
<label for="Samsung">Samsung</label>
</li>
<li>
<input type="checkbox" id="Whirlpool" value="Whirlpool" />
<label for="Whirlpool">Whirlpool</label>
</li>
</ul>
You can retrieve all checked checkboxes within ul#filter-brands using the css-selector #filter-brands input[type='checkbox']:checked. For example:
document.addEventListener(`click`, handle);
function handle(evt) {
if (evt.target.closest(`#filter-brands`)) {
console.clear();
const selected = [];
// all checked checkboxes
document.querySelectorAll(`#filter-brands input[type='checkbox']:checked`)
.forEach( cb => /* here you can insert code to display stuff */
selected.push(cb.id) );
console.log(`Selected: ${selected.length ? selected.join(`, `) : `NONE`}`);
}
}
<h5>Filter By Brand</h5>
<ul id="filter-brands">
<li>
<input type="checkbox" id="Amana" value="Amana" />
<label for="Amana">Amana</label>
</li>
<li>
<input type="checkbox" id="Frigidaire" value="Frigidaire" />
<label for="Frigidaire">Frigidaire</label>
</li>
<li>
<input type="checkbox" id="GE" value="GE" />
<label for="GE">GE</label>
</li>
<li>
<input type="checkbox" id="Insignia" value="Insignia" />
<label for="Insignia">Insignia</label>
</li>
<li>
<input type="checkbox" id="LG" value="LG" />
<label for="LG">LG</label>
</li>
<li>
<input type="checkbox" id="Samsung" value="Samsung" />
<label for="Samsung">Samsung</label>
</li>
<li>
<input type="checkbox" id="Whirlpool" value="Whirlpool" />
<label for="Whirlpool">Whirlpool</label>
</li>
</ul>
A more specific approach (handler per checkbox):
document.addEventListener(`click`, handle);
function handle(evt) {
if (evt.target.closest(`#filter-brands`) && evt.target.type === `checkbox`) {
const selected = evt.target.checked;
return document.querySelector(`[data-selector='${evt.target.id}']`)
.classList[evt.target.checked ? `add` : `remove`](`selected`);
}
}
ul {
display: inline-block;
max-width: 50vw;
}
ul#filter-brands {
float: left;
}
#brand-lists li {
display: none;
}
#brand-lists li.selected {
display: revert;
}
<h5>Filter By Brand</h5>
<ul id="filter-brands">
<li>
<input type="checkbox" id="Amana" value="Amana" />
<label for="Amana">Amana</label>
</li>
<li>
<input type="checkbox" id="Frigidaire" value="Frigidaire" />
<label for="Frigidaire">Frigidaire</label>
</li>
<li>
<input type="checkbox" id="GE" value="GE" />
<label for="GE">GE</label>
</li>
<li>
<input type="checkbox" id="Insignia" value="Insignia" />
<label for="Insignia">Insignia</label>
</li>
<li>
<input type="checkbox" id="LG" value="LG" />
<label for="LG">LG</label>
</li>
<li>
<input type="checkbox" id="Samsung" value="Samsung" />
<label for="Samsung">Samsung</label>
</li>
<li>
<input type="checkbox" id="Whirlpool" value="Whirlpool" />
<label for="Whirlpool">Whirlpool</label>
</li>
</ul>
<ul id="brand-lists">
<li data-selector="Amana">Amana list</li>
<li data-selector="Frigidaire">Frigidaire list</li>
<li data-selector="GE">GE list</li>
<li data-selector="Insignia">Insignia list
<li data-selector="LG">LG list</li>
<li data-selector="Samsung">Samsung list</li>
<li data-selector="Whirlpool">Whirlpool list</li>
</ul>

React & SASS - checkbox component not aligning with label

I am new to React and converting a previously pure HTML page into a component in React. How do I update the SASS stylesheet to resemble the previous HTML format?
This is what I currently have in React (checkbox is showing on right instead of left, and checkbox and labels are not aligned):
This is what I previously had in HTML, and the ideal format:
checkbox.component.jsx
import React from "react";
import './checkbox.styles.scss'
const Checkbox = ({ label, isSelected, onCheckboxChange }) => (
<div className="form-check">
<li>
<label for={label}> {label} </label>
<input
type="checkbox"
name={label}
id={label}
value={label}
checked={isSelected}
onChange={onCheckboxChange}
/>
</li>
</div>
);
export default Checkbox;
checkbox.styles.scss
.form-check{
li{
list-style: none;
margin-left: 15px;
text-align:left;
}
label{
cursor: pointer;
}
label:hover{
background-color:linen;
text-decoration:underline;
}
}
First - you need to move the div inside the li - the only valid child element of a list is an li element.
If you wrap the input with the label you will get that alignment plust the added benefit of being able to click the lable to change the checkbox. Obvsiously I have replaced the React interpolation with static content.
ul {list-style: none}
ul li {padding: 8px 0}
<ul>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-1"
id="form-check-1"
value="1"
checked=checked
/>
$ - $0 - 50 </label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-2"
id="form-check-2"
value="2"
/>
$$ - $51 - 100</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-3"
id="form-check-3"
value="3"
/>
$$$ - $101 - 150</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="checkbox"
name="form-check-4"
id="form-check-4"
value="4"
/>
$$$$ - $150+</label>
</div>
</li>
</ul>
Also - since these options appear to be mutually exlusive - I would suggest a radio button group to be more appropriate - that way only one option at a time can be selected. Using checkboxes will allow multiple selections - which is probably not intended in this case.
The radio button approach (which I would recommend) - use the same name attribute for all instances of hte radio input.
ul {list-style: none}
ul li {padding: 8px 0}
<ul>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-1"
value="1"
checked=checked
/>
$ - $0 - 50 </label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-2"
value="2"
/>
$$ - $51 - 100</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-3"
value="3"
/>
$$$ - $101 - 150</label>
</div>
</li>
<li>
<div className="form-check">
<label>
<input
type="radio"
name="form-check"
id="form-check-4"
value="4"
/>
$$$$ - $150+</label>
</div>
</li>
</ul>

How to change the style of checkboxes when clicking on one of the list , inactive change the style?

How to change the style of checkboxes when clicking on one of the list , inactive change the style ? When you click the checkbox, the sf-option-active class is issued. How can css be changed by others ?
Initially, all the elements are highlighted, when you click on one checkbox others are dimmed
<ul data-operator="or" class="list">
<li class="sf-level-0 sf-item-29" data-sf-count="19" data-sf-depth="0"><input class="sf-input-checkbox" type="checkbox" value="tehobor" name="_sft_tip[]" id="sf-input-fc6224670cc95e4fdecf6cc456d08c36">
<label class="sf-label-checkbox" for="sf-input-fc6224670cc95e4fdecf6cc456d08c36">Name1</label></li>
<li class="sf-level-0 sf-item-30 sf-option-active" data-sf-count="6" data-sf-depth="0"><input class="sf-input-checkbox" type="checkbox" value="konveiri" name="_sft_tip[]" checked="checked" id="sf-input-868176859db7cbdd316babead1c4a6ca"><label class="sf-label-checkbox" for="sf-input-868176859db7cbdd316babead1c4a6ca">Name2</label></li>
<li class="sf-level-0 sf-item-31" data-sf-count="8" data-sf-depth="0"><input class="sf-input-checkbox" type="checkbox" value="prolinii" name="_sft_tip[]" id="sf-input-080920625a50faa6f70e10891e88ebaa"><label class="sf-label-checkbox" for="sf-input-080920625a50faa6f70e10891e88ebaa">Name3</label></li>
<li class="sf-level-0 sf-item-32" data-sf-count="4" data-sf-depth="0"><input class="sf-input-checkbox" type="checkbox" value="neitrobor" name="_sft_tip[]" id="sf-input-df092a05d0048b1297780b8683077cb1"><label class="sf-label-checkbox" for="sf-input-df092a05d0048b1297780b8683077cb1">Name4</label></li>
</ul>
1:
2:
Problem with radio buttons is you cannot remove selection. If you do not want to use radio buttons, you can use this small jquery snippet here with checkboxes.
$(".sf-input-checkbox").on("click", (e) => {
if(e.target.checked) {
$(".sf-input-checkbox").not($(e.target)).prop('checked', false);;
$(".sf-label-checkbox").not($(e.target).next()).addClass("dimmed");
$(e.target).next().removeClass("dimmed");
} else {
$(".sf-label-checkbox").removeClass("dimmed");
}
});
.dimmed {
color: lightgray;
}
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul data-operator="or" class="list">
<li class="sf-level-0 sf-item-29" data-sf-count="19" data-sf-depth="0">
<input class="sf-input-checkbox hidden" type="checkbox" value="tehobor" name="_sft_tip[]" id="sf-input-fc6224670cc95e4fdecf6cc456d08c36">
<label class="sf-label-checkbox" for="sf-input-fc6224670cc95e4fdecf6cc456d08c36">Name1</label>
</li>
<li class="sf-level-0 sf-item-30 sf-option-active" data-sf-count="6" data-sf-depth="0">
<input class="sf-input-checkbox hidden" type="checkbox" value="konveiri" name="_sft_tip[]" id="sf-input-868176859db7cbdd316babead1c4a6ca">
<label class="sf-label-checkbox" for="sf-input-868176859db7cbdd316babead1c4a6ca">Name2</label>
</li>
<li class="sf-level-0 sf-item-31" data-sf-count="8" data-sf-depth="0">
<input class="sf-input-checkbox hidden" type="checkbox" value="prolinii" name="_sft_tip[]" id="sf-input-080920625a50faa6f70e10891e88ebaa">
<label class="sf-label-checkbox" for="sf-input-080920625a50faa6f70e10891e88ebaa">Name3</label>
</li>
<li class="sf-level-0 sf-item-32" data-sf-count="4" data-sf-depth="0">
<input class="sf-input-checkbox hidden" type="checkbox" value="neitrobor" name="_sft_tip[]" id="sf-input-df092a05d0048b1297780b8683077cb1">
<label class="sf-label-checkbox" for="sf-input-df092a05d0048b1297780b8683077cb1">Name4</label>
</li>
</ul>
You don't need any JS for this. Instead you can just say in CSS:
For every label who are AFTER a checkbox: put it gray (.moo + span)
For every label who are AFTER a CHECKED checkbox: put it black (.moo:checked + span)
.moo + span {
color: #AAA;
}
.moo:checked + span {
color: #000;
}
<input type='radio' name="moo" class="moo"><span>1111</span><br/>
<input type='radio' name="moo" class="moo"><span>2222</span><br/>
<input type='radio' name="moo" class="moo"><span>3333</span><br/>
<input type='radio' name="moo" class="moo"><span>4444</span>
With a little more code you can link the label to the checkbox and (why not) hiding the checkbox:
.moo {
visibility: hidden;
}
.moo + label {
color: #AAA;
cursor: pointer;
}
.moo:checked + label {
color: #000;
}
<div>
<input type='radio' name="moo" id="c1" class="moo">
<label for="c1">1111</label>
</div>
<div>
<input type='radio' name="moo" id="c2" class="moo">
<label for="c2">2222</label>
</div>
<div>
<input type='radio' name="moo" id="c3" class="moo">
<label for="c3">3333</label>
</div>
<div>
<input type='radio' name="moo" id="c4" class="moo">
<label for="c4">4444</label>
</div>
UPDATED with radio instead of checkbox

if has no child addClass?

I want to addClass my span.toggle if parent of li has no ul element inside.
click to see on codepen
HTML:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>No Title</title>
</head>
<body>
<ul>
<li>
<span class="toggle"></span><input type="checkbox" name="" id="0"><label for="0">Main 1</label>
<ul>
<span class="toggle"></span> <li><input type="checkbox" name="" id="0-1"><label for="0-1">Child 1</label></li>
<span class="toggle"></span><li><input type="checkbox" name="" id="0-2"><label for="0-2">Child 2</label>
<ul>
<span class="toggle"></span> <li><input type="checkbox" name="" id="0-1-1"><label for="0-1-1">Sub Child 1</label></li>
<span class="toggle"></span><li><input type="checkbox" name="" id="0-1-2"><label for="0-1-2">Sub Child 2</label></li>
</ul>
</li>
<span class="toggle"></span> <li><input type="checkbox" name="" id="0-3"><label for="0-3">Child 3</label></li>
<span class="toggle"></span> <li><input type="checkbox" name="" id="0-4"><label for="0-4">Child 4</label></li>
</ul>
</li>
<li>
<span class="toggle"></span> <input type="checkbox" name="" id="1"><label for="1">Main 2</label>
</li>
<li>
<span class="toggle"></span> <input type="checkbox" name="" id="2"><label for="2">Main 2</label>
<ul>
<li>
<span class="toggle"></span> <input type="checkbox" name="" id="2-1"><label for="2-1">Child 1</label>
</li>
</ul>
</li>
</ul>
<script type="text/javascript" src="https://cdn.anitur.com.tr/js/jquery-1.8.2.min.js" ></script>
</body>
</html>
CSS:
ul{
list-style: none;
padding:0;
margin: 0;
margin-left:20px;
font:13px calibri;
}
input[type="checkbox"]{
vertical-align:middle;
}
span.toggle{
float:left;
display:block;
background:url("https://cdn3.iconfinder.com/data/icons/fatcow/16/bullet_toggle_plus.png") no-repeat 0px 1px;
width:16px;
height:16px;
}
ul> * ul {
display:none;
}
input[type="checkbox"]:checked ~ ul{
display:block;
}
jQuery:
$(function(){
$("ul li").children("ul").each(function(){
$(this).find("li").addClass("parentUl");
});
});
$('ul > li').each(function(i,t){
var t = $(t);
if(! t.children('ul').length){
t.children('span').addClass('add-class');
}
});
Check out Get all elements without child node in jQuery
$('li'):not(:has(*)).addClass('classy');

Enable Multi Select option in bootstrap check box?

I am creating a web application in which bootstrap is used for design. And I am creating a check box using bootstrap.check-box.js and bootstrap.check-box.css
Using the code
$('input[type="checkbox"]').checkbox();
my html code is
<div id="popover-cnt-detect" class="hide">
<ul class="detectul">
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Frontal"> Frontal Face</label></div></li>
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Profile"> Profile Face</label></div></li>
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Eyes"> Eyes</label> </div></li>
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Head"> Head</label></div></li>
</ul>
<button type="submit" class="btn alert-continue-btn ">Continue</button>
</div>
This is the jquery code for popping up that checkbox div..
$("#detect").popover({
html: true,
content: function() { return $('#popover-cnt-detect').html(); }
});
$("#detect").click(function()
{
$(this).popover({
html: true,
trigger: 'click',
content: function() { return $('#popover-cnt-detect').html(); }
});
return false;
});
Now , What I need to know is that this check-box is single-select only,I couldn't select multiple options in that check box.
So,Please help me friends by telling how to provide multiple select option in check-boxes..
Thanks in advance...
Working jsFiddle example
Code
HTML
<div id="popover-cnt-detect" class="hide">
<div class="checkbox"><label><input type="checkbox" class="checkbox select-all">Select All</label></div>
<ul class="detectul">
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Frontal"> Frontal Face</label></div></li>
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Profile"> Profile Face</label></div></li>
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Eyes"> Eyes</label> </div></li>
<li class="listitems"> <div class="checkbox"><label><input name="check[]" type="checkbox" class="checkbox" value="Head"> Head</label></div></li>
</ul>
<button type="submit" class="btn alert-continue-btn ">Continue</button>
</div>
JavaScript
$(document).on('change','.select-all',function(){
if($(this).is(':checked')) {
$('[name="check[]"]').each(function(){
$(this).prop('checked', true);
});
} else {
$('[name="check[]"]').each(function(){
$(this).prop('checked', false);
});
}
});
Explanation
We add a new checkbox with the class select-all and listen to the change event of that checkbox. If it is checked, JavaScript will search for all the checkboxes with the name checkbox[] and make it checked using prop('checked', true). If it is unchecked it will uncheck the checkboxes using prop('checked', false).

Categories

Resources