Home > OS >  How to hide or show a WTForms field based on whether an option has been selected
How to hide or show a WTForms field based on whether an option has been selected

Time:06-22

I know I am not the first person to ask this question on this site, but none of the previous questions on this topic had an answer, so I'm hoping someone will answer mine :) I have a form made with Flask-WTF. In that form, there is a SelectMultipleField called relAffil and a SelectField called relImp. I would like to hide the relImp field and only show it once an answer has been selected for relAffil. If relAffil is left blank, the relImp field should stay hidden. Based on my research, the only way to do this is with JavaScript, but my attempts have shown no results. Here's my python form code:

ratings = [(i,str(i)) for i in range(1,11)] #choices 1-10

religionChoices = [(1,'Roman Catholic'), (2,'Other Christian'), (3,'Other Religious'), (4,'Non-secular')]

class Questionnaire(Form):
    relAffil = SelectMultipleField("What do you want your college's religious affiliation to be?",choices=religionChoices,coerce=int)
    relImp = SelectField("On a scale of 1-10, how important is the college's religious affiliation to you?",choices = ratings,coerce=int)

Here's my HTML (if it matters, the CSS comes from Bulma):

<form method="POST" action="/getStarted" role="form">
{{ form.csrf_token }}

<div >
    <div class ="control">
        {{ form.relAffil.label(class_="label") }}
        <div class = "select is-multiple">
        {{ form.relAffil(class_="select is-multiple",size=3) }}
        </div>
    </div>
</div>

<br>
<div >
    <div >
        {{ form.relImp.label(class_="label") }}
        <div class = "select is-rounded">
        {{ form.relImp(class_="select is-rounded") }}
        </div>
    </div>
</div>
</form>

<script src="jquery-3.6.0.min.js">
(function ($) {
  window.onload = function() {

  if ($("#relAffil").val().length == 0) {
    $('#relImp').hide();
  }

$("#relAffil").change(function() {
  if ($(this).val().length == 0) {
    $('#relImp').hide();
  } else {
    $('#relImp').show();
  }
});
}});
</script>

This simply doesn't work - there are no errors, the form just loads as if the script isn't there. I have no experience at all in JS and the code is simply copied from elsewhere, so most likely that is where the problem is. Does anyone know how to solve this?

CodePudding user response:

OK, I got it! Thank you very much, @MarcusWilliams, for setting me on the right path. In addition to my comments above, all that was missing was an onclick="religionSelected()" within the select tag. So, my updated HTML code is this:

<form method="POST" action="/getStarted" role="form">
{{ form.csrf_token }}

<div >
    <div class ="control">
        {{ form.relAffil.label(class_="label") }}
        <div class = "select is-multiple" onclick="religionSelected()">
        {{ form.relAffil(class_="select is-multiple",size=3) }}
        </div>
    </div>
</div>

<br>
<div  id = "relImp">
    <div >
        {{ form.relImp.label(class_="label") }}
        <div class = "select is-rounded">
        {{ form.relImp(class_="select is-rounded") }}
        </div>
    </div>
</div>
<script>
    window.onload = religionSelected()
    document.getElementById("relAffil").onclick = religionSelected()

    function religionSelected(){
        "use strict";
        var religion = document.getElementById('relAffil').selectedOptions;
        if(religion.length != 0 ){
             document.getElementById("relImp").style.display = 'block';
        }else{
            document.getElementById("relImp").style.display = 'none';
        }
    };

 </script>

</form>

CodePudding user response:

You can use javascript to check the data of the form and then display or hide the other object depending on what it is, I think something like this would work for you.

First give your select field an id and give the div containing relimp and id, something like this:

{{ form.relAffil(class_="select is-multiple",size=3", religionSelect") }}

<div class = "select is-rounded religionRating">
        {{ form.relImp(class_="select is-rounded") }}
</div>

Then your javascript can look something like this (Note: I use the example id's from above in this):


<script>
        window.onload = religionSelected()
        document.getElementById("relgionSelect").onclick = religionSelected()

        function religionSelected(){
            "use strict";
            var religion = document.getElementById('relgionSelect').selectedOptions[0].value;
            if( religion != ""){
                 document.getElementById("religionRating").style.display = 'block';
            }else{
                document.getElementById("religionRating").style.display = 'none';
            }
        };
 

<\script>

This works if you have the first option of the select list just be blank, if that is what is currently selected then the second part will be hidden. If the unselected option is not blank by default you may need to add another option to your select field that is just blank and make that what is first selected when the form loads.

I am also quite new to all of this, so apologies if this doesn't help at all. Let me know if it does!

  • Related