I have a form where there are 14 questions, 4 option for each question, 1 correct answer, and a timer field that has to be rendered on the page something like this:
Expected form format
Help me in understanding and using WTFroms along with bootstrap to make my form look like this:
Currently, this is how it looks:
Current form format
Code for forms.py:
class XMLQuestionForm(FlaskForm):
question = FieldList(StringField('Question', validators=[DataRequired(), Length(max=395)]), min_entries=14, max_entries=14 )
optionA = FieldList(StringField('Option A', validators=[DataRequired(), Length(max=85)]), min_entries=14, max_entries=14)
optionB = FieldList(StringField('Option B', validators=[DataRequired(), Length(max=85)]), min_entries=14, max_entries=14)
optionC = FieldList(StringField('Option C', validators=[DataRequired(), Length(max=85)]), min_entries=14, max_entries=14)
optionD = FieldList(StringField('Option D', validators=[DataRequired(), Length(max=85)]), min_entries=14, max_entries=14)
answer = FieldList(SelectField('Answer', validators=[DataRequired()], choices=[(None,'<Select an answer>'),('Option A','Option A'),('Option B','Option B'),('Option C','Option C'),('Option D','Option D')]), min_entries=14, max_entries=14)
timer = FieldList(IntegerField('Timer', default=60), min_entries=14, max_entries=14)
submit = SubmitField('Generate XML')
Code for home.html
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">KBC Question XML Creator</legend>
{% for n in range(14) %}
<!-- Question -->
{% if form.question[n].errors %}
{{ form.question[n](class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.question[n].label }} {{ loop.index }} {{ form.question[n](class="form-control form-control-lg") }}
{% endif %}
<!-- Options -->
{% if form.optionA[n].errors %}
{{ form.optionA[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionA[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.optionA[n].label }} {{ form.optionA[n](class="form-control col-sm-2") }}
{% endif %}
{% if form.optionB[n].errors %}
{{ form.optionB[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionB[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.optionB[n].label }} {{ form.optionB[n](class="form-control col-sm-2") }}
{% endif %}
{% if form.optionC[n].errors %}
{{ form.optionC[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionC[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.optionC[n].label }} {{ form.optionC[n](class="form-control col-sm-2") }}
{% endif %}
{% if form.optionD[n].errors %}
{{ form.optionD[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionD[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.optionD[n].label }} {{ form.optionD[n](class="form-control col-sm-2") }}
{% endif %}
<!-- Answer -->
{% if form.answer[n].errors %}
{{ form.answer[n](class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.answer[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.answer[n].label }} {{ form.answer[n](class="form-control col-sm-4") }}
{% endif %}
<!-- Timer -->
{% if form.timer[n].errors %}
{{ form.timer[n](class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.timer[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.timer[n].label }} {{ form.timer[n](class="form-control col-sm-4") }}
{% endif %}
<hr>
{% endfor %}
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}
Bootstrap's grid system works based on a 12 column system.
So for example, if you had 2 elements you wanted to display in the same row and give both an equal amount of space, you would give each of them 6 of the columns, each.
e.g. ->
<div class="row>
<h1 class="col-md-6">Hello</h1>
<h1 class="col-md-6">World</h1>
</div>
In your case where you needed to split up 8 pieces (4 answer labels, and 4 form boxes), it gets a bit more complex.
Once you give a DIV a set amount of the columns, inside that div, you distribute it based on the 12 column system still, even if 12 are not actually available.
Let's look at how I solved it in the solution I sent you below.
I started with putting half of the elements nested inside a div with class "col-md-6 row"
And the other half with the same.
Now when we are looking inside one of those halves, the moment we are nested inside, we are distribute those 6 columns based on the 12 grid system again.
So for example I could have given each of the 4 elements 3 each, class="col-md-3".
But since it seemed that you wanted the form field a bit larger than the text field, I went w/ "col-md-4" for the form fields and "col-md-2" for the text fields.
Here is what the solution looks like on my end -> https://imgur.com/gallery/ylMWjFN
I had to throw together an entire application to solve this so I went ahead and threw it on github for you if you want to look at the code there -> https://github.com/CraftyClark/ontrolling-the-styling-of-bootstrap-form-in-flask-wtforms/tree/main/application
Cheers,
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">KBC Question XML Creator</legend>
{% for n in range(14) %}
<div class="row col-md-10">
<!-- Question -->
{% if form.question[n].errors %}
{{ form.question[n](class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.question[n].label }} {{ loop.index }} {{ form.question[n](class="form-control form-control-lg") }}
{% endif %}
</div>
<br>
<!-- start of options row -->
<div class="row">
<!-- Options -->
<div class="col-md-6 row">
{% if form.optionA[n].errors %}
{{ form.optionA[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionA[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
<div class="form-group col-md-2">
{{ form.optionA[n].label(class="form-control-label") }}
</div>
<div class="form-group col-md-4">
{{ form.optionA[n](class="form-control form-control-lg") }}
</div>
{% endif %}
{% if form.optionB[n].errors %}
{{ form.optionB[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionB[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
<div class="form-group col-md-2">
{{ form.optionB[n].label(class="form-control-label") }}
</div>
<div class="form-group col-md-4">
{{ form.optionB[n](class="form-control form-control-lg") }}
</div>
{% endif %}
</div>
<div class="col-md-6 row">
{% if form.optionC[n].errors %}
{{ form.optionC[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionC[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
<div class="form-group col-md-2">
{{ form.optionC[n].label(class="form-control-label") }}
</div>
<div class="form-group col-md-4">
{{ form.optionC[n](class="form-control form-control-lg") }}
</div>
{% endif %}
{% if form.optionD[n].errors %}
{{ form.optionD[n](class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.optionD[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
<div class="form-group col-md-2">
{{ form.optionD[n].label(class="form-control-label") }}
</div>
<div class="form-group col-md-4">
{{ form.optionD[n](class="form-control form-control-lg") }}
</div>
{% endif %}
</div>
</div>
<!-- end of options row -->
<!-- Answer -->
{% if form.answer[n].errors %}
{{ form.answer[n](class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.answer[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.answer[n].label }} {{ form.answer[n](class="form-control col-sm-4") }}
{% endif %}
<!-- Timer -->
{% if form.timer[n].errors %}
{{ form.timer[n](class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.timer[n].errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.timer[n].label }} {{ form.timer[n](class="form-control col-sm-4") }}
{% endif %}
<hr>
{% endfor %}
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}
I am attempting to learn Django but keep receiving the error " 'endfor', expected 'endblock'. Did you forget to register or load this tag? " when I add the {% for key,value in
price.DISPLAY.items %} {{ key }} {% endfor %} part of the code. How can I fix this? Any help would be great thanks.
home.html
{% extends 'base.html' %} {% block content %} {% for key,value in
price.DISPLAY.items %} {{ key }} {% endfor %}
<br />
<br />
{{ price.DISPLAY }}
<div class="jumbotron">
<h1 class="display-4">Welcome</h1>
</div>
<div class="container">
<div class="row">
{% for info in api.Data %}
<div class="card" style="width: 18rem">
<img src="{{info.imageurl}}" class="card-img-top" alt="{{info.source}}" />
<div class="card-body">
<h5 class="card-title">{{info.title}}</h5>
<p class="card-text">{{info.body}}</p>
<a href="{{info.url}}" class="btn btn-secondary" target="_blank"
>Read more</a
>
</div>
</div>
{% endfor %}
</div>
</div>
{{ api.Data }} {% endblock content %}
A template tag should not span multiple lines. You should write the {% for … %} tag on a single line:
{% extends 'base.html' %} {% block content %}
{% for key,value in price.DISPLAY.items %} {{ key }} {% endfor %}
…
{% endblock content %}
I want registration and log in form in same page and in same html file. when i render form1 i have problem. i search in google but can't fix. can i render two form same html?
this is code --->
{% extends 'base.html' %}
<link rel="stylesheet" type="text/css" href="/static/css/style.css?{% now "U" %}" />
{% block content %}
<form action = '' method="post" novalidate="novalidate" id="reg" >
{% csrf_token %}
<div class="continer">
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
{% endfor %}
<button type="submit" name="register" id="btn" >registraton</button>
<button type="button" name="log" id="lgn">login</button>
</div>
</form>
<form action="" method="post" novalidate="novalidate" id="log">
{% csrf_token %}
<div class="continer2">
{% for field in form1 %}
{{ field }}
</div>
</form>
{% endblock %}
You're missing an endfor for the last for loop:
{% for field in form1 %}
{{ field }}
{% endfor %}
The error message indicated that you might be missing an endwith or endfor which is a hint to look for a with or for that hasn't been closed.
I am using Django Allauth for user flow in my project. I have successfully created my own set of templates which inherit from the standard Allauth templates and they work 95%. For some reason, however, I do not receive an error for an invalid login.
If I enter 'test#email' for the user I get a 'Please enter a valid email address' error but if I enter a proper email with an incorrect password it simply reloads the page but with no errors as to what went wrong. I've included my template below which has the {{ form.login.errors }} and {{ form.password.errors }} tags.
All guidance is appreciated, thank you.
Template:
<div id="search_container">
<div id="search_box_content">
{% block page_content %}
<h4>Login</h4>
<form class="" id="user-form" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
<h1> {{ form.login.errors }}</h1>
<h1> {{ form.password.errors }}</h1>
<div class="input_class">
<label for="login">Username: </label>
{{ form.login }}
</div>
<div class="input_class">
<label for="password">Password: </label>
{{ form.password }}
</div>
<div class="input_class" id="forgot_pass">
<label for="remember">
Remember Me? </label>
{{ form.remember }}
</div>
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<div id="modal_bottom_bar">
<a class="button secondaryAction" id="forgot_pass" href="{% url 'account_reset_password' %}">Forgot your Password?</a>
<button class="primaryAction" id="login_submit" type="submit">Login</button></div>
</form>
{% endblock %}
</div>
</div>
Some errors are non field errors such as those errors which are raised for some custom validation and are not included in field.errors rather they are in form.non_field_errors:
So better use this snippet to show all errors which belongs to fields and to custom validation if you are rendering your form manually:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
i wonder how i can add some extra html to a certain field in a template in Django
I have the following form (forms.py)
first_name = forms.CharField(widget=forms.TextInput(attrs={'required': 'required'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'required': 'required'}))
street = forms.CharField(widget=forms.TextInput(attrs={'required': 'required'}))
In my template i get the fields with:
<form action="" method="post">{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<input type="submit" value="Submit" />
</form>
Now i want to add some extra html to the street field like this
<form action="" method="post">{% csrf_token %}
{% for field in form %}
{% if field.type =='street' %}
<div class="fieldWrapper otherclass">
<hr>
{% else %}
<div class="fieldWrapper">
{% endif %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<input type="submit" value="Submit" />
</form>
The whole thing fails:
Could not parse the remainder: '=='street'' from '=='street''
Template operators require a space before and after so replace
{% if field.type =='street' %}
with
{% if field.type == 'street' %}
or use the ifequal templatetag
{% ifequal field.type 'street' %}
Hello world.
{% else %}
Apocalypse
{% endifequal %}