0

Looking for help with this please, tried to run with many articles on here but can't seem to get what I'm after.

What you will see in the following snippet works for showing and hiding the different options depending on whether the first option is Yes or No.

However I want all fields to be required but I need a way of them only being required, if they are shown. Believe there will be something I could add or alter with the JavaScript to remove the required attributes?

function yesnoCheck(that) {
    if (that.value == "Yes") {
        document.getElementById("ifYes").style.display = "block";
    } else {
        document.getElementById("ifYes").style.display = "none";
    }
    if (that.value == "No") {
        document.getElementById("ifNo").style.display = "block";
        document.getElementById("ifNo2").style.display = "block";
    } else {
        document.getElementById("ifNo").style.display = "none";
        document.getElementById("ifNo2").style.display = "none";
}
}
<form name="emailsend" class="form-check" method="post" action="send.php">
  <label>Decision maker selection</label>
  <br>
  <select name='resolved' onchange="yesnoCheck(this);">
    <option value='' selected disabled hidden></option>
    <option value='No'  > No  </option>
    <option value='Yes' > Yes </option>
  </select>
  <br>
  <div id="ifYes" style="display: none;">
    <br>
    <label>Showifresolvedisyes</label>
    <br>
    <select name='ref2' required>
      <option value='Test' > Test </option>
    </select>
  </div>
  <div id="ifNo" style="display: none;">
    <label>Showifresolvedisno</label>
    <br>
    <select name='colour' >  
      <option value=''  selected disabled hidden></option>
      <option value='red'    class="redoption"   > Red   </option>
      <option value='orange' class="amberoption" > Amber </option>
      <option value='green'  class="greenoption" > Green </option>
    </select>
  </div>
  <br>
  <div id="ifNo2" style="display: none;">
    <label>Showifresolvedisno</label>
    <br>
    <select name='ref3' required>
      <option value='Test'>Test</option>
    </select>
    <br>
    <br>
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-block btn-primary" name="btn-login">
      Take me to the Preview!
    </button>
  </div>
</form>

