Disable select options based on another select option after page load - javascript

I've recently asked this question, it's working fine as I expected until I found out that when I submitted the form and there's an error with the inputs (I'm using Laravel) after the page reloads the Grade Levels options which should be disabled some option based on the value of the Level selection options are now all enabled.
The expected outcome is even if the page reloads (because of the error after the form has been submitted) the Grade Levels options are still disabled based on the value of Level.
The value of the Level select box is preserved and selected after the error occurred, also did a console.log and it's showing the preserved value.
My approach is to have a DOMContentLoaded and place the JavaScript code there to handle the disabling of options based on the selected value in Level select option but I didn't make it work.
Code I'm trying to
document.addEventListener('DOMContentLoaded', (event) => {
let level = document.getElementById('level')
let grade_level = document.getElementById('grade_level')
let gradeSelect = document.querySelector('.grade_level')
let currentLevel = level.value;
console.log(currentLevel) // this shows the current value of level select option
grade_level.disabled = true
if (level.value == 'Senior') {
grade_level.removeAttribute('disabled')
} else if (level.value == 'Junior') {
grade_level.removeAttribute('disabled')
}
gradeSelect.querySelectorAll('option[value]').forEach(function(option) {
let match = currentLevel === option.dataset.level
option.disabled = !match
if(! match){
option.closest("select").append(option)
}
});
});
Code which is working fine with all inputs in the form is valid (no errors and not being redirected back to the page):
let gradeSelect = document.querySelector('.grade_level')
document.getElementById('level').onchange = function() {
let level = this.value;
gradeSelect.querySelectorAll('option[value]').forEach(function(option) {
let match = level === option.dataset.level
option.disabled = !match
if(!match){
option.closest("select").append(option)
}
});
// Sets the first one (Choose Grade Level) selected
gradeSelect.querySelector('option').selected = true
};
<select name="level" id="level" autofocus>
<option selected disabled>Choose</option>
<option value="Junior">Junior</option>
<option value="Senior">Senior</option>
</select>
<select name="grade_level" class="grade_level">
<option selected disabled>Choose Grade Level</option>
<option value="Grade 7" data-level="Junior">Grade 7</option>
<option value="Grade 8" data-level="Junior">Grade 8</option>
<option value="Grade 9" data-level="Junior">Grade 9</option>
<option value="Grade 10" data-level="Junior">Grade 10</option>
<option value="Grade 11" data-level="Senior">Grade 11</option>
<option value="Grade 12" data-level="Senior">Grade 12</option>
</select>
EDIT
I've implemented Stephen and Louys's answer but none of them works in disabling the Grade Levels select options based on the preserved value of the Level select option after page reloads.
To explain what I mean in page reloads I have a form (post method) that is submitted and by using PHP Laravel as the backend I validate the inputs if there's an error with the inputs the page then reloads and I'm showing the error and also I'm able to get the previously selected value of the Level select box.
I have the previous value of the Level select box (it is already selected) and by that value I want to also preserve the current state of Grade Levels options - only enable what is connected to the current value of Level select and disable the remaining options.
Question:
Why do you need to show all the Grade Levels options again instead of also preserving the previously selected value?
A:
I want to do that but I can't because I'm also populating the Grade Levels options using javascript inside $function()
$(function() {
// init the grade level options
$('#grade_level').site_data('fetch_list')
});
My current code
function updateSelect() {
const level = levelSelect.value;
// Ensure everything is enabled when no level selected (on first page load)
if (level === 'Choose') {
gradeSelect.querySelectorAll('option[value]')
.forEach(o => o.disabled = false);
}
gradeSelect.querySelectorAll('option[value]')
.forEach(function(option) {
option.disabled = !(level === option.dataset.level)
});
// Sets the first one (Choose Grade Level) selected
gradeSelect.querySelector('option').selected = true;
}
let levelSelect = document.getElementById('level');
let gradeSelect = document.querySelector('.grade_level');
// Update the selection when the page loads, so if 'level' already has
// a value the grade_levels will be enabled/disabled appropriately.
document.addEventListener('DOMContentLoaded', updateSelect);
levelSelect.onchange = updateSelect;
let test = document.querySelector("#level")
test.addEventListener("change", function(){
updateSelect()
})
let customEvent = document.createEvent("event");
customEvent.initEvent('change', true, true);
test.dispatchEvent(customEvent);
<select name="level" id="level" autofocus>
<option selected disabled>Choose</option>
<option value="Junior">Junior</option>
<option value="Senior">Senior</option>
</select>
<select name="grade_level" class="grade_level">
<option selected disabled>Choose Grade Level</option>
<option value="Grade 7" data-level="Junior">Grade 7</option>
<option value="Grade 8" data-level="Junior">Grade 8</option>
<option value="Grade 9" data-level="Junior">Grade 9</option>
<option value="Grade 10" data-level="Junior">Grade 10</option>
<option value="Grade 11" data-level="Senior">Grade 11</option>
<option value="Grade 12" data-level="Senior">Grade 12</option>
</select>
EDIT #2
Here, I will make Senior as default and we will try to see if the Grade Levels options will disable Grade 7-10.
function updateSelect() {
const level = levelSelect.value;
// Ensure everything is enabled when no level selected (on first page load)
if (level === 'Choose') {
gradeSelect.querySelectorAll('option[value]')
.forEach(o => o.disabled = false);
}
gradeSelect.querySelectorAll('option[value]')
.forEach(function(option) {
option.disabled = !(level === option.dataset.level)
});
// Sets the first one (Choose Grade Level) selected
gradeSelect.querySelector('option').selected = true;
}
let levelSelect = document.getElementById('level');
let gradeSelect = document.querySelector('.grade_level');
// Update the selection when the page loads, so if 'level' already has
// a value the grade_levels will be enabled/disabled appropriately.
document.addEventListener('DOMContentLoaded', updateSelect);
levelSelect.onchange = updateSelect;
let test = document.querySelector("#level")
test.addEventListener("change", function(){
updateSelect()
})
let customEvent = document.createEvent("event");
customEvent.initEvent('change', true, true);
test.dispatchEvent(customEvent);
<select name="level" id="level" autofocus>
<option disabled>Choose</option>
<option value="Junior" selected >Junior</option>
<option value="Senior">Senior</option>
</select>
<select name="grade_level" class="grade_level">
<option selected disabled>Choose Grade Level</option>
<option value="Grade 7" data-level="Junior">Grade 7</option>
<option value="Grade 8" data-level="Junior">Grade 8</option>
<option value="Grade 9" data-level="Junior">Grade 9</option>
<option value="Grade 10" data-level="Junior">Grade 10</option>
<option value="Grade 11" data-level="Senior">Grade 11</option>
<option value="Grade 12" data-level="Senior">Grade 12</option>
</select>

