I tried to have two input option enable based on the radio button choice, but only one option is enabling not matter which option I choose. Eg- If I choose sheetcake, instead of having input option for sheetcake, I have the input option of roundcake. I am new in javascript and any advice will be much appreciated. Thank You. ( I tried to run the code in snippet and it works fine but I run the same code in browser and only one input box is working no matter what, I tried to run in 3 different browsers and got the same error, I don't know what is the issue and where I made a mistake. Thank You in advance.
const sheetcake = document.getElementById("sheetcake");
const roundcake = document.getElementById("roundcake");
var caketype = document.getElementsById("caketype");
function CakeChoice(choice){
if (choice == sheetcake){
document.getElementById("SheetLength").disabled=false;
document.getElementById("SheetWidth").disabled=false;
document.getElementById("RoundRadius").disabled=true;
}
else {
document.getElementById("SheetLength").disabled=true;
document.getElementById("SheetWidth").disabled=true;
document.getElementById("RoundRadius").disabled=false;
}
}
<div id="caketype">
<label >Cake Type:</label> <br>
<input type="radio" id="sheetcake" name="caketype" value="0" required onclick="CakeChoice(sheetcake)">
<label>Sheet Cake</label><br>
<input type="radio" id="roundcake" name="caketype" value="0" required onclick="CakeChoice(roundcake)">
<label>Round Cake</label>
</div>
<br>
<div id="CakeDimensions" >
<label>Cake size (cm)</label><br>
<input type="number" id="SheetLength" value="0" min="30" max="60" required disabled>
<label >cm Length</label><br>
<input type="number" id="SheetWidth" value="0" min="30" max="45" required disabled>
<label >cm Width</label>
</div>
<br>
<div id="round">
<label>Cake size</label><br>
<input type="number" id="RoundRadius" min="15" max="30" disabled required>
<label >cm Radius</label>
</div>
<br><br>
<div id="cakelayers">
<label >How many layers?</label><br>
<input type="radio" id="OneLayer" name="CakeLayers" value="1layer" required>
<label for="OneLayer">One Layer</label><br>
<input type="radio" id="TwoLayers" name="CakeLayers" value="2layers" required>
<label for="TwoLayers">Two Layers</label><br>
<input type="radio" id="ThreeLayers" name="CakeLayers" value="3layers" required>
<label for="ThreeLayers">Three Layers</label>
</div>
<br><br>
CodePudding user response:
May I suggest a slightly alternative approach which avoids having irrelevant disabled options that some users might be trying to activate.
Instead of disabling the irrelevant options, manipulating the display styles of the two sets of option for cake dimensions (by javascript) allows for only the relevant one to be available for interaction. This lets you make the relevant size option only appear when a type has been chosen (and toggles between them if the user changes their mind).
As you have fairly complex markup for each option, I've added extra divisions containing each group. The id
s for the relevant divisions, rectangle
and round
are used to create references to each grouping in the javascript allowing access to their style.display
property, which can be toggled.
const sheetcake = document.getElementById("rectangle");
const roundcake = document.getElementById("round");
sheetcake.style = "display: none";
round.style = "display: none";
function CakeChoice(choice){
if (choice == 'sheetcake'){
sheetcake.style = "display: block";
roundcake.style = "display: none";
} else {
sheetcake.style = "display: none";
roundcake.style = "display: block";
}
}
<div id="caketype">
<label >Cake Type:</label> <br>
<input type="radio" id="sheetcake" name="caketype" value="0" required onclick="CakeChoice('sheetcake')">
<label>Sheet Cake</label><br>
<input type="radio" id="roundcake" name="caketype" value="0" required onclick="CakeChoice('roundcake')">
<label>Round Cake</label>
</div>
<br>
<div id="CakeDimensions" >
<div id="rectangle">
<label>Cake size (cm)</label><br>
<input type="number" id="SheetLength" value="0" min="30" max="60" required>
<label >cm Length</label><br>
<input type="number" id="SheetWidth" value="0" min="30" max="45" required>
<label >cm Width</label>
</div>
<div id="round">
<label>Cake size</label><br>
<input type="number" id="RoundRadius" min="15" max="30" required>
<label "required">cm Radius</label>
</div>
</div>
<br>
<div id="cakelayers">
<label >How many layers?</label><br>
<input type="radio" id="OneLayer" name="CakeLayers" value="1layer" required>
<label for="OneLayer">One Layer</label><br>
<input type="radio" id="TwoLayers" name="CakeLayers" value="2layers" required>
<label for="TwoLayers">Two Layers</label><br>
<input type="radio" id="ThreeLayers" name="CakeLayers" value="3layers" required>
<label for="ThreeLayers">Three Layers</label>
</div>
<br>
CodePudding user response:
I've made some minor refactoring to your HTML then removed a bit of replication to your javascript, reducing the dependencies on Ids. This will make it more flexible should you add more options for dimensions or round. I've also illustrated adding the event listeners via javascript.
//Get all the radio buttons in the element with ID caketype and itterate them
document.querySelectorAll("#caketype input[type=radio]").forEach(function(item) {
//Add an on click event listener
item.addEventListener("click", function() {
//Is Sheet cake chosen from the clicked element
let isSheetCake = this.value === "sheetcake";
//Set out disabled AND required attributes based on the above
//Get the input elements in the fieldset and itterate instead of being bound by id
document.querySelectorAll("#CakeDimensions input").forEach(function(element) {
element.disabled = !isSheetCake;
element.required = isSheetCake;
});
//Do the same for round, but invert the logic
document.querySelectorAll("#round input").forEach(function(element) {
element.disabled = isSheetCake;
element.required = !isSheetCake;
});
//Bonus: lets set a class to indicate that group is disabled
//.classList.toggle() ,adds or removes a class, in this case
// based on a truthy value
document.getElementById("CakeDimensions").classList.toggle("disabled", !isSheetCake);
document.getElementById("round").classList.toggle("disabled", isSheetCake);
});
});
fieldset {
border: none;
padding: 0.5em;
margin: 0;
}
.disabled {
color: #EEE;
}
<!-- Ive Given the radio buttond values, which you are going to want if you send this to a server-->
<!-- Also encapsulated the radio button group with a fieldset which is more semantic-->
<!-- Inline Javascript has been removed -->
<!-- Labels have been associated with their form elements with the "for" attribute-->
<fieldset id="caketype">
<label >Cake Type:</label> <br>
<input type="radio" id="sheetcake" name="caketype" value="sheetcake" required>
<label for="sheetcake">Sheet Cake</label><br>
<input type="radio" id="roundcake" name="caketype" value="roundcake" required>
<label for="roundcake">Round Cake</label>
</fieldset>
<fieldset id="CakeDimensions">
<label>Cake size (cm)</label><br>
<input type="number" id="SheetLength" value="0" min="30" max="60" required disabled>
<label >cm Length</label><br>
<input type="number" id="SheetWidth" value="0" min="30" max="45" required disabled>
<label >cm Width</label>
</fieldset>
<fieldset id="round">
<label>Cake size</label><br>
<input type="number" id="RoundRadius" min="15" max="30" disabled required>
<label >cm Radius</label>
</fieldset>