I have a form with 4 dependent select dropdowns. What I want is, to hide/disable the submit button until option from the last select is chosen.
const select = document.getElementsByClassName("f_select f_select_product_cat f_select_product_cat_3")[0];
const submitButton = document.querySelectorAll(".button, .woof_submit_search_form");
document.getElementsByClassName("f_select f_select_product_cat f_select_product_cat_3")[0].addEventListener('change', () => {
if (select.value === '0') {
submitButton.disabled = true;
} else {
submitButton.disabled = false;
}
});
<select class="f_select f_select_product_cat f_select_product_cat_0" name="product_cat">
<option value="0">Select cat 1</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select class="f_select f_select_product_cat f_select_product_cat_1" name="product_cat">
<option value="0">Select cat 2</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select class="f_select f_select_product_cat f_select_product_cat_2" name="product_cat">
<option value="0">Select cat 3</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select class="f_select f_select_product_cat f_select_product_cat_3" name="product_cat">
<option value="0">Select cat 4</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<button class="button f_submit_search_form">SEARCH</button>
I don't have much control over form rendering, so my best option is to get both the button and the last select by class name, but as you can see they have multiple classes.
Tried also to get the select with getElementsByName("product_cat")[0] but also doesn't make it to work.
Any help appreciated.
The first issue I see is that you're setting the submitButton to disabled when the value is 0. But you perform that verification only when the value of it changes as you listen to change.
You have only one button, why would you use document.querySelectorAll to retrieve it? Simply uses querySelector. More than that, it is an issue here as you are trying to set a NodeList to disabled = true and not an element! For you to understand, here are both output.
querySelectorAll
NodeList [button.button.f_submit_search_form, disabled: true]
0: button.button.f_submit_search_form
Excellent, we now see why it did not work! We are trying to set disabled = true to a NodeList which form is similar to an array!
So, in our case, we just need one element, so we can just fix that by using querySelector.
querySelector
<button class="button f_submit_search_form" disabled="">SEARCH</button>
That looks much more like what we need: the button alone.
And now, our .disabled makes sense and works!
const select = document.getElementsByClassName("f_select f_select_product_cat f_select_product_cat_3")[0];
const submitButton = document.querySelector(".button, .woof_submit_search_form");
select.addEventListener("change", () => {
if (select.value === '0') {
submitButton.disabled = true
} else {
submitButton.disabled = false
}
})
That logic has a little flaw though: we are only setting submitButton to be displayed when the addEventListener occurs.
So we need in the HTML to add disabled by default, as per default, it will for sure not be set to anything else than default value.
<button class="button f_submit_search_form" disabled>SEARCH</button>
It now works, the button will be enabled ONLY if the last field value is anything else than 0.
Related
I have a drop-down list where depending on the selected value, the next drop-down list shows specific values. when changing the value of the first list and then going back to the old value, the second list does not update. keeps the same value selected before. How can I make the second list update to the value I marked as selected by default whenever I change the value of the first list?
I hope you guys were able to understand me, and I thank you for your time.
Here's the code:
<select onchange="showprd('hidevalue', this), showprd2('hidevalue2', this)">
<option value="" disabled selected hidden>Selecione</option>
<option value="0">São Francisco</option>
<option value="1">Bradesco</option>
</select>
<br>
<br>
<select hidden id="hidevalue">
<option value="" disabled selected hidden>Selecione o produto</option>
<option value="pleno">Pleno</option>
<option value="integrado">Integrado</option>
</select>
<select hidden id="hidevalue2">
<option value="" disabled selected hidden>Selecione o produto</option>
<option value="junior">Junior</option>
<option value="senior">Senior</option>
</select>
</body>
<script>
function showprd(id, elementValue) {
document.getElementById(id).style.display = elementValue.value == 0 ? 'block' : 'none';
}
function showprd2(id, elementValue) {
document.getElementById(id).style.display = elementValue.value == 1 ? 'block' : 'none';
}
</script>
TL;DR. Control the input value changes in one place.
Please see the updated snippet below. html structure hasn't been changed, but I've removed the inline js call and updated the id names. JavaScript blocks are commented in details.
In a nut-shell, this code listens for any change to the parent select dropdown. Whenever a change occurs, its child dropdowns will reset their values and toggle their visibility accordingly.
// Assign each dom element to a variable
const primarySelect = document.querySelector('#primary');
const childSelect1 = document.querySelector('#child1');
const childSelect2 = document.querySelector('#child2');
const defaultValues = document.querySelectorAll('.default');
function resetInputs() {
// Reset the child select options to default
defaultValues.forEach(option => option.selected = true);
}
function handlePrimary(e) {
// Reset the child select values whenever the parent value changes
resetInputs();
// `input` value is always a string. Here we're converting it to a number
const val = parseFloat(e.target.value);
// Toggle visibility of child select dropdowns
[childSelect1, childSelect2].
forEach((select, i) => select.style.display = val === i ? 'block' : 'none');
}
primarySelect.addEventListener('change', handlePrimary);
<select id="primary">
<option value="" disabled selected hidden>Selecione</option>
<option value="0">São Francisco</option>
<option value="1">Bradesco</option>
</select>
<br>
<br>
<select hidden id="child1">
<option class="default" value="" disabled selected hidden>Selecione o produto</option>
<option value="pleno">Pleno</option>
<option value="integrado">Integrado</option>
</select>
<select hidden id="child2">
<option class="default" value="" disabled selected hidden>Selecione o produto</option>
<option value="junior">Junior</option>
<option value="senior">Senior</option>
</select>
If I understood correctly, the expected behavior is when the second or third <select> is hidden, the <select> should go back to default (the first <option>?). If so, then remove disabled and hidden from the first <option> of the second and third <select> then add the following:
selectObj.hidden = true;
selectObj.selectedIndex = 0;
The example below has a <form> wrapped around everything (always use a form if you have more than one form control. By using HTMLFormElement interface I rewrote the code and can reference all form controls with very little code. Inline event handlers are garbage so don't do this:
<select id='sel' onchange="lame(this)">
Instead do this:
selObj.onchange = good;
OR
selObj.addEventListener('change', better)
Read about events and event delegation
const UI = document.forms.UI;
UI.onchange = showSelect;
function showSelect(e) {
const sel = e.target;
const IO = this.elements;
if (sel.id === "A") {
if (sel.value === '0') {
IO.B.hidden = false;
IO.C.hidden = true;
IO.C.selectedIndex = 0;
} else {
IO.B.hidden = true;
IO.B.selectedIndex = 0;
IO.C.hidden = false;
}
}
}
<form id='UI'>
<select id='A'>
<option disabled selected hidden>Pick</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
<br>
<br>
<select id="B" hidden>
<option selected>Pick B</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
<select id="C" hidden>
<option selected>Pick C</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
</form>
I give you an example for your reference:
let secondList = [
[{
value: "pleno",
text: "Pleno"
},
{
value: "integrado",
text: "Integrado"
}
],
[
{
value: "junior",
text: "Junior"
},
{
value: "senior",
text: "Senior"
}
]
]
function update(v){
let secondSelectBox=document.getElementById("second");
secondSelectBox.style.display="none";
let optionList=secondList[v.value];
if (optionList){
let defaultOption=new Option("Selecione o produto","");
secondSelectBox.innerHTML="";
secondSelectBox.options.add(defaultOption);
optionList.forEach(o=>{
let vv=new Option(o.text,o.value);
secondSelectBox.options.add(vv);
})
secondSelectBox.style.display="block";
}
}
<select onchange="update(this)">
<option value="" disabled selected hidden>Selecione</option>
<option value="0">São Francisco</option>
<option value="1">Bradesco</option>
</select>
<select hidden id="second">
</select>
I'm writing a form with 4 <select> elements. They all have the same options and I would like to disable, hide, or remove the selected option from one <select> in the other <select> elements with the same options in order to prevent the user to select the same option in multiple <select> elements.
No jQuery, only plain JavaScript please.
If possible I would like the first option to always display in all <select> elements:
<option class="select-items" selected>Sélectionnez..</option>
Here is the HTML for one <select>:
<select class="custom-select mb-3" id="name_typage_0">
<option class="select-items" selected>Sélectionnez..</option>
<option class="select-items" value="designation">Désignation</option>
<option class="select-items" value="email">Email</option>
<option class="select-items" value="ville">Ville</option>
<option class="select-items" value="secteur_activite">Secteur d'activité</option>
</select>
Here is part of my JavaScript:
const custSelec = document.querySelectorAll('.custom-select');
custSelec.forEach(function(item){
item.addEventListener('change', function(){
if(item.options[item.selectedIndex].text == 'Sélectionnez..'){
count = -1;
}else{
count = 1;
total += count;
compteur.textContent = ` ${total}/${custSelec.length -1}`;
In your change event listener, you can get the current set of selected values from all <select> elements in the group, and then loop through each element's options to both disable the options currently selected elsewhere in the group as well as re-enable any options that were previously selected but have since been changed. You can avoid disabling the first "label" option in each of your selects by checking the value before disabling / enabling options.
You could use this same approach to hide or remove options keeping in mind that there are some browser compatibility issues when trying to hide <option> elements and that you would need some additional code to store the complete list of options if you were going to remove and restore them.
const selects = document.querySelectorAll('.select-group');
selects.forEach((elem) => {
elem.addEventListener('change', (event) => {
const values = Array.from(selects).map((select) => select.value);
for (const select of selects) {
select.querySelectorAll('option').forEach((option) => {
const value = option.value;
if (value && value !== select.value && values.includes(value)) {
option.disabled = true;
} else {
option.disabled = false;
}
});
}
});
});
<select class="select-group">
<option value="">Select...</option>
<option value="first">First Value</option>
<option value="second">Second Value</option>
<option value="third">Third Value</option>
</select>
<select class="select-group">
<option value="">Select...</option>
<option value="first">First Value</option>
<option value="second">Second Value</option>
<option value="third">Third Value</option>
</select>
<select class="select-group">
<option value="">Select...</option>
<option value="first">First Value</option>
<option value="second">Second Value</option>
<option value="third">Third Value</option>
</select>
Thanks a lot for your help! I added a small 'if' to fix my bug and it works perfectly (until the next bug ^^):
if(value !== ""){
option.disabled = true;
}
Or I could just :
if (value && value !== select.value && values.includes(value) && value !== "") {
option.disabled = true;
}
Another difficulty when you begin : learn to write simple code ^^z
I'm trying to create a working function that will hide specific select options based on certain values. The options will not have a class or id so I need to use the option value as an identifier.
Does anyone see a problem with this function?
function delivery_rate(valMap) {
if(valMap === 5000){
$(".addon-select option[value="1-day-1"]").setAttribute("hidden", true);
}
}
Instead of applying hidden on the options tag, create different versions of <select> and set all to be hidden. When a user selects a value that matches the criteria of that <select> tag, show that specific tag.
<select name="select" class="first-select">
<option value="value1">Value 1</option>
<option value="value2" selected>Value 2</option>
<option value="value3">Value 3</option>
</select>
<select name="select" class="second-select">
<option value="value4">Value 1</option>
<option value="value5" selected>Value 2</option>
<option value="value6">Value 3</option>
</select>
i have a problem. I wanted to do on my web page this thing:
1. i have select box like this
<select name="firstbox" id="#firstbox">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
2. i have select box of which options are depending on first box, so if i choose in first box Option 1 i will have lets say this:
<select name="secondbox" id="#secondbox">
<option value="4">Option 4</option>
<option value="5">Option 5</option>
</select>
and if i choose Option 2 i would have lets say
<select name="secondbox" id="#secondbox">
<option value="8">Option 8</option>
<option value="9">Option 9</option>
</select>
And in adition based on those two selection box i need one link that changes url depending on those two. So it would be IF option from #firstbox = 1, and secondbox=2 #link is first.html
<a href="first.html" id="link" >Show </a>
I dont know if its doable in javascript, or is it better and more smooth to make it with PHP and small database... But i still dont know in that case how to change link of that button... Hope someone has an idea.
Alternatively, if you opt to use jQuery, of course you can use the onchange event. But first, you need to set a simple default values, wherein, it depends on what you select. Consider this example:
<select name="firstbox" id="firstbox" style="width: 100px;">
<option disabled selected>Select Value</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<div id="select_boxes"></div>
<div id="link"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
var default_values = {
"1": {"label": "first","values": [4,5]},
"2": {"label": "second","values": [8,9]},
"3": {"label": "third","values": [6,7]}
};
$(document).ready(function(){
$('#firstbox').on('change', function(){
var current = $(this).val();
$('#select_boxes').html('<select name="secondbox" id="secondbox" style="width: 100px;"></select>');
var options = '';
$.each(default_values[current].values, function(index, values){
options += '<option value="'+values+'">Option '+values+'</option>'; // fetch options
});
$('#secondbox').html(options); // add options
$('#link').html('show');
});
});
</script>
Sample Output
how do I handle events for option elements?
<select>
<option value='option1'>Gateway 1</option>
<option value='option2'>Gateway 2</option>
<option value='option3'>Gateway 3</option>
</select>
When an option element is clicked I want to display a little description for the element. Any ideas how to do that?
You're going to want to use jQuery's change event. I am displaying the text of your option as an alert, but you can display whatever you want based on your needs. (You can also, obviously, put it inside another part of the page...it doesn't need to be an alert.)
$('#myOptions').change(function() {
var val = $("#myOptions option:selected").text();
alert(val);
});
Also, note, that I added an ID to your select tag so that you can more easily handle events to it (I called it myOptions).
Example: http://jsfiddle.net/S9WQv/
As specified by JasCav using jQuery you can accomplish the same in javascript using
<select onchange="alert(this.options[this.selectedIndex].text);">
<option value='option1'>Gateway 1</option>
<option value='option2'>Gateway 2</option>
<option value='option3'>Gateway 3</option>
</select>
Alternatively, onclick event of option, but note that it is not compatible on all browsers.
<select>
<option value='option1' onclick="alert(this.value);" >Gateway 1</option>
<option value='option2'>Gateway 2</option>
<option value='option3'>Gateway 3</option>
</select>
You can write it as below mention using javascript.
document.getElementById("select").addEventListener('change', (event) => {
console.log(event.target.value)
});
<select id="select">
<option value='option1'>Gateway 1</option>
<option value='option2'>Gateway 2</option>
<option value='option3'>Gateway 3</option>
</select>