In your other question, where it uses an anonymous function .onchange = function() — you will want to take that and make it a named function so it becomes (for example if you called that function "updateSelect") .onchange = updateSelect
Then you will want to run that function when the page loads, not just onchange, with something like document.addEventListener('DOMContentLoaded', updateSelect);
This assumes that, as you say, when the page reloads after your submit the value of the level select box is preserved and selected.
Adapting Louys Patrice Bessette's answer, I've pulled the function out to the top, set it up to be called when the page (DOM) is ready, and set it to be called onchange of the Level selection.
function updateSelect() {
const level = levelSelect.value;
// Ensure everything is enabled when no level selected (on first page load)
if (level === 'Select') {
gradeSelect.querySelectorAll('option[value]')
.forEach(o => o.disabled = false);
}
gradeSelect.querySelectorAll('option[value]')
.forEach(function(option) {
option.disabled = !(level === option.dataset.level)
});
// Sets the first one (Choose Grade Level) selected
gradeSelect.querySelector('option').selected = true;
}
let levelSelect = document.getElementById('level');
let gradeSelect = document.querySelector('.grade_level');
// Update the selection when the page loads, so if 'level' already has
// a value the grade_levels will be enabled/disabled appropriately.
document.addEventListener('DOMContentLoaded', updateSelect);
levelSelect.onchange = updateSelect;
<select name="level" id="level" autofocus>
<option selected disabled>Choose</option>
<option value="Junior">Junior</option>
<option value="Senior">Senior</option>
</select>
<select name="grade_level" class="grade_level">
<option selected disabled>Choose Grade Level</option>
<option value="Grade 7" data-level="Junior">Grade 7</option>
<option value="Grade 8" data-level="Junior">Grade 8</option>
<option value="Grade 9" data-level="Junior">Grade 9</option>
<option value="Grade 10" data-level="Junior">Grade 10</option>
<option value="Grade 11" data-level="Senior">Grade 11</option>
<option value="Grade 12" data-level="Senior">Grade 12</option>
</select>
EDIT
When you are populating the grade_level as you show in the update to your question:
$(function() {
// init the grade level options
$('#grade_level').site_data('fetch_list')
});
This is likely happening after the DOMContentLoaded event fires and updateSelect is run, therefore there are no <option> elements in grade_level yet for updateSelect to act upon.
You should be able to solve this by doing all of your initialization in one place, either moving the call to updateSelect into that function instead of using the DOMContentLoaded handler:
$(function() {
// init the grade level options
$('#grade_level').site_data('fetch_list');
updateSelect();
});
-or- eliminate that function and move populating the list into the DOMContentLoaded handler:
document.addEventListener('DOMContentLoaded', function() {
$('#grade_level').site_data('fetch_list');
updateSelect();
});
(note I have not tested these updated code fragments)

