Prevent option from being disabled in the current selector - javascript

When trying to submit my form, the guard[] field doesn't submit because the options in the select fields are disabled on submit.
The code I'm working with disables the option across all selects once chosen, but I'm looking for a way to keep it enabled for the one it was selected with (i.e. if I choose "Dingo" in the first select option in the guard[] name, then the 1st select will have Dingo enabled while the 2nd and 3rd selects will have it disabled.) Code attached below.
I'm either looking for a way to get the element ID from the TagName (as seen in my code comment) or a way to re-enable the disabled option before the form is submitted.
JS/JQ:
function disableGuards(selectOption)
{
var selectedGuards = [];
var allGuards = document.getElementsByName("guard[]");
var editedSelect = selectOption.id;
for (var i = 0; i < allGuards.length; i++)
{
selectedGuards.push(allGuards[i].value);
}
for (var i = 0; i < allGuards.length; i++)
{
var options = allGuards[i].getElementsByTagName("option");
for (var o = 1; o < options.length; o++)
{
var val = options[o].value;
var chosen = selectedGuards.indexOf(val);
var myvalue = allGuards[i].value;
options[o].disabled = (chosen != -1 && val != (myvalue && "NONE") /*&& editedSelect != a way to get the elementId from TagName*/);
}
}
if (document.getElementById("guard1").value == "RAND")
{
document.getElementById("guard2").disabled = true;
document.getElementById("guard3").disabled = true;
}
else
{
document.getElementById("guard2").disabled = false;
document.getElementById("guard3").disabled = ((document.getElementById("guard2").value == "NONE") ? true : false);
}
}
HTML:
<select name='guard[]' style='width:100%' id='guard1' onChange='disableGuards(this)'>
<option selected disabled>1st Choice...</option>
<option value='RAND'>No Preferences, Please Assign an Instructor</option>
<option value='Dingo'>Dingo</option>
<option value='Mike'>Mike</option>
<option value='Stephanie'>Stephanie</option>
<option value='Zach'>Zach</option>
</select>
<br>
<select name='guard[]' style='width:100%' id='guard2' onChange='disableGuards(this)'>
<option selected disabled>2nd Choice...</option>
<option value='NONE'>No 2nd Preference</option>
<option value='Dingo'>Dingo</option>
<option value='Mike'>Mike</option>
<option value='Stephanie'>Stephanie</option>
<option value='Zach'>Zach</option>
</select>
<br>
<select name='guard[]' style='width:100%' id='guard3' onChange='disableGuards(this)'>
<option selected disabled>3rd Choice...</option>
<option value='NONE'>No 3rd Preference</option>
<option value='Dingo'>Dingo</option>
<option value='Mike'>Mike</option>
<option value='Stephanie'>Stephanie</option>
<option value='Zach'>Zach</option>
</select>

Find all options which are selected, then remove the disabled keyword
Vanilla Javascipt
document.getElementById("#testform").addEventListener("submit",function (e) {
var options = e.querySelector("option:checked"), option, i;
for(i = 0; option = options[i]; i++) {
option.removeAttribute("disabled");
}
}, false);
jQuery
$("#testform").submit(function () {
$('option:selected', this).removeProp("disabled");
});

Following code should work:
$(document).ready(function() {
$('#your-form-id').submit(function() {
$(this).find('option:disabled').prop('disabled', false);
return true;
});
});
Working fiddle here.

