show and hide class based on checkbox value usig Jquery - javascript

Hi currently i am developing an filtering application . Please see my html and js code
jQuery(document).ready(function($){
$(".color-label").on("click",function(){
var color_box_val= $(this).find('.color-box').val();
$('.test-li').hide();
$('div:contains('+color_box_val+')').closest('.test-li').show();
});
});
.hidden-color{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<label class="color-label">Red<input type="checkbox" class="color-box" value="red"/></label>
<label class="color-label">Black <input type="checkbox" class="color-box" value="Black"/></label>
<ul>
<li class="test-li">
<div class="test-div">
<p class="hidden-color">red</p>
red poduct
</div>
</li>
<li class="test-li">
<div class="test-div">
<p class="hidden-color">Black</p>
black Product
</div>
</li>
<li class="test-li">
<div class="test-div">
<p class="hidden-color">Blue</p>
blue Product
</div>
</li>
So here what iam doing is when customer click black , then it will show black product . If the customer click both red and black then we need to show both , and if customer didn't tick anything then we need to show all product .
But i stuck in some point . Here how can i show both red and black when the clicked both ? Currently it is showing the result based on newly clicked check box . Also if they untick every thing then i need to show all box . Please suggest .

The first thing I would recommend changing is how you store color data in your list items. Instead of storing them in a hidden paragraph element, why not store them as HTML5 data- attributes?
Once that is done, it is quite simple to do what you intend: which is basically a OR operation, i.e. when red and black are ticked, you want to show items that are red or black.
The logic is as follow:
You listen to the .change() event on all the checkboxes
When this event is fired, you want to collect the values of all these checkboxes, but only if they are checked. This is done by using .filter(':checked') to select for checked checkboxes and .map() to return the array.
Next, you iterate through all the list items. If their data-color values are found in the array, you show them. Otherwise you hide them.
And all this logic is wrapped within a conditional statement that checks if any of the checkboxes are filtered:
If none is checked, we do not want any filtering
If one or more is checked, we perform filtering using the aforementioned filtering logic
Update: I have used .toLowerCase() to convert all your color values to lowercase, since from your question I can see that the values might be optionally capitalised.
See proof-of-concept example below:
jQuery(document).ready(function($) {
// Listen to change event
$('.color-box').change(function() {
// Store checked checkboxes
var $checked = $('.color-box').filter(':checked');
if ($checked.length) {
// Perform filtering if one or more is checked
// Collect ALL values from all .color-box into an array
var colors = $checked.map(function() {
return $(this).val().toLowerCase();
}).get();
// Iterate through each list item and evaluate
$('.test-li').each(function() {
var $t = $(this);
if (colors.indexOf($t.data('color').toLowerCase()) >= 0) {
$t.show();
} else {
$t.hide();
}
});
}
// If nothing is checked, show all list items
else {
$('.test-li').show();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<label class="color-label">Red<input type="checkbox" class="color-box" value="red"/></label>
<label class="color-label">Black <input type="checkbox" class="color-box" value="Black"/></label>
<ul>
<li class="test-li" data-color="red">
<div class="test-div">
red Product
</div>
</li>
<li class="test-li" data-color="black">
<div class="test-div">
black Product
</div>
</li>
<li class="test-li" data-color="blue">
<div class="test-div">
blue Product
</div>
</li>

Related

Using only JS and css, can I implement a filter, so that: clicking/tapping within a JS dropdown menu shows/hides page divs by data-type?

With the help of SO member the.marolie I learned how to implement a JS filter/selector [the 'demo JS filter']. I have this working perfectly on a test page: it shows/hides divs according to "data-types" assigned to them in the body html. However, the selection is made by sliding down a <select> dropdown list and letting go at the preferred option. That's not quite what I want.
I want to utilise my existing nav-bar dropdown ['my dropdown'] as the filter/selector. I especially want to retain the existing interactivity of my dropdown, whereby one click/tap reveals the whole of the dropdown content block, and one click outside the content block closes it.
I want the elements within my dropdown to represent various show/hide <div> 'options' for the html page, and enable the user to choose from these via an additional click/tap (essentially what the demo JS filter does, but at the instigation of a click/tap). Once revealed via a nav-bar click/tap, the whole dropdown content block has to stay on-screen -as it currently does- for this to be practically possible.
After making my dropdown identifiable via id="media-selector-demo" and name="filter" I was hoping that I could assign the demo JS filter's <option> elements to the <a> elements in it, and the whole thing would function like the <select> dropdown of the demo JS filter. I had a vague idea that using <a> elements might obviate the need for another onClick in the JS. I've tried various combinations of <a> and <option> elements, but nothing has worked yet.
Do I need another onClick to invoke the JS filter via my dropdown? or
Can I invoke the JS filter via 'active' <a> status?
I'm struggling by trial and error.
Here are what I think are the relevant sections of code pertaining to all discussed above:
My dropdown is based on the following code.
JS in the page head:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myDropdownJS() {
document.getElementsByClassName("navbarDROPDOWN-JS")[0].classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementsByClassName("navbarDROPDOWN-JS")[0];
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
My dropdown html in nav bar (most of the css is just design styling):
<span class="dropdown" onclick="myFunction()">
<a class="dropbtn navbarDROP-ICON" style="opacity:0.5; padding-top:0px;">menu</a>
<a class="dropbtn navbarDROP-TXT" style="opacity:0.5">menu </a>
<a class="dropbtn navbarDROP-TXT">Career Works by Date </a>
<div class="dropdown-content navbarDROPDOWN-JS" >
<a class="tag-bgd-INSTLLN" href="#">Installations (all media)</a>
<a class="tag-bgd-MOVIMG" href="#">Works with moving image (inc. vid/film releases)</a>
<a class="tag-bgd-SNDMUS" href="#">...with sound and music (inc. sound/music releases)</a>
<a class="tag-bgd-PHOTO" href="#">...with photographs</a>
<a class="tag-bgd-DRAW" href="#">...with drawing (inc. 2D works)</a>
<a class="tag-bgd-TXT" href="#">...with text</a>
<a class="tag-bgd-PERF" href="#">...with performative action</a>
<a class="tag-bgd-COLPUB" href="#">Collaborative and public works</a>
<a class="tag-bgd-OBJDEV" href="#">>Objects, garments, devices</a>
<a class="tag-bgd-EDPUB" href="#">Editions, publications</a>
<a class="tag-bgd-CAREER" href="#">Career Works by Date</a>
</div>
Above: the <a href> elements were going to contain URLs for alternatively styled pages. There is no need for these if I can enable the user to selectively show/hide parts of just this one page, via this dropdown.
The demo JS filter is based on the following code (via SO user the.marolie).
JS at page end:
var select = document.getElementById('media-selector-demo');
var filter;
select.addEventListener("change", function() {
filter = select.value;
var elements = document.querySelectorAll('.wk-date_ITEM');
elements.forEach((el) => {
var type = el.dataset.type.split(', ');
if (type.includes(filter)) {
el.classList.remove('hide-by-media');
} else {
el.classList.add('hide-by-media');
}
})
});
Demo JS filter CSS:
.hide-by-media {
display: none;
}
Demo JS filter html in page body:
<select id="media-selector-demo" name="filter">
<option value="INSTLLN"> Installations (all media)</option>
<option value="MOVIMG"> Works with moving image (inc. vid/film releases)</option>
<option value="SNDMUS" >...with sound and music (inc. sound/music releases)</option>
</select>
Example div in page body (there are 80-100 of these):
<!-- ++++++++++ START FULL-WIDTH LIST ENTRY '2017 STATE OF DREAD' ++++++++++ -->
<div id="state-of-dread" class="w3-container wk-date_ITEM" data-type="INSTLLN, SNDMUS">
<div class="w3-container wk-date_TXT-IMG">
<div class="wk-date_GRID">
<div class= "h3 wk-date_DATE"> 2017 </div>
<div class="wk-date_TTL"><h1>State of Dread</h1></div>
<div class="h2 wk-date_KIND-1" >Installation</div>
<div class="p wk-date_KIND-2" ><span class="sound">Sound</span>, for x2 interconnected rooms.<br>AB, CD, EF, Solo exhibition (as trio), Ohrenhoch sound gallery, Berlin.</div>
<div class="wk-date_IMG">
<div class="w3-container w3-right wk-date_IMG-BOX-LSCP">
<img src="../../imgs/INSTALLATION-EVENT/2017_dread_thmb.jpg"
alt="'xx' by Andrew Stones, installation view, xx"></div>
</div>
</div>
</div>
</div>
<!-- ++++++++++ END FULL-WIDTH LIST ENTRY '2017 STATE OF DREAD' ++++++++++ -->
Demo JS filter: JS at end of page:
<script type="text/javascript">
var select = document.getElementById('media-selector-demo');
var filter;
select.addEventListener("change", function() {
filter = select.value;
var elements = document.querySelectorAll('.wk-date_ITEM');
elements.forEach((el) => {
var type = el.dataset.type.split(', ');
if (type.includes(filter)) {
el.classList.remove('hide-by-media');
} else {
el.classList.add('hide-by-media');
}
})
});
</script>
What you would need to do is change the event listener from select, change to drop down element, click. you would also need to add the values of the options from the select as data-value attributes on the drop down elements.
1 - add a data-value attribute to the elements to represent what to hide
<a class="tag-bgd-INSTLLN" href="#" data-value="INSTLLN">
2 - target the drop down elements you want to attach the event listener to.
const dropDownElements = document.querySelectorAll('.dropdown-content a')
3 - attach event listeners to the selected targets (PS. the e in the function stands for event, click event listener produces an event object)
dropDownElements.forEach((dropDownElement) => {
dropDownElement.addEventListener('click',(e)=>{
const filter = e.target.dataset.value;
})
})
4 - the rest is just adding the rest of the filter used in the demo js filter
dropDownElements.forEach((dropDownElement) => {
dropDownElement.addEventListener("click", (e) => {
const filter = e.target.dataset.value
var elements = document.querySelectorAll(".wk-date_ITEM")
elements.forEach((el) => {
var type = el.dataset.type.split(", ")
if (type.includes(filter)) {
el.classList.remove("hide-by-media")
} else {
el.classList.add("hide-by-media")
}
})
})
})

Loop throught checkboxes and delete hidden copies javascript

Ok so, im trying to create a loop and a loop inside that loop. The point is to create a remove function. I have a list of users and copies of those same users hidden. Purpose of copies is show them on clicking 'online' link or 'offline' link or 'all'. When i want to remove a user i made a checkbox for each user, by clicking the checkbox, it pushes that element into an array. then when i click minus it removes that user and loops thru the hidden copies and removes the ones match the id. It works fine for one user, or if i check/select users from the bottom of the list going up, then it loops thru the array perfectly fine and removes all copies from DOM. But if i do it the normal way by selecting per say the first user on the list then second then third etc, it will only loop thru the first user element. but in console, it shows that the array has the users i pushed into, and it will actually loop thru that first element the amount of times as how many users i pushed into it.
Someone pointed out to not using duplicate ids and i knew that, but i didnt know how else to get this done, i tried using title, name, but cant use classes cuz i have multiple classes on the elements. Im mindfckd as to why it works if i select elements backwards. this is a isolated example from my project, so it only has one class and i dont have hidden copies. this is just so someone helping can better see what im tryin to do. the visible copies need to dissapear by checking only one copy but it has the same bug, html doesnt seen to show parent div..
http://codepen.io/Pagnito/pen/vmLOvj?editors=1010
function minus() {
$('.fa-minus').click(function() {
if ($('.chBox').is(':checked')) {
var div = $(':checked').closest('div');
var dib = div.next();
$(checkedArr).each(function(i, iteM) {
console.log(checkedArr)
var ch = iteM;
var chkd = $(ch).attr('id')
console.log(chkd)
console.log('hi' + i)
$('.g').each(function(index, item) {
var ite = $(item).attr('id')
if (ite == chkd) {
$(item).remove();
var dib = div.next('#acc');
$(dib).remove();
}
})
})
var dib = div.next('#acc');
$(dib).remove();
$(':checked').closest('a').remove();
checkedArr = [];
}
})
}
<div class="list-group hidden-xs-down streams">
<div class="g" class="free"><input class="chBox" type="checkbox" name="user">Free</div>
<div class="g" id="ninja"><input class="chBox" type="checkbox" name="user">ninja</div>
<div class="g" id="big"><input class="chBox" type="checkbox" name="user">big</div>
<div class="g" id="free"><input class="chBox" type="checkbox" name="user">Free</div>
<div class="g" id="ninja"><input class="chBox" type="checkbox" name="user">ninja</div>
<div class="g" id="big"><input class="chBox" type="checkbox" name="user">big</div>
<div class="g" id="free"><input class="chBox" type="checkbox" name="user">Free</div>
<div class="g" id="ninja"><input class="chBox" type="checkbox" name="user">ninja</div>
<div class="g" id="big"><input class="chBox" type="checkbox" name="user">big</div>
</div>

Checkboxes count selected checkboxes, sometimes returns an error

I am using an accordion, divided into 5 categories, showing several rows of checkboxes. When the visitor selects a checkbox, it returns the amount of selected checkboxes per category. Nothing is shown when none of the checkboxes are selected. E.g.
Category 1: 2 checkboxes selected
Category 2: 1 checkboxes selected
Category 3:
Category 4: 10 checkboxes selected
Category 5:
This works, so when the visitor adds another one in category 4 it will show "11 checkboxes selected". Also when one is turned off, it of course shows "9 checkboxes selected".
However, this works 95% of the time. When I randomly click the checkboxes, it sometimes returns an error in the log
Uncaught TypeError: undefined is not a function studiezoeker:487Request studiezoeker:487(anonymous function) studiezoeker:479v.event.dispatch ScriptResource.axd?d=dNZi6RW_20g0sp3isLHt5GoHGXYiqvO1u3-FU9wcgPXyQCu1rmFi0RuSIwIzaJjczNe7S8D3OTnoIX…:2o.handle.u
The counter in this case will be stuck at whatever it was. In this example, category 4 will be stuck at 10. However, when I now click another one, the results are correct again. 12 selected will be shown.
I've searched for hours, but I just can't find it.
The Javascript-part where it goes wrong. It goes wrong within the first 4 lines.
$(".filtercontainer .accordionitem").each(function () {
$(".beefup-body [type='checkbox']", this).change(function () {
var count = $(this).parent().parent().parent().delay(100).find($("[type='checkbox']:checked")).length;
console.log(count);
$(this).parent().parent().parent().siblings("h2").find(".checkCount").text(count + " geselecteerd");
if (count == 0) {
$(this).parent().parent().parent().siblings("h2").find(".checkCount").hide();
}
else {
$(this).parent().parent().parent().siblings("h2").find(".checkCount").show();
}
});
The HTML (stripped down all checkboxes and all categories, so it's easier to read
<div class="filtercontainer">
<div class="Accordion">
<div class="AccordionInner">
<article class="taxonomy accordionitem open" data-taxonomy="school" role="article">
<h2 class="beefup-head">school <span class="checkCount">14 selected</span></h2>
<div class="beefup-body" style="display: block;">
<div class="columncount">
<div class="taxa" title="ade08e3b-77bc-6478-97b6-ff00006ae40d" data-taxa-id="ade08e3b-77bc-6478-97b6-ff00006ae40d">
<input id="ade08e3b-77bc-6478-97b6-ff00006ae40d" type="checkbox" name="ctl00$Content$C022$cbFilter">
<label class="coverCheckBox" for="ade08e3b-77bc-6478-97b6-ff00006ae40d"><span></span></label>
<span class="filterName">One checkbox as an example</span>
<!-- More checkboxes below this one, upto 40 per category -->
</div>
<div class="taxa" title="afe08e3b-77bc-6478-97b6-ff00006ae40d" data-taxa-id="afe08e3b-77bc-6478-97b6-ff00006ae40d"></div>
</div>
</div>
</article>
<article class="taxonomy accordionitem" data-taxonomy="vorm" role="article">
<h2 class="beefup-head">vorm <span class="checkCount"></span></h2>
<div class="beefup-body" style="display: none;">
<div class="columncount">
<!-- Checkboxes in this category as well -->
</div>
</div>
</article>
<!-- More categories containing their own checkboxes here as well -->
</div>
</div>
</div>

Show/hide div on checkbox click with unknown amount of divs

I have an auto-generated list of sections that looks like that:
<div class="list">
<section class="visible list-0"></section>
<section class="hidden list-1"></section>
<section class="hidden list-2"></section>
<section class="hidden list-3"></section>
<!-- unknown amount of sections -->
</div>
And a checkbox:
<input type="checkbox" id="accept" value="1" required>
If checkbox is checked I want to hide the first section .list-0 and show next section list-1. Then if checkbox is checked again, hide list-0 and list-1 and show list-2. Please note that the amount of sections in unknown and can be up to about 25.
The following code is what I wrote by now.
$('#accept').on('click',function() {
var count_sections = $('.list > section').length;
$('.list-0').removeClass('visible').addClass('hidden');
$('.list-1').removeClass('hidden').addClass('visible');
// this should uncheck the checkbox
$('#accept').attr('checked', false);
});
I want to automate it so it will work no matter how many sections I have. Any help is very appreciated. Thanks.
try this one:
$('#accept').on('click',function() {
$('.visible').next('.hidden').removeClass('hidden').addClass('visible');
$('.visible:first').removeClass('visible').addClass('hidden');
// this should uncheck the checkbox
$('#accept').prop('checked', false);
});
this is my first approach. you select the visible element, hide it, toggle class visible, select the next element, show it and toggle class visible.
i completely removed the hidden class from this solution, since we switch between two states - visible and hidden - we only need the visible class to know if it is visible or hidden...
$('#accept').on('click',function() {
if (!$("section:last").hasClass("visible"))
{
$('.visible').hide().toggleClass("visible").next()
.show().toggleClass("visible");
// this should uncheck the checkbox
$('#accept').attr('checked', false);
}
});
UPDATED FIDDLE: http://jsfiddle.net/tbu116w8/2/
added the if statement to check, if you are currently on the last section
Try this -
var $previousSection=$(".list-0").show();
$('#accept').on('change',function() {
if($(this).is(":checked")){
$previousSection.hide();
$previousSection = $previousSection.next("section").show();
}
});
DEMO
You need to store the current visible in a variable. Then show the next one and hide the current one. This is more efficient than finding the visible one again.
You can also store the section you are showing next so you know when you have reached the end:
$('#accept').on('click',function() {
var vis = $('.visible');
var hid = vis.next('.hidden').removeClass('hidden').addClass('visible');
$('#accept').prop('checked', false);
// if we showed something (not at the end yet), hide the current visible one
if(hid.length > 0) {
vis.removeClass('visible').addClass('hidden');
}
});
.visible {
display:block;
}
.hidden {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div class="list">
<section class="visible list-0">0</section>
<section class="hidden list-1">1</section>
<section class="hidden list-2">2</section>
<section class="hidden list-3">3</section>
<!-- unknown amount of sections -->
</div>
<input type="checkbox" id="accept" value="1" required/>
use count on checkbox value
here is the working fiddle with the condition of upto 25
$('#accept').on('click',function() {
var count_sections = $('.list > section').length;
var count = $(this).val();
if(count > 25)
{
return false;
}
$('.list-'+count).removeClass('visible').addClass('hidden');
count++;
$('.list-'+count).removeClass('hidden').addClass('visible');
$(this).val(count);
// this should uncheck the checkbox
$('#accept').attr('checked', false);
});
here is the html
<div class="list">
<section class="visible list-0">1st</section>
<section class="hidden list-1">2nd</section>
<section class="hidden list-2">3rd</section>
<section class="hidden list-3">4th</section>
<!-- unknown amount of sections -->
</div>
working example
jsfiddle.net/dr8Ln350/

Am using Push() array was used am trying to use for select a list from drop down menu and post that list into a span?

HTML section
div to show the values
<div class="lef rightCol n">
<span class="para"> add-on Services(Optional)</span>
<div class="new">
<ul>
</ul>
</div>
</div
div that contain drop down
<div class="rightCol n mar ">
<span id="at1" class="spn">Click here to add add-on Services</span>
<ul id="ad1" class="drpdwn">
<li><input type="checkbox" id="ck1" value="1"><a id="a1">Drop Shadows</a></
li>
<li><input type="checkbox" id="ck2" value="2"><a id="a2">Reflections</a> <
li>
<li><input type="checkbox" id="ck3" value="6">General Spotting</a></li>
</ul>
I have tried this slide down while click
jQuery
slide down while click at1(Span)
this is the try for show on span on new div
here where should i use Push() most of them force me to use i don't know how and for what
var ots = [];
$('#at1,#at2,#at3,#at4,#at5,#at6').click(function(){
$(this).next('.drpdwn').stop().slideToggle();
}),
$('#ck1').click(function()
{
option=$('#a1').text();
$('.new ul').append('<li><span id="span1" alt="1" ></span></li>');
$('#span1').html(option).addClass('surr');
ots.push({id: 1});
}),
$('#ck2').click(function()
{
option=$('#a2').text();
$('.new ul').append('<li><span id="span2" alt="1" ></span></li>');
$('#span1').html(option).addClass('surr');
ots.push({id: 2});
}),
now i moved some value to array ots while append now the question is how to retrieve the newly created span's alt atrribute using array..?am using like these its not working clearly
some function
var f = $('.new span').length;
ad=o;
cs=o;
for(i=1;i<=f;i++)
{
$.each(this.opt, function() {
$.each(this, function(name, value) {
cs=eval($( "#span"+value).attr("alt"));
console.log(name + '=' + value);
ad+=cs;
console.log("ad: "+ad);
})
})
}
it shows ad as Nan and every time i click those id's it created like 1 then 1,2 then 1,2,3 like this help me out every time select check box it plays like this.!
push method is used to add new item in an array...so in your code push() was obivously used to push items to array(though i cannot find push methods in your question...so wouldn't be able to explain in your case)
docs
ex:
var sports = ["soccer", "baseball"];
sports.push("football", "swimming");

Categories