Hide all DIVs that don't contain all specified classes - javascript

On my page I have a large number of DIVs, each DIV represents a specific product, with a series of characteristics. I'm using those characteristics as classes, so every product would start similarly to this:
<div class='classA classB classC classD classE classF'>
Product Card
</div>
Ideally on my page I'd like to have one <select> element for each class, so that when the user select a value from the dropdown, only the <div> with the corresponding class remains displayed on the page, while all the others are hidden.
Also, the check on the class has to consider ALL the classes at the same time. By this I mean that if a user selects value from 3 dropdowns, only the <div> that have ALL the 3 classes selected will be shown.
I've tried to implement this idea using javascript, with the following code:
function filterPowerInput() {
var powerInput = document.getElementById("powerInput").value;
if (powerInput == 1) {
var myClasses = document.querySelectorAll('.ph3ph'),
i = 0,
l = myClasses.length;
for (i; i < l; i++) {
myClasses[i].style.display = 'none';
}
var myClassesTwo = document.querySelectorAll('.ph1ph'),
i = 0,
l = myClassesTwo.length;
for (i; i < l; i++) {
myClassesTwo[i].style.display = 'block';
}
} else if (powerInput == 3) {
var myClasses = document.querySelectorAll('.ph1ph'),
i = 0,
l = myClasses.length;
for (i; i < l; i++) {
myClasses[i].style.display = 'none';
}
var myClassesTwo = document.querySelectorAll('.ph3ph'),
i = 0,
l = myClassesTwo.length;
for (i; i < l; i++) {
myClassesTwo[i].style.display = 'block';
}
} else {
var myClasses = document.querySelectorAll('.ph1ph'),
i = 0,
l = myClasses.length;
for (i; i < l; i++) {
myClasses[i].style.display = 'block';
}
var myClassesTwo = document.querySelectorAll('.ph3ph'),
i = 0,
l = myClassesTwo.length;
for (i; i < l; i++) {
myClassesTwo[i].style.display = 'block';
}
}
}
This example works fine for a class that can only assume 2 values, but it becomes impossible to manage as soon as a class has many more value (they could go up to 12). Also, by using similar version of the code above on different dropdowns, they will override each other, I haven't found a way yet to make them work together as I need.
I hope it's clear enough, otherwise just ask. Thanks a lot for your time as always!
(The rest of my page is a mix of PHP/HTML/Javascript)

