javascriptformsconditional-statementshidden-field

Conditional Form Inputs - Multiple Fields Shown/Hidden


I am attempting to build a form that hides multiple input boxes of the form unless a condition is met.
So the question would be: Do you have a separate mailing address? Yes No

If "yes" is selected, I want to then show three input fields for their mailing address, city, and zip. If "no," then I don't want anything to show up. I'd just like them to be able to go to the next line.

What I've come up with so far from research only works if I do a simple single input box for a response. When I attempt to do multiple inputs within their own divs, it breaks the form.

 <div class="form-item">
                    <label>
                    <input type="radio" id="yes" name="yesOrNo" value="yes" onchange="displayQuestion(this.value)" />Yes</label>
                    <label>
                    <input type="radio" id="no" name="yesOrNo" value="no" onchange="displayQuestion(this.value)" />No</label>
            
                    <div id="yesQuestion" style="display:none;"><br/>
                        <div class="form-item">
                            <label for="Mailing Address" class="req-field">Mailing Address</label>
                            <input id="Mailing_Address" name="Mailing Address" type="text" class="required-text" autocomplete="mailing-address"/>
                        </div>
                        <div class="form-item">
                            <label for="Mailing_City" class="req-field">City</label>
                            <input id="mailing_city" name="mailing_city" type="text" class="required-text" autocomplete="street-city"/>
                        </div>
                        <div class="form-item">
                            <label for="mailing_zip" class="req-field">Zip Code</label>
                            <input id="mailing_zip" name="mailing_Zip" type="text" class="required-text" autocomplete="street-zip"/>
                        </div>
                    </div>
                </div>
    function displayQuestion(answer) {

        document.getElementById('noQuestion').style.display = "none";

        if (answer == "yes") {    

        document.getElementById(answer + 'Question').style.display = "block";

        } else if (answer == "no") {  document.getElementById('yesQuestion').style.display = "none";

}

}

Thank you.


Solution

  • I have a lot of comments here that hopefully can help you:

    1. A <fieldset> can be used in a form for handling a group of form fields. If it has the disabled attribute all child form fields will be disabled.
    2. In your case the radio buttons can have the values 0 and 1. These values can be turned into a boolean.
    3. The attribute in <input> can have any value, but try to stick to the standards: autocomplete #values.
    4. Try to make use of the name attribute in forms and use less IDs -- IDs need to be unique in the HTML document.
    5. Instead of using a class name like "required-text" in your case for styling required fields, use the required attribute and style according to that.

    The JavaScript listens for a change event on the entire form (so, this could be any change on any form field). I test if the e.target.name is "yesOrNo" -- then I know that the radio buttons changed. Now I can take the boolean value from the "radioNodeList" and assign that to the disabled property of the fieldset.

    document.addEventListener('DOMContentLoaded', e => {
      document.forms.form01.addEventListener('change', e => {
        if (e.target.name == 'yesOrNo') {
          let yesOrNo = new Boolean(parseInt(e.target.form.yesOrNo.value));
          e.target.form.yesQuestion.disabled = yesOrNo.valueOf();
        }
      });
    });
    input:required {
      border: red thin solid;
    }
    
    input:disabled {
      border: darkgray thin solid;
      background-color: lightgray;
    }
    
    fieldset:disabled {
      display: none;
    }
    <form name="form01">
      <div class="form-item">
        <label><input type="radio" name="yesOrNo" value="0"/>Yes</label>
        <label><input type="radio" name="yesOrNo" value="1" checked/>No</label>
      </div>
      <fieldset name="yesQuestion" disabled>
        <div class="form-item">
          <label for="mailing_address" class="req-field">Mailing Address</label>
          <input id="mailing_address" name="mailing_address" type="text"
            autocomplete="street-address" required/>
        </div>
        <div class="form-item">
          <label for="mailing_city" class="req-field">City</label>
          <input id="mailing_city" name="mailing_city" type="text"
            autocomplete="address-level2" required/>
        </div>
        <div class="form-item">
          <label for="mailing_zip" class="req-field">Zip Code</label>
          <input id="mailing_zip" name="mailing_zip" type="text"
            autocomplete="postal-code" required/>
        </div>
      </fieldset>
    </form>