Any help would be massively appreciated!

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
  • Yeah this is just a snippet of my code just to give an example of what im trying to achieve, added the form ending now too just to make it clear but its definitely a form – Steven Rothera Dec 30 '20 at 18:47
  • @StevenRothera Give this a read: (https://stackoverflow.com/questions/18111915/remove-required-property-from-input-field-on-form-submit) – Ryan Wilson Dec 30 '20 at 18:51
  • Can you post a snippet showing how you are validating these fields? Because that's the part where it will need to be changed. If you are only validating it on the server side ( e.g form action send.php ), this info about which is shown will need to be sent too. – Felipe Malara Dec 30 '20 at 18:54
  • There is no validation outside of this, the form action post just puts the POST elements into a variable. All i need to do with the above is make it so that if said input/select is hidden based on the first option, it removes the required attribute that is set. – Steven Rothera Dec 30 '20 at 18:57

2 Answers2

1

First you don't need to add selected and disabled attributes to your empty default options. When you select an empty option by default, that overrides the required attribute of the select tag because it is already selected with an empty value.

second I would choose class name instead of id for ifYes and ifNo containers.

this way it would be easier to add more Select tags and options without need to add more ids and styling them separately and you can control them simultaneously like this:

const ifYes = document.querySelectorAll(".ifYes");
const ifNo = document.querySelectorAll(".ifNo");
const theForm = document.forms["emailsend"];

theForm.resolved.onchange = () => {
  const yes = theForm.resolved.value === "Yes";
    ifYes.forEach((div) => {
      div.classList.toggle("noDisplay", !yes);
      div.querySelector("select").required = yes;
    });
    ifNo.forEach((div) => {
      div.classList.toggle("noDisplay", yes);
      div.querySelector("select").required = !yes;
    });
};
.noDisplay {
  display: none;
  }
<form name="emailsend" class="form-check" method="post" action="send.php">
  <label>Decision maker selection</label><br />
  <select name="resolved" required>
    <option value="" hidden></option>
    <option value="No">No</option>
    <option value="Yes">Yes</option>
  </select>
  <br />
  <div class="noDisplay ifYes">
    <label>Show if resolved is yes</label><br />
    <select name="ref2" required>
      <option value="" hidden></option>
      <option value="Test">Option 1</option>
      <option value="Test">Option 2</option>
    </select>
  </div>
  <div class="noDisplay ifNo">
    <label>Show if resolved is no</label><br />
    <select name="colour" required>
      <option value="" hidden></option>
      <option value="red">Red</option>
      <option value="orange">Amber</option>
    </select>
  </div>
  <br />
  <div class="noDisplay ifNo">
    <label>Show if resolved is no</label><br />
    <select name="ref3" required>
      <option value="" hidden></option>
      <option value="Test">option 1</option>
      <option value="Test">option 2</option>
    </select>
    <br />
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-block btn-primary" name="btn-login">
      Take me to the Preview!
    </button>
  </div>
</form>
Abbas Hosseini
  • 1,545
  • 8
  • 21
  • Thanks for this, the snippet works, for some reason when I put it in my own PHP file exactly as you have put it, it never shows the other fields. Unsure if i need to call it in a specific way. The file has the JavaScript inside of and the CSS inside of . Tried setting the script type to text/javascript but still nothing. What am i missing? Also if say i have inputs instead of selects within the form, will it work if i simply add another attribute for input instead of select? – Steven Rothera Dec 31 '20 at 19:29
  • You have to put the script tag after the HTML content of your page. That's because if you put it in the head, you're HTML content is not loaded yet so the script can't query your document. you don't need to specify the type attribute of your script tag. and you can add the 'ifYes' or 'ifNo' class to any element you want so they will be rendered or not depending on the yes or no options of your first select tag. I strongly recommend to you to read HTML, CSS and Javascript tutorials of w3schools.com and MDN. – Abbas Hosseini Dec 31 '20 at 20:13
  • Hi Abbas, I have just cropped up with another requirement for this that I'm struggling to achieve. Moved it to here https://jsfiddle.net/v2pwz4tc/ Instead of the primary field being named resolved and answers being yes or no, its updatetype and multiple text answers. there are two separate HTML elements that i want to display or not dependent on the answer, for example if its Re-Scheduled, show both, if its Reminder, show none of them, if its anything else, show one of them I'm struggling to see how I can achieve it? Any help would be much appreciated, this worked a treat before :) – Steven Rothera Aug 13 '21 at 07:36
  • Hi, would you please add the HTML skeleton so I can see what are the results that you expect? – Abbas Hosseini Aug 13 '21 at 08:52
  • Hi Abbas, to keep it separate from what worked, added it to here: https://jsfiddle.net/ug0b8acv/ – Steven Rothera Aug 13 '21 at 09:02
  • Hey, here is the [fiddle](https://jsfiddle.net/sam4zjpn). It's anonymous so save it if you may need it later. The code could be more concise if you had just the three options you've included, but doing it this way is more general. – Abbas Hosseini Aug 13 '21 at 09:43
  • Thanks Abbas, that has worked perfectly, really appreciate your help! – Steven Rothera Aug 13 '21 at 12:20
  • You're always welcome, Steven! I'm glad I could help! – Abbas Hosseini Aug 13 '21 at 17:47
0

I will do that this way:

It is necessary to dispose of a css noDisplay class, instead of your style="display: none;" in the HTML

const div_ifYes   = document.getElementById('ifYes')
  ,   div_ifNo1   = document.getElementById('ifNo')
  ,   div_ifNo2   = document.getElementById('ifNo2')
  ,   theForm     = document.forms['emailsend']
  ,   AllRequired = theForm.querySelectorAll('[required]')
  ;
function setRequired()
  {
  AllRequired.forEach(el=>
    {
    el.required = !el.closest('div').classList.contains('noDisplay');
    })
  }
setRequired()  // on start 
  ;
theForm.resolved.onchange = () =>
  {
  div_ifYes.classList.toggle('noDisplay', !(theForm.resolved.value === 'Yes'))
  div_ifNo1.classList.toggle('noDisplay', !(theForm.resolved.value === 'No'))
  div_ifNo2.classList.toggle('noDisplay', !(theForm.resolved.value === 'No'))
  setRequired()
  }
theForm.onsubmit = e =>  // just for letting the testing here
  {
  e.preventDefault() // disable submit
  }
.noDisplay {
  display: none;
  }
<form name="emailsend" class="form-check" method="post" action="send.php">
  <label>Decision maker selection</label>
  <br>
  <select name='resolved'>
    <option value='' selected disabled hidden></option>
    <option value='No'  > No  </option>
    <option value='Yes' > Yes </option>
  </select>
  <br>
  <div id="ifYes" class="noDisplay">
    <br>
    <label>Showifresolvedisyes</label>
    <br>
    <select name='ref2' required>
      <option value='Test' > Test </option>
    </select>
  </div>
  <div id="ifNo" class="noDisplay">
    <label>Showifresolvedisno</label>
    <br>
    <select name='colour' >  
      <option value=''  selected disabled hidden></option>
      <option value='red'    class="redoption"   > Red   </option>
      <option value='orange' class="amberoption" > Amber </option>
      <option value='green'  class="greenoption" > Green </option>
    </select>
  </div>
  <br>
  <div id="ifNo2" class="noDisplay">
    <label>Showifresolvedisno</label>
    <br>
    <select name='ref3' required>
      <option value='Test' > Test </option>
    </select>
    <br>
    <br>
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-block btn-primary" name="btn-login">
      Take me to the Preview!
    </button>
  </div>
</form>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40