Related

Change option values of select 2 if select 1 has a value with jquery

I require a bit of jQuery to do the following:
A user can currently select Program and/or a region.
If a user selects Program AND a Region I require the option values of the region dropdown to change to "?region=1" and "?region=2"
<select class="program" id="program">
<option value="program1.html">Program 1</option>
<option value="program2.html">Program 2</option>
</select>
<select class="region" id="region">
<option value="region1.html">Region 1</option>
<option value="region2.html">Region2</option>
</select>
Greatly appreciate the assist.
My attempt at JQuery:
$('#program').on('change', function () { if($(this).val() !="0") { } else { // no option is selected } })
You need to further extend the change event for #program and include a similar one for #region.
var programSelected = null;
var regionSelected = null;
$('#program').on('change', function(element) {
programSelected = $('#program option:selected').text();
updateRegionOptions();
});
$('#region').on('change', function(element) {
regionSelected = $('#region option:selected').text();
updateRegionOptions();
});
function updateRegionOptions() {
if(programSelected != null && regionSelected != null) {
$('#region option').each(function() {
var modifiedString = '?';
modifiedString += $(this).val().replace(/\d+/,'');
modifiedString = modifiedString.replace('.html','');
modifiedString += '=';
modifiedString += $(this).val().match(/\d+/);
$(this).val(modifiedString);
});
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="program" id="program">
<option value="" selected disabled>Select Program</option>
<option value="program1.html">Program 1</option>
<option value="program2.html">Program 2</option>
</select>
<select class="region" id="region">
<option value="" selected disabled>Select Region</option>
<option value="region1.html">Region 1</option>
<option value="region2.html">Region2</option>
</select>
Explanation of the logic above:
on('change' event for both #region and #program
Set the relevant variable programSelected or regionSelected depending on the change event
Run function updateRegionOptions();
If the variables programSelected and regionSelected both have a value
For each of the options in #region
Mutate the existing value to be of the form "?region=1" and "?region=2"
Update the value section of each of the option elements to have this value
The relevant JSFiddle for review.
If this solved your issue, please accept this answer :)

If value in select option is lower than in second select option, then change option

I want to achieve:
If I select "16" in first select box and bigger value in second, for example "17", then in second select automatically changing to "16".
Just if value in first select box is lower than second, always change to same values, for example 16 to 16, 18 to 18.
<select id="from_age_js" name="from_age" class="select-advertise-style">
<option value="f13">13</option>
<option value="f14">14</option>
<option value="f15">15</option>
<option value="f16">16</option>
<option value="f17">17</option>
<option value="f18" selected>18</option>
<option value="f19">19</option>
<option value="f20">20</option>
</select>
—
<select id="to_age_js" name="to_age" class="select-advertise-style">
<option value="t13">13</option>
<option value="t14">14</option>
<option value="t15">15</option>
<option value="t16">16</option>
<option value="t17">17</option>
<option value="t18">18</option>
<option value="t20" selected>20+</option>
</select>
That's an easy one, in your case, with pure javascript, I would do something like this:
function checkit()
{
//Store the two dropdowns for easy reference
var fromAge = document.getElementById('from_age_js');
var toAge = document.getElementById('to_age_js');
//Verify if the toAge value is minor, to see if the conditional code will be executed
if( fromAge.options[fromAge.selectedIndex].value >
toAge.options[toAge.selectedIndex].value)
{
//In that case, match the values to be the same...
document.getElementById('to_age_js').value =
fromAge.options[fromAge.selectedIndex].value;
}
}
And you just have to add that function to where you want it to be called. I would choose to add the onchange event from Javascript within the select dropdowns. Like this:
<select id="from_age_js" name="from_age" class="select-advertise-style" onchange="checkit();">
You can see a working example here:
https://jsfiddle.net/8cmad3tz/19/

JavsScript can not click on element "option"

Below is the HTML code for the element I want to click:
<select id = "per-page-xxxxxxxx" //xxxxxxx is a dynamic string
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
It is basically a dropdown list that allow you to choose how many items to be displayed on current page.
My code to click <option value="100">100</option> is:
var dropdownListXpath = "//select[starts-with(#id,'per-page-')]";
var PublicationPerPageOptionXpath = "//select[starts-with(#id,'per-page-')]/option[#value='100']";
var dropdownList;
var PublicationPerPageOption;
aqUtils.Delay(500);
try {
dropdownList = PageObj.EvaluateXpath(dropdownListXpath);
dropdownList[0].Click();
aqUtils.Delay(500);
PublicationPerPageOption = PageObj.EvaluateXpath(PublicationPerPageOptionXpath);
PublicationPerPageOption[0].Click();
}
catch(err) {
Log.Message("Can not find options to show 100 publications per page.");
}
The result:
Dropdown list is clicked and expanded, then nothing happens afterwards, e.g. option 100 is not clicked
Can anyone please provide any help?

Multiple dependent select boxes not working

I'm looking to make a series of select boxes in html which show different options depending on what has already been selected. I can get the first two to work but can't work out why it's not injecting into the last box here, the #FCadultseats select box.
I basically want the FCadultseats box to be available only when the movie is in the big cinema (at 9pm).
Thanks a lot for any and all help. I've been trying for ages and dont know why this wont work.
Here's my code:
<form id = "booking" method = "POST" action = "testserver">
Day:
<select id = "dayselector" name = "day">
<option disabled selected> -- Select a Day -- </option>
<option value= "Monday">Monday </option>
<option value = "Tuesday">Tuesday</option>
<option value = "Wednesday">Wednesday</option>
<option value = "Thursday">Thursday</option>
<option value = "Friday">Friday</option>
<option value = "Saturday">Saturday</option>
<option value = "Sunday">Sunday</option>
</select>
<br>
Time and Cinema:
<select id ="timeselector" name ="time">
<option disabled selected> -- Select a Time -- </option>
</select>
First Class Adults: <select id ="FCadultseats">
<option disabled selected> -- Not Available -- </option>
</select>
</form>
$(document).ready(function(){
$("#dayselector").change(function(){
var sel_day = $('option:selected').val();
if (sel_day == "Saturday" || sel_day == "Sunday"){
$("select#timeselector").html('<option disabled selected> -- Select a Time -- </option><option value ="9">9pm - Large Cinema</option><option value ="4">4pm - Small Cinema</option>');
} else {
$("select#timeselector").html('<option disabled selected> -- Select a Time -- </option><option value ="9">9pm - Large Cinema</option>');
}
});
$("#timeselector").change(function(){
var sel_time = $('option:selected').val();
if (sel_time == 9){
$("#FCadultseats").html('<option value ="0">0</option><option value ="1"></option><option value ="2">2</option><option value ="3">3</option><option value ="4">4</option><option value ="5">5</option><option value ="6">6</option><option value ="7">7</option><option value ="8">8</option><option value ="9">9</option><option value ="10">10</option><option value ="11">11</option><option value ="12">12</option>');
}
});
});
Try changing
var sel_day = $('option:selected').val();
to
var sel_day = this.value;
and do that in both places.
$('option:selected') selects ALL the selected options on the page, for every select.

Can I have my list tile as first option with null value?

So here is my code
<select id="BVT STUFF" onChange="jumpTo(getSelected(this));">
<option>HardRock Catalog</option>
<option value="http://link">BVT WIKI</option>
<option value="http://link">BVT CALENDAR</option>
<option value="https://link">Sustainment</option>
<option value="link">UVerse Dispatch Servlet</option>
This is a tool that I created for my team.
My problem is that I have the list "Title" as the first option and tried to give it a null value but whenever it is selected it tries to open a page. i.e. HardRock Catalog
Is there anything I could do with this to allow the list title to really have no value?
I'll suggest to add value="" for the first option. Then in your jumpTo function check
<option value="">HardRock Catalog</option>
function jumpTo(url) {
if(url === "") return;
// other stuff here
}
You could add selected and disabled attributes.
jsfiddle
HTML
<option selected="selected" disabled>HardRock Catalog</option>
You may try this
HTML :
<select onchange="jumpTo(this)">
<option value='0'>HardRock Catalog</option>
<option value="http:\\google.com">Goto Google</option>
<option value="http:\\yahoo.com">Goto Yahoo</option>
</select>
JS :
function jumpTo(select)
{
if(select.value != '0'){
// code goes here
location.href = select.value;
}
}
DEMO.

Categories