In your loop you could add a condition: if(selectOption !== allGuards[i]) { // disable }, which would leave the option enabled for the select that triggered the handler.
function disableGuards(selectOption)
{
var allGuards = document.getElementsByName("guard[]");
for (var i = 0; i < allGuards.length; i++)
{
if(allGuards[i] === selectOption) {
continue;
}
var options = allGuards[i].getElementsByTagName("option");
for (var o = 1; o < options.length; o++)
{
if(options[o].value === selectOption.value) {
options[o].disabled = true;
}
}
}
if (document.getElementById("guard1").value == "RAND")
{
document.getElementById("guard2").disabled = true;
document.getElementById("guard3").disabled = true;
}
else
{
document.getElementById("guard2").disabled = false;
document.getElementById("guard3").disabled = ((document.getElementById("guard2").value == "NONE") ? true : false);
}
}
<select name='guard[]' style='width:100%' id='guard1' onChange='disableGuards(this)'>
<option selected disabled>1st Choice...</option>
<option value='RAND'>No Preferences, Please Assign an Instructor</option>
<option value='Dingo'>Dingo</option>
<option value='Mike'>Mike</option>
<option value='Stephanie'>Stephanie</option>
<option value='Zach'>Zach</option>
</select>
<br>
<select name='guard[]' style='width:100%' id='guard2' onChange='disableGuards(this)'>
<option selected disabled>2nd Choice...</option>
<option value='NONE'>No 2nd Preference</option>
<option value='Dingo'>Dingo</option>
<option value='Mike'>Mike</option>
<option value='Stephanie'>Stephanie</option>
<option value='Zach'>Zach</option>
</select>
<br>
<select name='guard[]' style='width:100%' id='guard3' onChange='disableGuards(this)'>
<option selected disabled>3rd Choice...</option>
<option value='NONE'>No 3rd Preference</option>
<option value='Dingo'>Dingo</option>
<option value='Mike'>Mike</option>
<option value='Stephanie'>Stephanie</option>
<option value='Zach'>Zach</option>
</select>

Related

javascript select alphabetically sorting

I am trying to sort option alphabetically
My Html is
<select id="myOpt">
<option value="" selected data-default>Select Name</option>
<option value="3">John Snow</option>
<option value="34">Arya Stark</option>
<option value="54">Sansa Stark</option>
<option value="4">Hound</option>
</select>
js
var options = $("#myOpt option");
options.detach().sort(function(a,b) {
var at = $(a).text();
var bt = $(b).text();
return (at > bt)?1:((at < bt)?-1:0);
});
options.appendTo("#myOpt");
it sorts option correctly but now instead of selected option it shows last option. My question is how to show selected option instead of last option and can it be done by another client side method? since for big list it making page slow
Try this,
var options = $("#myOpt option");
var selectedVal = '';
options.detach().sort(function(a,b) {
var at = $(a).text();
var bt = $(b).text();
if($(a).attr('selected') || $(b).attr('selected')){
selectedVal = $(a).attr('selected') ? $(a).val() : $(b).val();
return false;
}
return (at > bt)?1:((at < bt)?-1:0);
});
options.appendTo("#myOpt");
$('#myOpt').val(selectedVal);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
<option value="" selected data-default>Select Name</option>
<option value="3">John Snow</option>
<option value="34">Arya Stark</option>
<option value="54">Sansa Stark</option>
<option value="4">Hound</option>
</select>
Don't select the 1st option to sort. var options = $("#myOpt option:not(:eq(0))");
You may use web workers to avoid browser frize if this a big list.
also, you can put it inside setTimeout to push it in event loop
$(function() {
var options = $("#myOpt option:not(:eq(0))");
options.detach().sort(function(a, b) {
var be = $(b);
var ae = $(a);
if (be.attr('selected')) {
selectedVal = be.val();
return 1;
}
if (ae.attr('selected')) {
selectedVal = ae.val();
return -1;
}
var at = ae.text();
var bt = be.text();
return (at > bt) ? 1 : ((at < bt) ? -1 : 0);
});
options.appendTo("#myOpt");
$("#myOpt").val(selectedVal);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
<option value="" selected data-default>Select Name</option>
<option value="3">John Snow</option>
<option value="34">Arya Stark</option>
<option value="54">Sansa Stark</option>
<option value="4">Hound</option>
</select>
$(function() {
var options = $("#myOpt option");
options.detach().sort(function(a, b) {
var be = $(b);
var ae = $(a);
if (be.attr('selected')) {
selectedVal = be.val();
return 1;
}
if (ae.attr('selected')) {
selectedVal = ae.val();
return -1;
}
var at = ae.text();
var bt = be.text();
return (at > bt) ? 1 : ((at < bt) ? -1 : 0);
});
options.appendTo("#myOpt");
$("#myOpt").val(selectedVal);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
<option value="" selected data-default>Select Name</option>
<option value="3">John Snow</option>
<option value="34">Arya Stark</option>
<option value="54">Sansa Stark</option>
<option value="4">Hound</option>
</select>
To do the sort using native JavaScript may actually give you somewhat more readable code, while taking advantage of operations (like shift/unshift) that jQuery does not implement.
The selection issue is occurring because an option detached from it's parent select cannot be selected - so you need to either select the first option again.
document.addEventListener("DOMContentLoaded", function() {
var options = $("#myOpt option").detach()
options = $.makeArray(options);
var first = options.shift();
options.sort( (a,b) => a.text.localeCompare(b.text) );
options.unshift(first);
$("#myOpt").append(options);
$("#myOpt option").eq(0).prop("selected", true)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
<option value="" selected data-default>Select Name</option>
<option value="3">John Snow</option>
<option value="34">Arya Stark</option>
<option value="54">Sansa Stark</option>
<option value="4">Hound</option>
</select>
You may want to simply just leave the selected element alone and just detach/sort the others, which ends up being quite a bit simpler:
document.addEventListener("DOMContentLoaded", function() {
var options = $("#myOpt option").not('[value=""]').detach();
options.sort( (a,b) => a.text.localeCompare(b.text) );
$("#myOpt").append(options);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="myOpt">
<option value="" selected data-default>Select Name</option>
<option value="3">John Snow</option>
<option value="34">Arya Stark</option>
<option value="54">Sansa Stark</option>
<option value="4">Hound</option>
</select>

Hiding an option if its selected in the other select box JavaScript

I want to hide the option in the selection box if the option is already selected in another box. I am not sure where the problem is in my code, I tried running it on different editors it didn't work. Here is my code:
<html>
<head>
<title>Currency Converter</title>
</head>
<body>
<script langauge="javascript">
function CheckDropDowns() {
ListOfSelectedCountires = [];
for (CountryNumber = 0; CountryNumber < 3; CountryNumber++) {
ListOfSelectedCountires[CountryNumber] = document.getElementById("country" + (CountryNumber + 1)).value;
}
for (algoritmCountryNumber = 0; algoritmCountryNumber < 3; algoritmCountryNumber++) {
for (countryOptions = 1; countryOptions < 5; countryOptions++) {
document.getElementById("country" + (algoritmCountryNumber + 1)).options[countryOptions].style.display = "block";
for (processedOption = 0; processedOption < 3; processedOption++) {
if (document.getElementById("country" + (algoritmCountryNumber + 1).options[countryOptions].value == ListOfSelectedCountires[processedOption]) {
document.getElementById("country" + (algoritmCountryNumber + 1)).options[countryOptions].style.display = "none";
}
}
}
}
}
</script>
<section>
<select id="country1" onchange="CheckDropDowns()">
<option value="">Choose</option>
<option value="1">Australia</option>
<option value="2">Indonesian Rupiah</option>
<option value="3">Chinese Yaun</option>
<option value="4">Japanese Yen</option>
</select>
Convert to
<select id="country2" onchange="CheckDropDowns()">
<option value="">Choose</option>
<option value="1">Australia</option>
<option value="2">Indonesian Rupiah</option>
<option value="3">Chinese Yaun</option>
<option value="4">Japanese Yen</option>
</select>
</section>
</body>
</html>
First determine which select needs to be filtered, then loop through the options setting display to block first(to undo the previous filter), and then if the option's value matches the selected value set it's display to none.
Edit
Above method does not work in every browser. The better HTML5 way is to set and remove the hidden attribute. I've updated the snippet.
window.CheckDropDowns = function(thisSelect) {
var otherSelectId = ("country1" == thisSelect.id) ? "country2" : "country1";
var otherSelect = document.getElementById(otherSelectId);
for (i = 0; i < otherSelect.options.length; i++) {
//otherSelect.options[i].style.display = 'block';
otherSelect.options[i].removeAttribute('hidden');
if (otherSelect.options[i].value == thisSelect.value) {
//otherSelect.options[i].style.display = 'none';
otherSelect.options[i].setAttribute('hidden', 'hidden');
}
}
}
<section>
<select id="country1" onchange="CheckDropDowns(this)">
<option value="">Choose</option>
<option value="1">Australia</option>
<option value="2">Indonesian Rupiah</option>
<option value="3">Chinese Yaun</option>
<option value="4">Japanese Yen</option>
</select>
Convert to
<select id="country2" onchange="CheckDropDowns(this)">
<option value="">Choose</option>
<option value="1">Australia</option>
<option value="2">Indonesian Rupiah</option>
<option value="3">Chinese Yaun</option>
<option value="4">Japanese Yen</option>
</select>
</section>
I don't know what's wrong with your code, the logic seems convoluted. You can't reliably hide options by setting their display to 'none', in some browsers they remain visible. If it was that simple, life would be easy.
You can hide options by removing them from the list, but then you have to remember where they came from so you can put them back when the selection changes.
In the following, each time an option is selected, if there's one stored it's put back and the one matching the selected option is removed. If the first option is selected, the stored one is just put back, nothing is removed.
This only depends on the two selects having the same class value, they could be related by some other value (e.g. a data-* property).
Hopefully the comments are sufficient.
var matchSelected = (function() {
// Store for "hidden" node
var nodeStore = {
sourceElement: null,
node: document.createDocumentFragment(),
index: null
};
return function(evt) {
// Get the element that got the event
var tgt = this;
// If there's a stored option, put it back
if (nodeStore.sourceElement) {
let sel = nodeStore.sourceElement;
sel.insertBefore(nodeStore.node.firstChild, sel.options[nodeStore.index]);
nodeStore.sourceElement = null;
nodeStore.node = document.createDocumentFragment();
nodeStore.index = null;
}
// If the selected option is the first one, stop here
if (tgt.selectedIndex == 0) return;
// Get all selects with the same className
var sels = document.querySelectorAll('.' + this.className);
// Get the "other" option
var other = sels[0] == this ? sels[1] : sels[0];
// Remove and keep the option on the other element that is the same
// as the selected option on the target element
nodeStore.sourceElement = other;
nodeStore.index = tgt.selectedIndex;
nodeStore.node.appendChild(other.options[tgt.selectedIndex]);
}
}());
window.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.countrySelect').forEach(
node => node.addEventListener('change', matchSelected, false)
);
}, false);
<select id="country1" class="countrySelect">
<option value="" selected>Choose</option>
<option value="1">Australia Dollar</option>
<option value="2">Indonesian Rupiah</option>
<option value="3">Chinese Yaun</option>
<option value="4">Japanese Yen</option>
</select>
Convert to
<select id="country2" class="countrySelect">
<option value="" selected>Choose</option>
<option value="1">Australia Dollar</option>
<option value="2">Indonesian Rupiah</option>
<option value="3">Chinese Yaun</option>
<option value="4">Japanese Yen</option>
</select>

Display items of drop down based on each other

1) I have two drop downs with exactly the same values. I want the drop down 2 to display the values based on the selection of items of drop down 1. So the selected index of drop down 2 will be equal to or more than the selected index of drop down 1. ( this code is working)
but When I add one more drop down and based on its items the other two dropdowns should behave as:
2) If I select TCD in the first Dropdown and change to value B in the second dropdown the value should be B in the third dropdown too but If I select BCD from the first dropdown it should retain the values of other two dropdown from the previous selection.( should not go back to A)
The first part is working but the second part is having issues.
Fiddle : 1) http://jsfiddle.net/wtLm4805/2/
Fiddle with three dropdowns : 2) http://jsfiddle.net/wtLm4805/3/
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
for (var i = 0; i < select1.options.length; i++) {
var o = document.createElement("option");
o.value = select1.options[i].value;
o.text = select1.options[i].text;
(i < select1.selectedIndex)
? o.disabled = true
: o.disabled = false ;
select2.appendChild(o);
}
Where am I going wrong ?
You can go somewhere along these lines
var typeValue = 'TCD'; // default initialisation
$('#Type').change(function(){
var value = $(this).val();
console.log(value);
if(value == 'TCD')
{
typeValue = 'TCD';
// change something in other selects too
}
else if(value == 'MCD')
{
typeValue = 'MCD';
}
else if(value == 'BCD')
{
$('#SELECTA').val('B');
$('#SELECTB').val('B');
typeValue = 'BCD';
}
});
$('#SELECTA').change(function(){
var value = $(this).val();
console.log(value);
if(typeValue = 'TCD')
{
$('#SELECTB').val(value);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<select name="Type" id="Type" >
<option value="TCD">TCD</option>
<option value="MCD" >MCD</option>
<option value="BCD" >BCD</option>
</select>
<select id="SELECTA" class="SELECTA">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
<select id="SELECTB" class="SELECTB" >
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
Since you have only one element with class SELECTA and one with class SELECTB, these will always be undefined:
var select1 = document.getElementsByClassName("SELECTA")[1];
var select2 = document.getElementsByClassName("SELECTB")[1];
var select1 = document.getElementsByClassName("SELECTA")[2];
var select2 = document.getElementsByClassName("SELECTB")[2];
If you're trying to target the options, you could move the classes to the options themselves, or you could reference them like this:
document.getElementsByClassName("SELECTA")[0].options[1]
Not sure why you're deleting/adding items to the SELECTB element, but is this what you're going for?
function clickButton() {
var Type= document.getElementById('Type');
var select1= document.getElementById('SELECTA');
var select2= document.getElementById('SELECTB');
if(Type.value === 'TCD') {
for(var i = 0 ; i < select1.options.length ; i++) {
select2.options[i].disabled= i < select1.selectedIndex;
}
select2.value= select1.value;
}
else {
for(var i = 0 ; i < select2.options.length ; i++) {
select2.options[i].disabled= false;
}
}
}
<select name="Type" id="Type" onchange="clickButton()">
<option value="TCD">TCD</option>
<option value="MCD">MCD</option>
<option value="BCD">BCD</option>
</select>
<select id="SELECTA" onchange="clickButton()">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
<select id="SELECTB">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>

Can I pass multiple Id's inside a document.getelementbyID?

I have a form which has got 45 dropdownlist and I m using the bottom code for its
validation.
how can I use only one function of bottom code to do validation for all of my 45 dropdownlist ??
Here is the Function
function Validate()
{
var e = document.getElementById("dropdownlistone");
var strUser = e.options[e.selectedIndex].value;
var strUser1 = e.options[e.selectedIndex].text;
if(strUser==0)
{
alert("Please select a user");
}
}
----- HTML CODE
<select id="dropdownlistone">
<option value="0">Select</option>
<option value="1">test1</option>
<option value="2">test2</option>
<option value="3">test3</option>
</select>
<input type="button" onClick="Validate()" value="select"/>
This is a case when you need to use classes. Then use querySelectorAll method:
function Validate() {
var e = document.querySelectorAll(".dropdownlistone");
for (var i = 0; i < e.length; i++) {
var strUser = e[i].options[e[i].selectedIndex].value;
var strUser1 = e[i].options[e[i].selectedIndex].text;
if (strUser == 0) {
alert("Please select a user");
return;
}
}
}
Demo: http://jsfiddle.net/cwNaH/
And here is one more example with more user friendly validation messages: http://jsfiddle.net/cwNaH/1/
You can use DOM Method getElementsByTagName for select box and set an data-attr to "validate" for those whom you want to validate, if you dont want it to be validate simply don't add the above mentioned attribute.
Ex. HTML
<select id="sel1" data-attr="validate">
<option value="0">Select</option>
<option value="1">test1</option>
<option value="2">test2</option>
<option value="3">test3</option>
</select>
<select id="sel2" data-attr="validate">
<option value="0">Select</option>
<option value="1">test1</option>
<option value="2">test2</option>
<option value="3">test3</option>
</select>
JavaScript
function validate()
{
var ele = document.getElementsByTagName("select");
for(var i=0;i<ele.length;i++)
{
if(ele.getAttribute("data-attr") && ele.getAttribute("data-attr")=='validate')
{
// you have all 47 select boxes whoose data-attr is validate
// each select box will be in ele[i]
var value= ele[i].options[ele[i].selectedIndex].value;
var text= ele[i].options[ele[i].selectedIndex].text;
alert( value+ " : " + text);
}
}
}

Code where <select> changes options in another <select>

I have made same code in Javascript that will change options in drop-down list of cities when user changes state.
The problem with the code is that it won't work. I think that code is OK, but I am very new in JavaScript, so I can't see the error.
Can you please check my code and see where I made error. Thanks.
JavaScript:
function drzava_promjena() {
var obj_state = document.getElementById("id_drzava")
var index = obj_states.selectedIndex;
var value_state = obj_state.options[index].value;
towns = town_list[value_state];
var obj_town = document.getElementById("id_gradovi");
while (obj_town.options.length > 0) {
obj_town.remove(0);
}
var new_value;
for (var i = 0; i < towns.length; i++) {
new_value = document.createElement("option");
new_value.value = towns[i];
new_value.text = towns[i];
try {
obj_town.add(new_value);
} catch (e) {
obj_town.appendChild(new_value);
}
}
And this is HTML:
<select id="id_drzava" onchange="drzava_promjena(this);">
<option value="Austrija">Austrija</option>
<option value="Njemacka">Njemacka</option>
<option value="Slovenija">Slovenija</option>
<option value="Ceska">Ceska</option>
</select>
<br>
<select id="id_gradovi" onchange="">
<option value="0"></option>
</select>
<br>
<select id="id_uni" onchange="">
<option></option>
</select>
Try the following code. I've also put up a fiddle to demonstrate.
JavaScript:
var populateCities = function (country, target_id) {
var i = 0, options, cities, selection, target;
cities = {
"usa": {
"dallas": "dal",
"san francisco": "sf",
"houston": "hou"
},
"fr": {
"paris": "pr",
"la riche": "lr"
}
};
selection = country.options[country.selectedIndex].value;
target = document.getElementById(target_id);
target.options.length = 0;
if(selection !== 'none') {
options = cities[selection];
for(var city in options) {
target.options[i] = new Option(city, options[city]);
i++;
}
}
}​
HTML:
<select id="country" onchange="populateCities(this, 'cities')">
<option selected value="none">Pick a country</option>
<option value="usa">USA</option>
<option value="fr">France</option>
</select>
<select id="cities"></select>

Categories

Resources