Selecting an option will select an other option

For example, if you select the option with id=“chocolate-yes” or id=“vanilla-yes”, the the option with id=“icecreamcone-yes” will also be selected.
As you can see on the image below, when you select the option with id=“chocolate-yes”, <select id=“icecreamcone”> will be disabled.

When both id=“chocolate-yes” and id=“vanilla-yes” are not selected the the option with id=“icecreamcone-no” will not be disabled.

To put it in simpler words: you always need to have an ice cream cone if you want to add vanilla or chocolate ice cream, with the exception of sprinkles :smiley:

Anyone know of a Javascript that can do this?


Note 1: the option with id=“sprinkles-yes” will not effect id=“icecreamcone-yes”.
Note 2: id=“icecreamcone-yes” need still be selectable prior to selecting id=“vanilla-yes” or id=“chocolate-yes”.
Note 3: id names cannot be changed, nor can you add more properties to the elements.
Note 4: cannot use jQuery.


<ul id="icecream" style="list-style:none;line-height:30px;">
  <li>
        <select id="icecreamcone">
          <option value="addicecreamcone">Would you like an ice cream cone?</option>
          <option id="icecreamcone-yes" value="yes">Yes</option>
          <option id="icecreamcone-no" value="no">No thanks</option>
        </select>
  </li>
  <li>
        <select id="vanilla">
          <option value="addvanilla">Would you like to add vanilla ice cream?</option>
          <option id="vanilla-yes" value="yes">Yes</option>
          <option id="vanilla-no" value="no">No thanks</option>
        </select>
  </li>
  <li>
        <select id="chocolate">
          <option value="addchocolate">Would you like to add chocolate ice cream?</option>
          <option id="chocolate-yes" value="yes">Yes</option>
          <option id="chocolate-no" value="no">No thanks</option>
        </select>
  </li>
  <li>
        <select id="sprinkles">
          <option value="addsprinkles">Would you like to add sprinkles on top?</option>
          <option id="sprinkles-yes" value="yes">Yes</option>
          <option id="sprinkles-no" value="no">No thanks</option>
        </select>
  </li>
</ul>

The problem that you’re finding is why it’s not such a good idea for client-side scripting to be in charge of business logic.

A possible way to do this though is to assign an onchange event to the vanilla and chocolate ones so that when they are selected, the icecream cone is changed to yes and is then disabled from further changes.

Warning: Disabling a form field results in that field not being sent to the server. So the server will need to check if icecream has been chosen, and if it has, the server knows that the cone must also be mandatory.

Yes this is a problem :frowning:

With some help I’ve got the following script:


<script type="text/javascript">
function observeFlavor(flavor, requires) {
    document.getElementById(flavor).onchange = function(){
      if(document.getElementById(flavor).options[1].selected == true) {
        document.getElementById(requires).options[1].selected = true
      }
    }
}
        
observeFlavor("chocolate","icecreamcone");
observeFlavor("vanilla","icecreamcone");
</script>

However, the above script doesn’t disable the field.

Maybe instead of disabling the field you make it unclickable when vanilla or chocolate, or both are selected. But when they are both deselected, the cone will be clickable again.

Would this solve the server-side problem? And could you give me an example if you know how to do this?

The script below turns “disabled” off when the submit button is clicked. But there’s only one problem: when you have selected both vanilla and chocolate, and you deselect one of them, “disabled” is turned off for the cone.

If one of the two is still selected, the cone must be disabled. Do you know how to fix this problem?


<script type="text/javascript">
function observeFlavor(flavor, requires) {
    document.getElementById(flavor).onchange = function(){
      if(document.getElementById(flavor).options[1].selected == true) {
        document.getElementById(requires).options[1].selected = true;
        document.getElementById(requires).disabled = true;
      }
      else{
        document.getElementById(requires).disabled = false;
      }
    }
}

document.getElementById("your-submit-button").onclick = function () {
    document.getElementById("icecreamcone").disabled = false;
}

observeFlavor("chocolate","icecreamcone");
observeFlavor("vanilla","icecreamcone");
</script>

What I would do is to add a method on to the icecreamcone field, perhaps called updateFromFlavours, so that you can then run that method to perform the update.


function createUpdateFromFlavoursHandler(target, flavours) {
target.updateFromFlavours = function () {
    var requiresCone = false,
        i;
    for (i = 0; i < flavours.length; i += 1) {
        if (...) { // check if the flavour is used
            requiredCone = true;
        }
    }
    target.disabled = !requiresCone;
};

var icecreamCone = document.getElementById('icecreamcone');
var flavours = [
    document.getElementById('chocolate'),
    document.getElementById('vanilla')
];
createUpdateFromFlavoursHandler(icecreamCone, flavours);

With something like that.

It’s also better to pass the object as a function argument, than just a string of the identifier. So assuming that you have a reference to the icecreamCone as the variable called requires, you could update it from within the observeFlavour function by making the following call:


requires.updateFromFlavours();

Thank you Paul :slight_smile: