Flask WTForms Validator Message changes layout

Issue

I’m using WTForms in Flask and am validating Form inputs on submission.
The problem I’m facing occurs with the use of wtforms validators. in particular, the error messages on validation are changing the layout of my HTML page. Code is as follows, Screenshots of changes are also included.

forms.py

from flask_wtf import FlaskForm
from wtforms import FieldList, FormField, HiddenField, validators
from wtforms.fields import StringField


class SingleGuessForm(FlaskForm):
    # load list of accepted vocab
    class Meta:
        csrf = False
    with open('accepted_words.txt') as f:
        l = f.readlines()
    l = [s.rstrip() for s in l]

    guess = StringField(validators=[validators.Required(message='Guess is required'), validators.AnyOf(l, message='Guess is not in vocabulary.')])


class SentenceForm(FlaskForm):
    # Disable CSRF for this class.
    class Meta:
        csrf = False

    guess_form = FieldList(FormField(SingleGuessForm), min_entries=5, max_entries=5) 

    id = HiddenField()

page.html (relevant part)

<form action="" method="POST" id="overall_guess_form">
    <table class="table">
        <tr>
            <td>
                <div class="audio_elements">
                    <audio controls class="sentence_audio"
                           id="{{ form.id.data }}">
                        <source src="{{ form.path.data }}"
                                type="audio/wav">
                    </audio>
                    <span class="iconify check_mark"
                          data-icon="emojione:check-mark-button"
                          style="visibility: hidden;"
                          data-inline="false"></span>
                </div>
            </td>
            <td style="width: 100%">
            <form class="guess_fields">
                {% for single_word_guess in form.guess_form %}
                    {{ single_word_guess.form.guess(class_='guess_box') }}
                    {{ single_word_guess.form.hidden_tag() }}
                    {{ single_word_guess.form.crsf_token }}
                    {# print errors if someone made one. Let's see if this works #}
                     {% for field, errors in single_word_guess.form.errors.items() %}
                        <small class="form-text text-muted ">
                            {{ ', '.join(errors) }}
                        </small>
                    {% endfor %}
                {% endfor %}
            </form>
            </td>
        </tr>
    </table>

    {{ form.hidden_tag() }}
    {{ form.crsf_token }}

    <div class="input submit" style="text-align: center">
        <input id="submit-button" class="btn btn-primary" type="submit"
               name="submitButton"
               value="Continue"/>
    </div>
</form>

style.css

.guess_fields {
    display: inline;
    margin: auto;
}

.guess_box {
    margin-top: 2%;
    width: 18%;
}

This is what my rendered HTML looks like before submission – the input text fields are nicely put next to each other, as they are supposed to:
enter image description here

But after sumission, the layout changes to this:

enter image description here

I’ve tried making the error message shorter (just ‘test’) because I suspected the text below to be too long, but that didn’t make a difference. How do I keep my input fields in row here, with the potential error messages appearing below its corresponding TextField?

Solution

Did you have a look at the source code in your browser before and after submitting the form ? I suspect that the issue is caused by the legends (<small class="form-text text-muted ">), that appear after submission, when errors are reported.

I guess you are using Bootstrap, so I suggest that you have a look at the form layout help, to restructure your form as an inline form. The available Bootstrap classes should suffice.

Answered By – Anonymous

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published