Looking to add an icon toggle to a password field.
In my forms.py I have:
class LoginForm(FlaskForm):
email = StringField("Email Address", validators=[DataRequired(), Email()])
eye_icon = Markup('<i class="icon-eye" id="togglePassword" style="margin-left: -30px; cursor: pointer;"></i>') # Not currently doing anything
password = PasswordField("Password", validators=[DataRequired()])
And in my login.html
<div class="form-group">
{% if form.email.errors %}
{{ form.email(class_="form-control is-invalid", placeholder="Email") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span> {{ error }} </span>
{% endfor %}
</div>
{% else %}
{{ form.email(class_="form-control ", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if form.password.errors %}
{{ form.password(class_="form-control is-invalid", placeholder="Password") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span> {{ error }} </span>
{% endfor %}
</div>
{% else %}
{{ form.password(class_="form-control shadow-none", placeholder="Password") }}
<i class="icon-eye" id="togglePassword" style="margin-left: -30px; cursor: pointer;"></i>
{% endif %}
</div>
And I have my JS that toggles between showing the password. I just don't see how I can get the eye icon to show on the right of the password field like it shows on most login screens
I had to wrap the tag in a span tag, and add a class to my css to get it to work:
{{ form.password(class_="form-control ", placeholder="Password") }}
<span class="p-viewer"><i class="icon-eye" id="togglePassword" style="margin-left: 100px; cursor: pointer;"></i></span>
and css:
.p-viewer {
z-index: 9999;
position: absolute;
top: 30%;
right: 10px;
}
you could remove the styling from the password field, and apply it to a div that surrounds both the password field and the icon.
Related
While "DataRequired" and "NumberRange" produce a pop-up error message, "EqualTo" (and my own custom "MoreThan") do not. How can I get them to also produce a pop-up message?
####################################################################
My form has three fields. "min_nFeatures" has to be lower than "max_nFeatures", so I changed the code of the "EqualTo" validator to "MoreThan" (as advised in Code a validator for a WTForms form which compares the inputs from two fields). The validator is working: if the user enters a larger value for "min_nFeatures", it does not go through (it returns to the same page). However, there is no pop-up message as with the other built-in validators (for example, if the user does not enter anything, there's a pop-up "Please fill out this field"). I would like the same behavior for the custom validator.
My code:
class MoreThan(object):
def __init__(self, fieldname, message=None):
self.fieldname = fieldname
self.message = message
def __call__(self, form, field):
try:
other = form[self.fieldname]
except KeyError:
raise ValidationError(field.gettext("Invalid field name '%s'.") % self.fieldname)
if field.data <= other.data:
d = {
'other_label': hasattr(other, 'label') and other.label.text or self.fieldname,
'other_name': self.fieldname
}
message = self.message
if message is None:
message = field.gettext(
'The maximal number of expressed genes has to be larger than the minimal number of expressed genes')
raise ValidationError(message)
class vln_plot_form(FlaskForm):
min_nFeatures = IntegerField('* Minimal number of expressed genes:', validators=[DataRequired()])
max_nFeatures = IntegerField('* Maximal number of expressed genes:',
validators=[DataRequired(), MoreThan('min_nFeatures')])
max_mtpercent = IntegerField('Maximal percent of mitochondrial gene expression:', validators=[NumberRange(1, 100)])
submit = SubmitField('Submit')
view:
#app.route('/vln', methods=['POST', 'GET'])
def violin_plots():
...
form = vln_plot_form()
if request.method == 'POST':
if form.validate_on_submit():
...
return redirect(url_for('next_page'))
return render_template('violin_plots.html', form=form)
I read Message not flashing on some WTForm validation methods but could not apply it to my case.
########################################################################
edit:
Here's my HTML code:
{% extends 'base.html' %}
{% block head %}
<title>HELLO</title>
{% endblock %}
{% block body %}
<center><h1>Run!</h1></center>
<h2>Step 2/3</h2>
<figure>
<img src={{ vln_plot_file }} align="middle" alt="vln_plot" style="width:70%">
</figure>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-horizontal">
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.min_nFeatures.label }}</label>
{{ form.min_nFeatures }}
</div>
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.max_nFeatures.label }}</label>
{{ form.max_nFeatures }}
</div>
{% if with_mt %}
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.max_mtpercent.label }}</label>
{{ form.max_mtpercent }}
</div>
{% endif %}
<div class="form-group">
{{ form.csrf_token() }}
{{ form.submit(class="btn btn-primary")}}
</div>
</div>
{% if form.errors %}
{{ form.errors }}
{% endif %}
</form>
{% endblock %}
Since I added "{{ form.errors }}" at the end of the HTML, I do see the correct form.errors at the bottom of the webpage, but this is of course a very ugly way to display the errors...
This should do the trick:
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-horizontal">
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.min_nFeatures.label }}</label>
{{ form.min_nFeatures }}
{% for error in form.min_nFeatures.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.max_nFeatures.label }}</label>
{{ form.max_nFeatures }}
{% for error in form.max_nFeatures.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
{% if with_mt %}
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.max_mtpercent.label }}</label>
{{ form.max_mtpercent }}
{% for error in form.max_mtpercent.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
{% endif %}
<div class="form-group">
{{ form.csrf_token() }}
{{ form.submit(class="btn btn-primary")}}
</div>
</div>
</form
Note how I manage the display of errors for each of the fields individually.
So I have 2 forms, login form and registration form, on home.html, which show up as a modal when clicked on the login button, which looks like as follows:
home.html
<button type="button" class="btn btn-outline-danger" data-bs-toggle="modal" data-bs-target="#loginModal">
Login
</button>
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Sign In</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<button id="login" class="btn btn-login btn-md">Log In</button>
<button id="regis" class="btn btn-login btn-md">Register</button><hr style="margin-top: 0px;">
<div class="" id="login">
<form method="POST" action="">
{{ login_form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{% if login_form.email_login.errors %}
{{ login_form.email_login(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in login_form.email_login.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ login_form.email_login(class="form-control form-control-md mb-2", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if login_form.password_login.errors %}
{{ login_form.password_login(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in login_form.password_login.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ login_form.password_login(class="form-control form-control-md mb-2", placeholder="Password") }}
{% endif %}
</div>
<div class="form-check">
{{ login_form.remember(class="form-check-input") }}
{{ login_form.remember.label(class="form-check-label") }}
</div>
</fieldset>
<div class="form-group">
{{ login_form.submit_login(class="btn btn-danger") }}
<small class="text-muted ml-2">
Forgot Password?
</small>
</div>
</form>
</div>
<div class="" id="regis">
<form method="POST" action="">
{{ regis_form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{% if regis_form.username_regis.errors %}
{{ regis_form.username_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.username_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.username_regis(class="form-control form-control-md mb-2", placeholder="Username") }}
{% endif %}
</div>
<div class="form-group">
{% if regis_form.email_regis.errors %}
{{ regis_form.email_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.email_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.email_regis(class="form-control form-control-md mb-2", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if regis_form.password_regis.errors %}
{{ regis_form.password_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.password_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.password_regis(class="form-control form-control-md mb-2", placeholder="Password") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ regis_form.submit_regis(class="btn btn-danger") }}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
The two "Log In" and "Register" buttons are tabs i.e. by clicking on "Register" button you will see registration form and vice versa which is controlled by JavaScript.
My forms.py file looks like this:
forms.py
class RegistrationForm(FlaskForm):
username_regis = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)])
email_regis = StringField('Email',
validators=[DataRequired(), Email()])
password_regis = PasswordField('Password', validators=[DataRequired()])
submit_regis = SubmitField('Sign Up')
class LoginForm(FlaskForm):
email_login = StringField('Email',
validators=[DataRequired(), Email()])
password_login = PasswordField('Password', validators=[DataRequired()])
remember = BooleanField('Remember Me')
submit_login = SubmitField('Login')
and below is the routes.py function:
routes.py
#app.route("/", methods=['GET', 'POST'])
def home():
login_form = LoginForm()
regis_form = RegistrationForm()
if request.method == 'POST':
if login_form.validate_on_submit() and login_form.submit_login.data:
user = User.query.filter_by(email=login_form.email_login.data).first()
if user and bcrypt.check_password_hash(user.password, login_form.password_login.data):
login_user(user, remember=login_form.remember.data)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
if regis_form.validate_on_submit() and regis_form.submit_regis.data:
hashed_password = bcrypt.generate_password_hash(regis_form.password_regis.data).decode('utf-8')
user = User(username=regis_form.username_regis.data, email=regis_form.email_regis.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('home'))
return render_template('home.html', login_form=login_form, regis_form=regis_form)
Now, The problem is that when I try to login using an email that is not registered it flashes me
'Login Unsuccessful. Please check email and password'
which is ok as it should do this. but when I open the login modal again and open the registration tab, the * username_regis password_regis and email_regis* fields are showing me 'The field is required' error.
It should not show me this error on registration form because I never submitted this form.
I want to get rid of these error messages. I will deeply appreciate any help.
The code you wrote is as follows:
if request.method == 'POST':
if login_form.validate_on_submit() and login_form.submit_login.data:
<SNIP>
if regis_form.validate_on_submit() and regis_form.submit_regis.data:
<SNIP>
That means that both forms are are validated, no matter what form you submit. So when you submit one form the other will always show errors. The preferred solution is to post to different routes. On your form the action parameter will need to be filled and you will need two functions, one for each route. You than will also get rid of asking if form data is available. It must be, because you are on that route.
Hey there im finishing my little app which is an online platform that sells tickets for events. Im currently having some problems when the user goes out of the page. I want to get rid of the data that he has already submitted. This happens when the promoter of the event wants to create a party, there´s two "stages" the event info and the tickets info. Im handling this with javascript´s "beforeunload" but im stuck. Could anyone give me a hint? Thank you by the way guys.
I don´t have a particular error, i would just like to get rid of the unfinished posts after the user leaves.
routes
#app.route("/post/new",methods=["GET","POST"])
#login_required
def new_post():
#event forms
post_form=PostForm()
#valdiating the submission of those forms
if post_form.validate_on_submit():
if post_form.image_file.data:
picture_file=save_picture(post_form.image_file.data)
#loading to our database
post=Post(title=post_form.title.data,content=post_form.content.data,start_dh=post_form.start_dh.data,
finish_dh=post_form.finish_dh.data,image_file=picture_file,author=current_user)
db.session.add(post)
db.session.commit()
flash("create your tickets now", "success")
return redirect(url_for("tickets", post_id=post.id))
return render_template("create_post.html",title="new post",post_form=post_form,legend="New Event")
#create new tickets
#app.route("/ticket/<int:post_id>",methods=["GET","POST"])
#login_required
def tickets(post_id):
post=Post.query.get_or_404(post_id)
ticket_form=TicketForm()
#this variable give us the id of the last post that this user posted
post_relation=Post.query.filter_by(user_id=current_user.id).order_by(Post.date_posted.desc()).first()
#submission
if ticket_form.validate_on_submit():
tickets=Tickets(ticket_type=ticket_form.ticket_type.data,ticket_quantity=ticket_form.ticket_quantity.data,
price_ticket=ticket_form.price_ticket.data, start_dh_tickets=ticket_form.start_dh_tickets.data,
finish_dh_tickets=ticket_form.finish_dh_tickets.data,event=post_relation)
db.session.add(tickets)
db.session.commit()
flash("your tickets have been created","success")
return redirect(url_for("tickets",post_id=post.id))
tick=Tickets.query.order_by(Tickets.post_id)
return render_template("create_ticket.html",title="tickets",ticket_form=ticket_form,tick=tick,post_id=post.id)
html/javascript
creating the tickets front end
<div class="content-section">
<form method="POST" action="" onsubmit="setFormSubmitting()">
{{ticket_form.hidden_tag()}}
<fieldset class="form-group">
<div class="form-group">
{{ticket_form.ticket_quantity.label(class="form-control-label")}}
{% if ticket_form.ticket_quantity.errors %}
{{ticket_form.ticket_quantity(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in form.ticket_quantity.errors %}
<span> {{error}}</span>
{% endfor %}
</div>
{% else %}
{{ ticket_form.ticket_quantity(class="form-control-label") }}
{% endif %}
</div>
<div class="form-group">
{{ticket_form.ticket_type.label(class="form-control-label")}}
{% if ticket_form.ticket_type.errors %}
{{ticket_form.ticket_type(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in ticket_form.ticket_type.errors %}
<span> {{error}} </span>
{% endfor %}
</div>
{% else %}
{{ ticket_form.ticket_type(class="form-control-label")}}
{% endif %}
</div>
<div class="form-group">
{{ticket_form.price_ticket.label(class="form-control-label")}}
{% if ticket_form.price_ticket.errors %}
{{ticket_form.price_ticket(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in ticket_form.price_ticket.errors %}
<span> {{error}} </span>
{% endfor %}
</div>
{% else %}
{{ ticket_form.price_ticket(class="form-control-label")}}
{% endif %}
</div>
<div class="form-group">
{{ticket_form.start_dh_tickets.label(class="form-control-label")}}
{% if ticket_form.start_dh_tickets.errors %}
{{ticket_form.start_dh_tickets(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in ticket_form.start_dh_tickets.errors %}
<span> {{error}} </span>
{% endfor %}
</div>
{% else %}
{{ ticket_form.start_dh_tickets(class="form-control-label")}}
{% endif %}
</div>
<div class="form-group">
{{ticket_form.finish_dh_tickets.label(class="form-control-label")}}
{% if ticket_form.finish_dh_tickets.errors %}
{{ticket_form.finish_dh_tickets(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in ticket_form.finish_dh_tickets.errors %}
<span> {{error}} </span>
{% endfor %}
</div>
{% else %}
{{ ticket_form.finish_dh_tickets(class="form-control-label")}}
{% endif %}
</div>
<div class="form-group">
{{ticket_form.submit_ticket(class="btn btn-primary")}}
</div>
</fieldset>
</form>
</div>
<script type="text/javascript">
var formSubmitting = false;
var postComplete= true;
var setFormSubmitting = function() { formSubmitting = true; };
var setPostComplete=function() { postComplete=false; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'you want to leave? your data will be lost';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
</script>
creating the post frontend
<div class="content-section">
<form method="POST" action="" enctype="multipart/form-data" onsubmit="setFormSubmitting()">
{{post_form.hidden_tag()}}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> {{ legend }}</legend>
<div class="form-group">
{{post_form.title.label(class="form-control-label")}}
{% if post_form.title.errors %}
{{post_form.title(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in post_form.title.errors %}
<span> {{error}}</span>
{% endfor %}
</div>
{% else %}
{{ post_form.title(class="form-control-label")}}
{% endif %}
</div>
<div class="form-group">
{{post_form.content.label(class="form-control-label")}}
{% if post_form.content.errors %}
{{post_form.content(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in post_form.content.errors %}
<span> {{error}} </span>
{% endfor %}
</div>
{% else %}
{{ post_form.content(class="form-control-label")}}
{% endif %}
</div>
<!-- section for setting the date and hour of the event-->
<!-- starting date hour-->
<div class="form-group">
{{post_form.start_dh.label(class="form-control-label")}}
{% if post_form.start_dh.errors %}
{{post_form.start_dh(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in post_form.start_dh.errors %}
<span> {{error}}</span>
{% endfor %}
</div>
{% else %}
{{ post_form.start_dh(class="form-control-label")}}
{% endif %}
<!-- finish -->
<div class="form-group">
{{post_form.finish_dh.label(class="form-control-label")}}
{% if post_form.finish_dh.errors %}
{{post_form.finish_dh(class="form-control form-control-lg is-invalid")}}
<div class="invalid-feedback">
{% for error in post_form.finish_dh.errors %}
<span> {{error}} </span>
{% endfor %}
</div>
{% else %}
{{ post_form.finish_dh(class="form-control-label")}}
{% endif %}
</div>
<!-- image -->
<div class="form-group">
{{post_form.image_file.label()}}
{{post_form.image_file(class="form-control-file")}}
{% if post_form.image_file.errors %}
{% for error in post_form.image_file.errors %}
<span class="text-danger"> {{error}} </span></br>
{% endfor %}
{% endif %}
</div>
<div class="form-group">
{{post_form.submit_post(class="btn btn-primary")}}
</div>
</fieldset>
</form>
</div>
<script type="text/javascript">
var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
</script>
databases
class Post(db.Model):
#unique id for the user
id= db.Column(db.Integer, primary_key=True)
#name of the event
title= db.Column(db.String(100), nullable=False)
#when the event was posted
date_posted= db.Column(db.DateTime, nullable=False, default=datetime.now())
#description of the event
content= db.Column(db.Text, nullable=False)
#start date and hour of the event
start_dh= db.Column(db.DateTime, nullable=False)
#finish date and hour of the event
finish_dh= db.Column(db.DateTime, nullable=False)
#image of the flyer for the post
image_file= db.Column(db.String(20), nullable=False, default="default.jpg")
#linking the post table with the user
user_id= db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
#relation with the ticket model
ticket=db.relationship("Tickets", backref="event", lazy=True)
#relation ship with the customer
customer=db.relationship("Customer", backref="party", lazy=True)
#this is a method that declares how our class is going to be printed out
def __repr__(self):
return "%s,%s,%s,%s,%s" % (self.user_id,self.title,self.date_posted,self.content,self.image_file)
#data base for the tickets
class Tickets(db.Model):
#unique id for the user
id= db.Column(db.Integer, primary_key=True)
#name or kind of the event, this is set by the creators
ticket_type=db.Column(db.String(20), nullable=False)
#initial stock of the ticket
ticket_quantity=db.Column(db.Integer,nullable=False)
#initial price of this kind of ticket
price_ticket=db.Column(db.Integer, nullable=False)
#start date and hour of the event
start_dh_tickets=db.Column(db.DateTime, nullable=False)
#finish date and hour of the event
finish_dh_tickets=db.Column(db.DateTime, nullable=False)
#id of the event we have a relationship with
post_id= db.Column(db.Integer, db.ForeignKey("post.id"), nullable=False)
#this is a method that declares how our class is going to be printed out
def __repr__(self):
return "%s,%s,%s,%s,%s,%s" % (self.post_id,self.ticket_type, self.ticket_quantity,self.price_ticket,self.start_dh_tickets,self.finish_dh_tickets)
You can use warn message to user from browser in JavaScript:
window.onbeforeunload = function(){
return 'Are you sure you want to leave?';
};
Or you can send data to Flask server immidiately after user changes the inputs and after click on the button, you can officially proceed them.
I have a problem I have a site which displays users but it displays users not in a straight line but in an inverted pyramid. It could be because I am using django-filter app but it shouldnt create a problem as such. The profiles right at the end (especially in the mobile view) overlap and drag. It gets worse as profiles increase. Is it possible to align the profiles or user list in a straight line?
Please find below my code.
filters.py(for djang-filters app)
import django_filters
from userprofile.models import UserProfiles
class UserProfilesFilter(django_filters.FilterSet):
class Meta:
model = UserProfiles
fields = ['gender', 'age', 'Nationality','preference', 'Country',
'City']
views.py
#login_required
def profiles_list(request):
filter = UserProfilesFilter(request.GET, queryset =
UserProfiles.objects.all().order_by('-pub_date'))
return render(request,"userprofile/user_list.html", {'filter': filter})
user_list.html
{% extends 'base.html' %}
{% block content %}
{% load static %}
{% load bootstrap %}
<div class="container">
<form class="form-horizontal col-md-4 col-lg-4 col-sm-4" action=""
method="get">
{{ filter.form|bootstrap}} {% csrf_token %}
<input type="submit" value='search'/>
</form>
{% for profile in filter.qs %}
<div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
<hr>
<a href="{% url 'userprofile:profileview' profile.user %}"><h3>{{
profile.user }}</h3></a>
<br>
<img src="{{ profile.image.url }}" class="rounded mx-auto d-block img-
responsive float-left" style= "max-height: 100px; max-width: 100px;">
<br><br>
<br><br> <br>
<div class="font-weight-normal text-justify">
Gender: {{ profile.gender }}
<br>
Country: {{ profile.Country }}
<br>
Description: {{ profile.summary }}
<br>
Preferences: {{ profile.preference }}
<br><br>
{% endfor %}
</div>
</div>
<!--adnow ad-->
<script type="text/javascript">
(sc_adv_out = window.sc_adv_out || []).push({
id : "575193",
domain : "n.ads1-adnow.com"
});
</script>
<script type="text/javascript" src="//st-n.ads1-adnow.com/js/a.js">
</script>
<div id="SC_TBlock_575193" class="SC_TBlock">loading...</div>
<!--adnow finishes-->
{% endblock %}
You should close your div tags in each for loop, since you start them within the loop.
Change:
{% endfor %}
</div>
</div>
to:
</div>
</div>
{% endfor %}
I am using wtforms-recaptcha in order to get the Recaptcha to show.
pip install wtforms-recaptcha
I guided myself on this site to make the installation:
https://pypi.python.org/pypi/wtforms-recaptcha
The problem is that the recaptcha code is being echoed into the form. That is, I see the recaptcha's code on the form and not the recaptcha itself:
<script type="text/javascript" src="https://www.google.com/recaptcha/api/challenge?k=6LeCJvUSAAAAAAvqwJEueVdV0wyNLPtX6KWSTdXp"> </script> <noscript> <iframe src="https://www.google.com/recaptcha/api/noscript?k=6LeCJvUSAAAAAAvqwJEueVdV0wyNLPtX6KWSTdXp" height="300" width="500" frameborder="0"></iframe><br> <textarea name="recaptcha_challenge_field" rows="3" cols="40"> </textarea> <input type="hidden" name="recaptcha_response_field" value="manual_challenge"> </noscript>
Form code on form.py:
from wtforms import PasswordField, StringField, validators, widgets
from wtforms.form import Form
from wtfrecaptcha.fields import RecaptchaField
class ContactForm(Form):
"""Enables the user to provide feedback."""
first_name = StringField('First Name', [
validators.DataRequired()
])
last_name = StringField('Last Name', [
validators.DataRequired()
])
captcha = RecaptchaField('Captcha', [], public_key='6LeCJvUSAAAAAAvqwJEueVdV0wyNLPtX6KWSTdXp', private_key='6LeCJvUSAAAAADcUvYyLv8kt9ARiTAluDGqHBumY', secure=True)
Calling the form from within the HTML:
<form method="post">
{% for field in form %}
<div class="form-group{% if field.errors %} has-error has-feedback{% endif %}">
<div class="row">
<div class="col-xs-12 col-md-4">
{{ field.label(class="control-label") }}
</div>
<div class="col-xs-12 col-md-8">
{{ field(class="form-control") }}
</div>
</div>
{% if field.errors %}
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
{% endif %}
{% for error in field.errors %}
<p class="help-block text-danger">
<span class="glyphicon glyphicon-remove"></span>
{{ error }}
</p>
{% endfor %}
</div>
{% endfor %}
<br>
<button type="submit" class="btn btn-primary">{{ title }}</button>
</form>
Route call code:
#app.route('/contact', methods=['GET', 'POST'])
def contact():
"""Display the contact page."""
form = ContactForm(request.form, captcha={'ip_address': request.remote_addr})
if request.method == 'POST' and form.validate():
return "Thank you for contacting us."
return render_template(
...
)
The issue is that WTForms-RECAPTCH does not return a safe string, but instead returns a unicode string. The underlying issue needs to be fixed here (by returning an instance of wtforms.widgets.core.HTMLString or something else that provides an __html__ method).
To work around the problem for now you should simply mark the field as safe in your template:
<div class="col-xs-12 col-md-8">
{{ field(class="form-control") | safe }}
</div>
Or, alternately, only mark the re-captcha field as safe:
<div class="col-xs-12 col-md-8">
{% if field.short_name == "captcha" %}
{{ field(class="form-control") | safe }}
{% else %}
{{ field(class="form-control") }}
{% endif %}
</div>
There is a PR for this issue and this is fixed as of version 0.3.2