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++) {
Related
I want to make a dropdown menu with the following options. I want be able to select a select multiple value for option A, B, and C, but disable multiple selection if option D is selected. How can I do that? Thanks.
<label>Choose an option:</label>
<select required multiple>
<option>Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">C</option>
</select>
Remove the other selected options if "D" is selected, otherwise allow multiple select (do nothing).
document.addEventListener("mouseup", checkMultiple);
function checkMultiple(evt) {
const selectr = evt.target.closest(`select`);
if (selectr && selectr.querySelector(`[value='D']:checked`)) {
[...selectr.options].forEach(v => v.selected = v.value === `D`);
}
}
/*
Note: the above is a shortened version of
the function in the original answer:
function checkMultiple(evt) {
if (!/option/i.test(evt.target.nodeName)) {
return true;
}
const selector = evt.target.parentNode;
const options = [...selector.querySelectorAll("option")];
if (options.find(v => v.value === "D").selected) {
options
.filter(v => v.value !== "D")
.forEach(v => v.selected = false);
}
}
*/
<label>Choose an option:</label>
<select required multiple>
<option>Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
let arr = [];
document.querySelector('#product_attr_ids').onchange = function(e) {
if (this.querySelectorAll('option:checked').length <= 1) {
arr = Array.apply(null, this.querySelectorAll('option:checked'));
} else {
Array.apply(null, this.querySelectorAll('option')).forEach(function(e) {
e.selected = arr.indexOf(e) > -1;
});
}
}
<p>The html of selections with multiple set to true.</p>
<p>Pressing command + click will not allow you to choose more than one option</p>
<p>Javascript. You can chnage the <strong>('option:checked').length <= 1) </strong> to whatever number you want, peraps you want your users to choose only 2 or 3 options.</p>
<label>Choose an option:</label>
<br />
<select id="product_attr_ids" required multiple>
<!-- Prevent user from select first blank option -->
<option disabled>Please select</option>
<option value="A">Attribute 1</option>
<option value="B">Attribute 2</option>
<option value="C">Attribute 3</option>
<option value="D">Attribute 4</option>
</select>
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');
I am trying to get (or show) values from Multiple Select using only Javascritpt. Let's say, the user can select multiple options from here, and when they click the 'Show Select' button they can see what are the values of these options.
I took the idea about 'selected' attribute from here
But, the code didn't work. Any help?
<select id ="selectOptions" name="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button onclick="myFunction()">Show Selects</button>
<script>
function myFunction()
{
var numOfOptions = document.getElementById("slectOptions").options.length;
var n=0;
for (n=0; n<numOfOptions; n++)
{
// I tried to use a for loop that will go around from option 0 to 3,
//and through 'selected' attribute wanted to check the condition if the option is selected then only show the values
// I still couldn't figure out if the loop is working at all
if (document.getElementById("slectOptions")[n].selected)
{
var x = document.getElementById("slectOptions").value;
window.alert(x);}
}
}
Just use
var select = document.getElementById("selectOptions");
console.log(select.selectedOptions);
Iterate over the options and check checked property. Although there is a simple type in your selector where missing e in the string.
function myFunction() {
var options = document.getElementById("selectOptions").options;
for (var n = 0; n < options.length; n++) {
if (options[n].selected) {
console.log(options[n].value);
}
}
}
<select id="selectOptions" name="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button onclick="myFunction()">Show Selects</button>
Or use readonly selectedOptions property to get the collection of selected options.
function myFunction() {
var options = document.getElementById("selectOptions").selectedOptions;
for (var n = 0; n < options.length; n++) {
console.log(options[n].value);
}
}
<select id="selectOptions" name="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button onclick="myFunction()">Show Selects</button>
<!DOCTYPE html>
<html>
<script>
function eraseText() {document.getElementById("txtChoices").value = "";
}
function SetMulti() {var txtChoices = document.getElementById("txtChoices"); txtChoices.value += document.getElementById("choiceNames").value;
}
</script>
</head>
<body>
<input type="text" id="txtChoices" readonly="readonly" placeholder="Multiple choice"/></br>
"Variable" Choice dropdown:
</br>
<select multiple="" name="choiceNames" id="choiceNames">
<option value="Long, ">Long, </option>
<option value="Short, ">Short, </option>
<option value="Red, ">Red, </option>
<option value="Curly, ">Curly, </option>
<option value="Straight, ">Straight, </option>
</select>
<button onclick="SetMulti()">Add</button>
<button onclick="eraseText()">Reset</button>
</body>
</html>
This question is based on THIS QUESTION
When an option from one of the SELECT boxes were selected, I wanted the rest to be repopulated, without said option, but instead, is there an easy way to loop through all these select items, to ensure the same option hasn't been selected twice?
Thanks.
Person Number 1
<select name="person1">
<option value="null">Please Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
Person Number 2
<select name="person2">
<option value="null">Please Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
Person Number 3
<select name="person3">
<option value="null">Please Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
Basic Overview:
JavaScript loop to ensure none of the options have been selected twice?
<!DOCTYPE html>
<html>
<head>
<script>
function doAction(el) {
for (var i = 0; i < document.getElementById('person2').length; i++) {
var v = (i != el.selectedIndex ? '' : 'disabled');
document.getElementById('person2')[i].disabled = v;
if (document.getElementById('person2').selectedIndex == el.selectedIndex)
document.getElementById('person2').selectedIndex = 0;
document.getElementById('person3')[i].disabled = v;
if (document.getElementById('person3').selectedIndex == el.selectedIndex)
document.getElementById('person3').selectedIndex = 0;
}
}
</script>
</head>
<body>
Person Number 1
<select id="person1" onchange="doAction(this)" >
<option value="null">Please Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<br/>
Person Number 2
<select id="person2">
<option value="null">Please Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<br/>
Person Number 3
<select id="person3">
<option value="null">Please Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</body>
</html>
If you use
var x = document.getElementByName('person1').value;
var y = document.getElementByName('person2').value;
var z = document.getElementByName('person3').value;
you can get the values. Then, you have 3 items, to compare against all of them you just have to do 3 checks:
if(x == y || x == z || y == z){
...
}
Or you could throw all of the values into an array, and then splice out the first occurrence, and then check to see if it occurs again.
//get all selects
var selects = document.getElementsByTagName('select');
var setOfPeople = [];
for(i in selects){
setOfPeople[i] = selects[i].name;
}
var selections = [];
//put everything in an array
for(i in setOfPeople){
selections[i] = document.getElementByName(setOfPeople[i]).value;
}
for(i in setOfPeople){
var val = document.getElementByName(setOfPeople[i]).value;
//make sure the element is in the selection array
if(selections.indexOf(val) != -1){
//rip out first occurrence
selections.splice(selections.indexOf(val), 1);
}
//check for another occurrence
if(selections.indexOf(val) != -1){
...
}
}
I am creating a website where their are 4 identical dropdown menu's, each dropdown menu has got 10 options. But each of those options can only be selected in one of the dropdown menu's.
So for example:
When I select option 1 in this dropdown menu.
<select name="select1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">2</option>
<option value="4">4</option>
</select>
I can't select it in this one. So it should say disabled in option one.
<select name="select2">
<option value="1" //disabled >1</option>
<option value="2">2</option>
<option value="3">2</option>
<option value="4">4</option>
</select>
I don't know how to do it myself so I would be very glad if someone could help me.
To provide a better user experience, you should disable the items using JavaScript when the user selects something in a drop down. Are you using jQuery by any chance?
You should also enforce it on the server because as a general rule, clients are not to be trusted.
If I understand you correctly, what you are trying to achieve is better done via checkboxes.
Instead of <select> do this:
<input type="checkbox" name="1" value="1">option1<br>
<input type="checkbox" name="2" value="2">option2 <br> ...
The code below does what you are asking. I also made a jsfiddle
It will correctly disable and enable options as options from ANY of the select inputs are changed.
The javascript
<script type="text/javascript">
// *** EDIT THIS ***
var selectIds = new Array('select1', 'select2', 'select3', 'select4'); // all of the select input id values to apply the only one option value anywhere rule against
function process_selection(theObj){
var allSelectedValues = new Array(); // used to store all currently selected values
// == get all of the currently selected values for all the select inputs
for (var x=0; x<selectIds.length; x++){
var v = document.getElementById(selectIds[x]).value; // the value of the selected option for the select input currently being looked at in the loop (selectIds[x])
// if the selected option value is not an empty string ..
if(v!==""){
// store the value of the selected option and it's associated select input id value
allSelectedValues[v] = selectIds[x];
}
}
// == now work on each option within each select input
for (var x=0; x<selectIds.length; x++){
// loop thru all the options of this select input
var optionObj = document.getElementById(selectIds[x]).getElementsByTagName("option");
for (var i = 0; i < optionObj.length; i++) {
var v = optionObj[i].value; // the value of the current option in the iteration
// only worry about option values that are not an empty string ("")
if(v!==""){
if(allSelectedValues[v]){
if(allSelectedValues[v] && allSelectedValues[v] != selectIds[x]){
// disable this option because it is already selected
// and this select input is NOT the one that it is selected in
optionObj[i].disabled = true;
}
}else{
// enable this option because it is not already selected
// in any of the other select inputs
optionObj[i].disabled = false;
}
}
} // end for (option loop)
} // end for (select loop)
} // end func
</script>
The HTML that works with the above
But really the code above will work with any select inputs on your page by editing the one line indicated in the js code above
<select name="select1" id="select1" onchange="process_selection(this)">
<option value="">-- choose one --</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select name="select2" id="select2" onchange="process_selection(this)">
<option value="">-- choose one --</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select name="select3" id="select3" onchange="process_selection(this)">
<option value="">-- choose one --</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select name="select4" id="select4" onchange="process_selection(this)">
<option value="">-- choose one --</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
As others have mentioned, it is a cleaner way to do it in checkboxes. However, just to improve my JavaScript skills, I came up with something that should answer what you asked for:
var boxes, i, disableOthers;
boxes = document.getElementsByTagName('select');
disableOthers = function () {
'use strict';
var i, j, k, selectedValues = [],
options;
for (i = 0; i < boxes.length; i += 1) {
selectedValues.push(boxes[i].value);
for (j = 0; j < boxes.length; j += 1) {
if (boxes[j] !== boxes[i]) {
options = boxes[j].querySelectorAll('option');
for (k = 0; k < options.length; k += 1) {
options[k].disabled = (selectedValues.indexOf(options[k].value) > -1);
}
}
}
}
};
for (i = 0; i < boxes.length; i += 1) {
boxes[i].addEventListener('change', disableOthers, false);
}
See jsFiddle