I think this is what you meant
$(function() {
$(".sel").on("change",function() {
var classLst = ["selDiv"];
$(".sel").each(function() {
var val = this.value;
if (val) classLst.push("class"+val);
});
classLst.sort();
$(".selDiv").each(function() {
var divClassLst = $(this).attr("class");
if (divClassLst) {
$(this).toggle(divClassLst.split(" ").sort().join(".") == classLst.join("."));
}
})
}).change(); // run when loaded
});
.selDiv { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b>Note: Possible combinations: </b><i>A,B,C; D,E</i> and <i>C,D</i>
<hr/>
<select class="sel">
<option value="">Please select</option>
<option value="A" selected>A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<select class="sel">
<option value="">Please select</option>
<option value="A">A</option>
<option value="B" selected>B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<select class="sel">
<option value="">Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C" selected>C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<select class="sel">
<option value="">Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<select class="sel">
<option value="">Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<div class='selDiv classA classB classC'>
Product Card A B C
</div>
<div class='selDiv classD classE'>
Product Card D E
</div>
<div class='selDiv classC classD'>
Product Card C D
</div>

Something far more important than answer to your question. I know it's not an answer but I had to show the importance of this matter.
As a developer if you write a block of the same code more than once - something is not right. Why not simply writing a function that does the same procedure?
var customtog = function(cls, dis){
var myClasses = document.querySelectorAll(cls),
i = 0,
l = myClasses.length;
for (i; i < l; i++) {
myClasses[i].style.display = dis;
}
}
So look how your code is gonna look now:
Far more easier to follow and maintain.
if(powerInput == 1)
{
customtog('.ph3ph', 'none');
customtog('.ph1ph', 'block');
}
else if(powerInput == 3)
{
customtog('.ph1ph', 'none');
customtog('.ph3ph', 'block');
}
else
{
customtog('.ph1ph', 'block');
customtog('.ph3ph', 'block');
}
Update - Following #mplungjan comment
customtog('.ph3ph', powerInput==1?'none':'block');
customtog('.ph1ph', powerInput==1?'block':'none');

Related

Multiple Select Unselect And Disabled

I Have 2 Multiple Select Field On My Code
I Want Make If All Selected Then Other Option Will Be Unselect And Disabled And Similarly If Other Any Field Selected Then All Option Will Unselect And Disabled
My Code Is
<select multiple name="device[]" id="device" class="form-control" >
<option value=\'ALL\' selected="selected">ALL</option>
<option value=\'Android\'>Android</option>
<option value=\'iPod\'>iPod</option>
<option value=\'iPad\'>iPad</option>
<option value=\'Java\'>Java</option>
<option value=\'Windows\'>Windows</option>
<option value=\'Linux\'>Linux</option>
<option value=\'Mac\'>Mac</option>
</select>
And
<select multiple name="country[]" id="device" class="form-control" >
<option value=\'ALL\' selected="selected">ALL</option>
<option value=\'BD\'>Bangladesh</option>
<option value=\'IN\'>India</option>
<option value=\'ID\'>Indonesia</option>
<option value=\'NG\'>Naigeria</option>
<option value=\'PK\'>Pakistan</option>
</select>
By disabling an element you say i'll not use this element, I refuse to use this elemen, so disabled elements can not get Mouse Events, so disabling is wrong way.
Instead make it visually disabled.
Here is pure JS code, because i am not like jquery ;)
<style>
select {
height:300px;
width:150px;
}
</style>
<body>
<select multiple name="device[]" id="device" class="form-control" onChange="Go()" >
<option value=\'ALL\' selected="selected">ALL</option>
<option value=\'Android\'>Android</option>
<option value=\'iPod\'>iPod</option>
<option value=\'iPad\'>iPad</option>
<option value=\'Java\'>Java</option>
<option value=\'Windows\'>Windows</option>
<option value=\'Linux\'>Linux</option>
<option value=\'Mac\'>Mac</option>
</select>
<select multiple name="country[]" id="device" class="form-control" onChange="Go()" >
<option value=\'ALL\' selected="selected">ALL</option>
<option value=\'BD\'>Bangladesh</option>
<option value=\'IN\'>India</option>
<option value=\'ID\'>Indonesia</option>
<option value=\'NG\'>Naigeria</option>
<option value=\'PK\'>Pakistan</option>
</select>
<script>
function Go(){
parentElements = document.getElementsByTagName("select");
for(var i = 0; i < parentElements.length; i++){
parentElement = parentElements[i]
children = parentElement.childNodes;
for(var j = 0; j < children.length; j++){
childNode = children[j];
if(childNode.nodeName == "OPTION" || childNode.nodeName == "option"){
if(childNode.value == "\\'ALL\\'" && childNode.selected == true){
for(var k = 0; k < children.length; k++){
if(typeof(children[k].value) !== "undefined" && k != j){
children[k].style.color = "#ccc";
children[k].style.textDecorationLine = "line-through";
children[k].selected = false;
}
if(typeof(children[k].value) !== "undefined" && k == j){
children[k].style.color = "";
children[k].style.textDecorationLine = "";
}
}
}
if(childNode.value != "\\'ALL\\'" && childNode.selected == true){
for(var k = 0; k < children.length; k++){
if(typeof(children[k].value) !== "undefined" && children[k].value == "\\'ALL\\'"){
children[k].style.color = "#ccc";
children[k].style.textDecorationLine = "line-through";
children[k].selected = false;
}
if(typeof(children[k].value) !== "undefined" && children[k].value != "\\'ALL\\'"){
children[k].style.color = "";
children[k].style.textDecorationLine = "";
}
}
}
}
}
}
}
</script>
</body>
EDIT:
How about adding an extra button to reset the menus ?
Please check this fiddle
OLD:
If you are not holding ctrl key then other options will be deselected automatically
$(document).ready(function() {
$('#device, #country').on('change', function() {
var selectedVal = $(this).val();
for (var i = 0; i < selectedVal.length; i++) {
if (selectedVal[i] === 'ALL') {
// $("#device > option").attr('disabled','disabled');
$(this).find('option').attr('disabled', 'disabled');
$(this).find('option[value=ALL]').removeAttr('disabled');
} else {
$(this).find('option[value=ALL]').attr('disabled', 'disabled');
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<select multiple name="device[]" id="device" class="form-control">
<option value='ALL'>ALL</option>
<option value='Android'>Android</option>
<option value='iPod'>iPod</option>
<option value='iPad'>iPad</option>
<option value='Java'>Java</option>
<option value='Windows'>Windows</option>
<option value='Linux'>Linux</option>
<option value='Mac'>Mac</option>
</select>
<select multiple name="country[]" id="country" class="form-control">
<option value='ALL'>ALL</option>
<option value='BD'>Bangladesh</option>
<option value='IN'>India</option>
<option value='ID'>Indonesia</option>
<option value='NG'>Naigeria</option>
<option value='PK'>Pakistan</option>
</select>
$('#device option').click(function(){
var Allselected = $('#device :selected').text();
var AllselectedCountry = $('#country :selected').text();
if(Allselected =="ALL"){
$('#device option:not(:selected)').addClass('ashClass');
}
else if (Allselected !="ALL"){
$('#device option:first-child').css('color', '#ccc');
$('#device option:not(:selected)').removeClass('ashClass');
}
});
$('#country option').click(function(){
var AllselectedCountry = $('#country :selected').text();
if(AllselectedCountry =="ALL"){
$('#country option:not(:selected)').addClass('ashClass');
}
else if (AllselectedCountry !="ALL"){
$('#country option:first-child').css('color', '#ccc');
$('#country option:not(:selected)').removeClass('ashClass');
}
});
.ashClass {
color: #ccc;
}
.blackClass {
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<select multiple name="device[]" id="device" class="form-control" >
<option value=\'ALL\' >ALL</option><option value=\'Android\'>Android</option><option value=\'iPod\'>iPod</option><option value=\'iPad\'>iPad</option><option value=\'Java\'>Java</option><option value=\'Windows\'>Windows</option><option value=\'Linux\'>Linux</option><option value=\'Mac\'>Mac</option> </select>
<select multiple name="country[]" id="country" class="form-control" >
<option value=\'ALL\' >ALL</option><option value=\'BD\'>Bangladesh</option><option value=\'IN\'>India</option><option value=\'ID\'>Indonesia</option><option value=\'NG\'>Naigeria</option><option
value=\'PK\'>Pakistan</option></select>
Updated the codes,Hope this one resolves your problem.
Is this what you are asking?

Disable elements with an option using js

Thanks for all answers, help. Unfortunately i have a new problem. I edited the script a little bit. Now i added 2 new values (named:64) to 2 new options. With these options, i want to disable the options classed -> "test". The code actually works, but now, when i added this new code, the previous code is not working. I think the problem is that i added 2 classes to 1 option, but i am not sure, and i dont know any other way to fix it. I know my troubles are really ridiculous, but i am new in js.
<div class="config">
<select onchange="yesnoCheck(this);">
<option>Not selected</option>
<option value="1151">Intel® Pentium® Processor G4560 3.5 Ghz</option>
<option value="1151">Intel® Core® i3-7300 4 Ghz</option>
<option value="1151">Intel® Core® i5-7500 3.4 Ghz</option>
<option value="AM3">AMD FX-Series FX-6300 3.5Ghz</option>
<option value="AM3">AMD FX-Series FX-8300 3.3Ghz</option>
<option value="AM3">AMD FX-Series FX-8320 3.5Ghz</option>
</select>
<script>
function yesnoCheck(that) {
if (that.value == "1151") {
var option = document.querySelectorAll('option.intel'),
i = 0,
len = option.length;
for (; i < len; i++) {
option[i].disabled = true;
}
var option2 = document.querySelectorAll('option.amd'),
i = 0,
len = option2.length;
for (; i < len; i++) {
option2[i].disabled = false;
}
}
else if (that.value == "AM3") {
var option = document.querySelectorAll('option.amd'),
i = 0,
len = option.length;
for (; i < len; i++) {
option[i].disabled = true;
}
var option2 = document.querySelectorAll('option.intel'),
i = 0,
len = option2.length;
for (; i < len; i++) {
option2[i].disabled = false;
}
}
}
</script>
</div>
<div class="config">
<select onchange="yesnoCheck(this);">
<option>Not selected</option>
<option>Kingston HyperX FURY 8GB</option>
<option>Kingston HyperX FURY 16GB</option>
<option>Kingston HyperX FURY 32GB (2x16GB)</option>
<option value="64">Kingston HyperX FURY 64GB (4x16GB)</option>
</select>
<script>
function yesnoCheck(that) {
if (that.value == "64") {
var option = document.querySelectorAll('option.test'),
i = 0,
len = option.length;
for (; i < len; i++) {
option[i].disabled = true;
}
}
}
</script>
</div>
<div class="config">
<select onchange="yesnoCheck(this);">
<option>Not selected</option>
<option class="intel">ASRock B250M-HDV</option>
<option class="intel">ASUS Z170-K</option>
<option class="intel">GIGABYTE GA-B250M-DS3H</option>
<option class="amd">GIGABYTE GA-970A-UD3P</option>
<option class="amd">GIGABYTE GA-990FXA-UD3 R5 </option>
<option class="test" class="amd">MSI 970A SLI Krait Edition</option>
<option class="test" class="amd">ASUS CROSSHAIR V FORMULA-Z</option>
</select>
</div>
When you select element by class, you have to response an array.
To disable all elements, you should disable for all in the array like this :
replace :
document.getElementsByClassName('amd').disabled = true;
to :
var items = document.getElementsByClassName('amd');
for(var i = 0; i < items.length; i++ ){
items[i].disabled = true;
}
Try this:
<div class="config">
<select onchange="yesnoCheck(this);">
<option value="">Not selected</option>
<option value="1151">Intel® Pentium® Processor G4560 3.5 Ghz</option>
<option value="1151">Intel® Core® i3-7300 4 Ghz</option>
<option value="1151">Intel® Core® i5-7500 3.4 Ghz</option>
<option value="AM3">AMD FX-Series FX-6300 3.5Ghz</option>
<option value="AM3">AMD FX-Series FX-8300 3.3Ghz</option>
<option value="AM3">AMD FX-Series FX-8320 3.5Ghz</option>
</select>
<script>
function yesnoCheck(that) {
var op = document.getElementById("foo").getElementsByTagName("option");
for (var i = 0; i < op.length; i++) {
if (op[i].className == "amd" && that.value == "1151") {
op[i].disabled = true
} else {
op[i].disabled = false;
}
}
}
</script>
</div>
<div class="config">
<select id="foo">
<option class="">Not selected</option>
<option class="intel">ASRock B250M-HDV</option>
<option class="intel">ASUS Z170-K</option>
<option class="intel">GIGABYTE GA-B250M-DS3H</option>
<option class="amd">GIGABYTE GA-970A-UD3P</option>
<option class="amd">GIGABYTE GA-990FXA-UD3 R5 </option>
<option class="amd">MSI 970A SLI Krait Edition</option>
<option class="amd">ASUS CROSSHAIR V FORMULA-Z</option>
</select>
</div>

JavaScript - how to remove `options` by its `value`

I have a dropdown menu with products similiar like this
<select class="fruits" >
<option value="1" >Oranges</option>
<option value="2" >Bananes</option>
<option value="3" >Apples</option>
</select>
I need to remove options by its value. How to do that ?
Pure JavaScript please.
EDIT : I know that I need to use element.removeChild(child) method. But how to reference child by its value. Thats my point.
EDIT 2 : I use the script of zdrohn below and it works. Because I have several fruits dropdowns with the same collection I need to iterate trough all dropdowns and delete it from all dropdowns. This is my code now :
<script type='text/javascript'>
var id = 3;
var el= document.getElementsByClassName("fruits");
for (i=0;i<el.length;i++) {
for(var n = 0; n < el[i].length; n++) {
if(el[i][n].value == id) {
el[i][n].remove();
}
}
</script>
Though it works I wonder about that I do not need to use the parent.removeChild() method. How comes ?
P.S. I wonder that peole vote this question down. As the response shows their are several solutions. Though not all are sufficiantly explained.
Here is a snippet to play with.
The code removes the option with value = 3
window.onload = function() {
var optionToDelete = document.querySelector("select.fruits > option[value='3']");
optionToDelete.parentNode.removeChild(optionToDelete);
}
<select class="fruits">
<option value="1">Oranges</option>
<option value="2">Bananes</option>
<option value="3">Apples</option>
</select>
EDIT: Based on the updated question - I have several fruits drop-downs.
We could make use of querySelectorAll to select all matching elements and forEach to apply the desired logic on each element in the selected list.
window.onload = function() {
var optionsToDelete = document.querySelectorAll("select.fruits > option[value='3']");
optionsToDelete.forEach(function(element, index, array) {
element.parentNode.removeChild(element);
});
}
<select class="fruits">
<option value="1">Oranges</option>
<option value="2">Bananes</option>
<option value="3">Apples</option>
</select>
<select class="fruits">
<option value="1">Seville oranges</option>
<option value="2">Burro Bananes</option>
<option value="3">Baldwin Apples</option>
</select>
<select class="fruits">
<option value="1">Bergamot oranges</option>
<option value="2">Red Bananes</option>
<option value="3">Gravenstein Apples</option>
</select>
<select class="fruits" >
<option value="1" >Oranges</option>
<option value="2" >Bananas</option>
<option value="3" >Apples</option>
</select>
<script type='text/javascript'>
var valueToRemove = 1;
var select = document.getElementsByClassName('fruits');
for(var i = 0; i < select[0].length; i++) {
if(select[0][i].value == valueToRemove) {
select[0][i].remove();
}
}
</script>
Edit:
<select class="fruits" >
<option value="1">Oranges</option>
<option value="2">Bananas</option>
<option value="3">Apples</option>
</select>
<br>
<label>Input value to delete</label><input type='text' id='delete_value'>
<button onclick='remove(document.getElementById("delete_value").value)'>Delete</button>
<script type='text/javascript'>
function remove(item) {
var valueToRemove = item;
var select = document.getElementsByClassName('fruits');
for(var i = 0; i < select[0].length; i++) {
if(select[0][i].value == valueToRemove) {
select[0][i].remove();
}
}
}
</script>
You can select the desired option by using document.querySelector() and a selector of this form
A more complete list of selectors can be found here
Example
var element = document.evaluate( '//option[#value="1"]' ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
element.parentNode.removeChild(element)

Make it 100% of all

I have 3 dropdown boxes, in which there are values of 10 to 100. I want user to select cumulative value of 100 from all dropdown boxes.
Which means, if I select 20 from the first dropdown box the next 2 dropdown should be left with the options of selecting total of 100
What I have done so far is here: CHECK IT HERE (JS FIDDLE)
HTML
<select id="foreign" class="me">
<option value="">Foreign Policy</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30">30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select>
<select id="economy" class="me">
<option value="">Economy Policy</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30">30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select>
<select id="social" class="me">
<option value="">Social Policy</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30">30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select>
<br />
<span id="message"></span>
JavaScript
/*var total = new Array();
$('#foreign option').each(function() {
total.push($(this).val());
});
console.log(total);*/
var total = 100;
var ids = ['foreign', 'social', 'economy'];
var current_selected;
$('.me').change(function() {
current_selected = $(this).attr('id');
var socval = $('#' + current_selected + ' option:selected').val();
total = total - socval;
if ($.inArray($(this).attr('id'), ids) > -1) {
ids.splice($.inArray($(this).attr('id'), ids), 1);
}
for (var i = 0; i < ids.length; i++) {
$('#' + ids[i] + ' option').each(function() {
if ($(this).val() >= total) {
$(this).attr('disabled', true);
} else {
$(this).attr('disabled', false);
}
});
}
if (total <= 0) {
total = 100;
}
console.log(total);
ids.push(current_selected);
});
It is pretty much working, with some minor faults.
UPDATE
I think I solved it.
SOLVED FIDDLE
Thanks who helped.
Regards
Changing:
if ($(this).val() >= total) {
to
if ($(this).val() > total) {
solves the problem of only being able to select upto 90%
Working sample
Update
With regard to changing values, i'd probably take a forward-looking approach and reset the value of the forward selects. Something like:
var selectIds = ['first', 'second', 'third']
$('select').change(function(){
var currentIndex = $.inArray($(this).attr('id'), selectIds);
for(var i = currentIndex + 1; i < selectIds.length; i++)
{
$('#' + selectIds[i]).val("0");
}
});
This basically resets the value of select items in the chain that are further ahead than the current select box being used.
Working example
You'll also want to look ahead when doing the disables. You should only be disabling items in the select lists further down the chain from the current select. The first select list should always be able to choose any value and the following selects filtered based on that. This fits in well with the above approach.
I did another version of your code, plus fixing the bug
http://jsfiddle.net/rzBej/62/
$('.me').change(function() {
var totalSoFar = 0;
$('.me').each(function() {
totalSoFar += +$(this).val();
});
var tmp = 100 - totalSoFar;
$('.me').each(function() {
var $this = $(this);
$this.find('option').each(function() {
$this.prop('disabled', $this.attr('value') > tmp);
});
})
});​

Multiple select in Mobile Safari

I have a multiple select with the first option as "All" and other options. What I'm trying to do is when "All" is selected, A, B, C, D will deselect but A, B, C, D is selected, "All" is unselected.
HTML:
<select name="filter" id="filter-select" multiple="multiple">
<option id="All" value="All">All</option>
<option id="A" value="A">A</option>
<option id="B" value="B">B</option>
<option id="C" value="C">C</option>
<option id="D" value="D">D</option>
<option id="E" value="E">E</option>
<option id="F" value="F">F</option>
<option id="G" value="G">G</option>
<option id="H" value="H">H</option>
</select>
JavaScript:
function UnselectAll() {
var select = document.getElementById('filter-select');
if(select.options[select.selectedIndex].id != 'All' ) {
select[0].selected = false;
} else {
for(var x = 0; x < select.length; x++) {
select[x].selected = false;
}
}
}
document.getElementById('filter-select').addEventListener('change', UnselectAll, false);
My problem is that as you select the options, they will not display the unselection till you scroll out of view within the select box.
Please assist.
Thanks
Small typo - You are clearing 0 together with other options, so one little change will help :
for(var x = 1; x < select.length; x++) {

Categories

Resources