I have created a view which output a form containing:
class Person(colander.Schema):
name = colander.SchemaNode(colander.String())
age = colander.SchemaNode(colander.Integer(),
validator=colander.Range(0, 200))
class People(colander.SequenceSchema):
person = Person()
class Schema(colander.Schema):
people = People()
class SchemaSpace(colander.MappingSchema):
schema = Schema()
corners = colander.SchemaNode(colander.String())
The output is correct but when I click the button Add Person, nothing happen. The page blink and scrolls up and nothing, I fill anything. Do you know what is happening here? I am using multiples forms, is it coming from here?
My HTML is small and I am using jinja2:
{% extends "layout.jinja2" %}
{% block head %}
<script src="{{request.static_url('deform:static/scripts/jquery-2.0.3.min.js')}}"
type="text/javascript"></script>
<script src="{{request.static_url('deform:static/scripts/bootstrap.min.js')}}"
type="text/javascript"></script>
<script src="{{request.static_url('deform:static/scripts/jquery.form-3.09.js')}}"
type="text/javascript"></script>
<script src="{{request.static_url('deform:static/scripts/jquery-sortable.js')}}"
type="text/javascript"></script>
<script src="{{request.static_url('deform:static/scripts/jquery.maskedinput-1.3.1.min.js')}}"
type="text/javascript"></script>
{% endblock head %}
{% block content %}
<div class="row">
<div class="col-md-8">
<div class="content">
<h1>{{view.view_name}} - {{page_title}}</h1>
<p>Welcome</p>
{{form | safe}}
</div>
</div>
<div class="col-md-4">
<h2>Extra</h2>
<p>some text</p>
</div>
</div>
{% endblock content %}
From what I found from the doc, I added some scripts. But I had some issues so I manually entered them. Using:
<tal:block tal:repeat="reqt view.reqts['css']">
<link rel="stylesheet" type="text/css"
href="${request.static_url(reqt)}"/>
</tal:block>
Issue was:
<script type="text/javascript" src="{{request.static_url(reqt)}}"></script>
File "/Users/roy/Applications/miniconda3/envs/WebAppBatman/lib/python3.6/site-packages/pyramid/url.py", line 644, in static_url
if not os.path.isabs(path):
File "/Users/roy/Applications/miniconda3/envs/WebAppBatman/lib/python3.6/posixpath.py", line 64, in isabs
s = os.fspath(s)
TypeError: expected str, bytes or os.PathLike object, not Undefined
To be complete, here is the view:
#view_config(renderer='templates/settings.jinja2')
def settings(self):
html = []
if 'submit' in self.request.POST:
posted_formid = self.request.POST['__formid__']
for (formid, form) in forms.items():
if formid == posted_formid:
try:
controls = self.request.POST.items()
form['captured'] = form['form'].validate(controls)
html.append(form['form'].render(form['captured']))
except deform.ValidationFailure as e:
# the submitted values could not be validated
html.append(e.render())
else:
if form['captured'] is not None:
html.append(form['form'].render(form['captured']))
else:
html.append(form['form'].render())
else:
for _, form in forms.items():
html.append(form['form'].render())
reqts = forms['form1']['form'].get_widget_resources()
html = ''.join(html)
# values passed to template for rendering
return {'form': html, 'page_title': 'Settings', 'reqts': reqts}
I got it working! It was due to the scripts as I suspected.
Here is a working syntax using jinja2:
{% for reqt in reqts['js'] %}
<script src="{{request.static_url(reqt)}}"
type="text/javascript"></script>
{% endfor %}
I was not able to make it work using tap:repeat.
Related
I'm using a database to retrieve project numbers and put them in a search for a user in a form. I am using an api (ajax google api) for autocompletion on the search.
When putting it as autocomplete in search field it contains brackets and a comma.
I need it just to be like:
24403
24429
not like:
(24403,)
(24429,)
I am unsure how to do this. My current code is:
app.py
class Element(db.Model):
__tablename__ = 'elements'
ProjectNumber = db.Column(db.Integer, primary_key=True)
#app.route("/", methods=["POST", "GET"])
def basicTemplate():
project_number = Element.query.with_entities(Element.ProjectNumber).distinct()
if request.method == "GET":
return render_template('search.html', navigation=project_number)
if __name__ == '__main__':
app.run()
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static\style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/ui-lightness/jquery-ui.css" rel="stylesheet" type="text/css" />
{% block head %}
<title>{% block title %}{% endblock %}- base</title>
{% endblock %}
</head>
<body>
{% block body %}
{% block project_number %} {% endblock %}
{% endblock %}
</body>
</html>
search.html
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% block project_number %}
<label for="project_code">Project Number</label><input type="text" id="project_code" name="project_code">
<input type="submit">
<script>
$( function() {
var project = [
{% for test in navigation %}
"{{test}}",
{% endfor %}
];
$( "#project_code" ).autocomplete({
source: project
});
} );
</script>
{% endblock %}
The command with_entities always returns a list of tuples.
You can combine multiple jinja filters to get a list of strings that can be passed directly to javascript.
First you extract the first element of all tuples and convert them into strings. You convert the received generator into a list and output it in a javascript-compatible manner.
$(function() {
const projects = {{ navigation | map('first') | map('string') | list | tojson }};
$('#project_code').autocomplete({
source: projects
});
});
Of course you can also perform the extraction and conversion to the string in the endpoint.
Depending on how many projects are stored in your database, I recommend getting the data via ajax.
$(function() {
$('#project_code').autocomplete({
source: '/search',
});
});
#app.route('/search')
def search():
term = request.args.get('term', '')
projects = Element.query.filter(Element.ProjectNumber.ilike(f'%{term}%')).all()
return jsonify([str(p.ProjectNumber) for p in projects])
I am using Django version 3.0 to create a sign up application for various departments at my school. I have connected the form to a model and the model is stored in a postgressql database. After I start the server using python manage.py runserver and I complete the form and click save, the form refreshes and I get the OK HTTP Code 200 from the server accessed through the terminal, but when I query the postgressql database using pg Admin interface the data has not been stored. Can anyone see where I am going wrong? This process worked before, I'm not sure if the data is just being stored in another table. Please help out if you can.
This is my base.html file:
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>Signup Prototype</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link href='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="{% static 'js/jquery.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
<script src="{% static 'js/bootstrap.js' %}"></script>
<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/redmond/jquery-ui.css" rel="Stylesheet" />
<script language="javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<script type="text/javascript">
$(function(){
$("#id_date").datepicker();
});
</script>
{{form.media}}
</head>
<body>
<header class="page-header">
<div class="container">
<a href="{% url 'Engineering' %}" class="top-menu">
</a>
<h1>Signup </h1>
</div>
</header>
<main class="content container">
<div class="row">
<div class="col">
{% block content %}
{% endblock %}
</div>
</div>
</main>
</body>
</html>
This is my engineering.html file that displays the form
<html>
{% extends 'base.html' %}
{% load static %}
{% block content %}
<h2>Engineering</h2>
<form method="POST" class="engineering-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock %}
<html>
This is my .views file:
from django.shortcuts import render
from .forms import Engineering
def engineering(request):
form = Engineering()
return render(request, 'my_app/engineering.html', {'form': form})
This is my form
class Engineering(forms.ModelForm):
name = forms.CharField(label="Name")
etoken_user = forms.BooleanField(required = False, label="Etoken Use")
mfa_use = forms.BooleanField(required = False, label="MFA Use")
usage_type = forms.CharField(label="Usage Type")
email = forms.EmailField(label="Email")
user_id = forms.CharField(label="USERid")
date = forms.DateTimeField(label="Date") # date just time stamp the date they are using
class Meta: #tells django which model should be used to create the form
model = Engineering
fields = ('name','etoken_user', 'mfa_use','usage_type','email','user_id','date')
widgets = {
'datetime':DateTimeWidget(attrs={'id':'UTC' },usel10n=True, bootstrap_version=4)
}
this is the model
class Engineering(models.Model):
user_name = models.CharField(max_length = 100)
etoken_use = models.BooleanField()
mfa_use = models.BooleanField()
usage_type = models.CharField(max_length = 100)
date_recorded = models.DateTimeField(auto_now_add = True)
email = models.EmailField(max_length = 150)
user_id = models.CharField(max_length = 20)
As the earlier answer noted, you are not doing anything with the data posted from the forms in the view.
from django.shortcuts import render
from .forms import Engineering
def engineering(request):
form = Engineering()
if request.method == 'POST':
form = Engineering(request.POST)
if form.is_valid():
form.save()
# probably a redirect over here.
return render(request, 'my_app/engineering.html', {'form': form})
yes, because your view does not do anything with the data on POST.
See https://docs.djangoproject.com/en/3.0/topics/forms/#the-view
I am using Django 3.0 and python 3.8.2 to develop an ads website. To add a post, I used Django formtools wizard. It worked and everything goes nicely. I could save the multiform data. However, I could not retrieve the files from the FileSystemStorage so I can save them. Hence, any help to achieve this or suggestion is much appreciated. I want to retrieve uploaded files, save them to the data base and then delete them from the wizard (from the FileSystemStorage). Note: there is no error and everything is working except that the uploaded files are not saved to the data base even though they are available in the FileSystemStorage. Thus, I want to retrieve them to be able to save them to the data base.
Here is the view class:
TEMPLATES = {"CommonForm": "towns/salehslist/ads_main_form.html",
"JobForm": "towns/salehslist/forms/jobPostForm.html",
}
FORMS = [
("CommonForm", CommonForm),
("JobForm", JobForm, JobImagesForm),
]
class PostWizard(SessionWizardView):
# The form wizard itself; will not be called directly by urls.py,
# but rather wrapped in a function that provide the condition_dictionary
_condition_dict = { # a dictionary with key=step, value=callable function that return True to show step and False to not
"CommonForm": True, # callable function that says to always show this step
"JobForm": select_second_step, # conditional callable for verifying whether to show step two
}
file_storage = FileSystemStorage(
location=os.path.join(settings.MEDIA_ROOT, "photos")
)
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
def done(self, form_list, form_dict, **kwargs):
# form_data = [form.cleaned_data for form in form_list]
# print(form_data)
data = {k: v for form in form_list for k, v in form.cleaned_data.items()}
data["posted_by"] = self.request.user
instance = Job.objects.create(**data)
print("YOU ARE HERE")
print(self.request.FILES.getlist("files"))
for file in self.request.FILES.getlist("files"):
print(file)
img_instance = JobImages.objects.create(job=instance, images=file)
img_instance.save()
return HttpResponse("<h1>Post Page </h1>")
Here is the url:
url(r'^post/$', PostWizard.as_view(FORMS, condition_dict = PostWizard._condition_dict)),
Here is the html template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% load static %}
{% load crispy_forms_tags %}
{% load i18n %}
<script type="text/javascript" src="{% static 'towns/assets/fontawesome-free-5-12-0-we/js/all.js' %}">
</script>
<link rel="stylesheet" type="text/css" href="{% static 'towns/assets/bootstrap-4.4.1/dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'towns/assets/fontawesome-free-5-12-0-we/scc/fontawesome.min.css' %}">
<!-- file uploader font -->
<link type="text/css" rel="stylesheet" media="all" href="{% static 'towns/assets/fileuploader-2.2/dist/font/font-fileuploader.css' %}" >
<link rel="stylesheet" type="text/css" href="{% static 'towns/style/forms/jobPostForm.css' %}">
</head>
<body>
<div class="container">
<div class="row h-100">
<div class="col-lg-6 my-auto">
<div class="breadcrumb">
<div class="ads-form-title">
Job Post
</div>
</div>
<form class="" action="" method="POST" enctype="multipart/form-data" novalidate id="jobPost">
{% csrf_token %}
{{ wizard.management_form }}
{{ wizard.form.media }}
<hr>
<div class="form-group">
<div>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form|crispy }}
{% endfor %}
{% else %}
{{ wizard.form|crispy }}
{% endif %}
</div>
</div>
<hr>
<!-- upload images -->
<!-- file input -->
<input type="file" name="files" class="files">
<center>
<button type="submit" class="btn btn-primary" style="position:relative; width: 33%; height: 100%;"> Submit </button>
</center>
</form>
</div>
</div>
</div>
<script type="text/javascript" src=" {% static 'towns/assets/jquery-3.5.0.min.js' %}">
</script>
<script type="text/javascript" src=" {% static 'towns/assets/bootstrap-4.4.1/dist/js/bootstrap.min.js' %}">
</script>
<script type="text/javascript" src="{% static 'towns/assets/fileuploader-2.2/dist/jquery.fileuploader.min.js' %}" >
</script>
</body>
</html>
When user hit submit button of the form wizard, def post() method is called. def post() will
validate the form and
save data and files into session.
then if the current page is the last page, it will
render_done, which is def done()
The reason why your request.files is empty is because, the current request does not have files or data associated with it. All your data and files are saved to the session when you hit the submit buttons which are preceding the done() method.
Since I do not know how your form is structured, I am not sure how to definetely solve your problem. But something like below should do:
# iterate over all forms in the form_list
for form in form_list:
# check if current form has files
if bool(self.get_form_step_files(form)):
# if yes, do something
uploadedfiles = form.files
print(uploadedfiles)
for key, value in uploadedfiles.items():
jobimage = JobImage(job=?, image=value)
jobimage.save()
Update
wihtout your model, form structure, and template, it is difficult to come out with complete solution. I am posting a minimum working example.
1. in models.py
class MyPost(models.Model):
field1 = models.CharField(max_length=50)
field2 = models.CharField(max_length=50)
class Photo(models.Model):
mypost = models.ForeignKey(MyPost, on_delete=models.CASCADE)
photo = models.FileField(blank=True, null=True)
2. In forms, you will not include photoform, because you are trying to uplaod more than one images.
from .models import MyPost, Image
from django import forms
class step_first_form(forms.ModelForm):
class Meta:
model = MyPost
fields = ['field1']
class step_second_form(forms.ModelForm):
class Meta:
model = MyPost
fields = ['field2']
in template, you can keep your first template same as whatever you have. For the second one, say, you will have MyPost's field2 and 2 image inputs, you will change it to:
<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{wizard.form.field2}}
<input type="file" name ="imagefile1" >
<input type="file" name ="imagefile2" >
{% endif %}
</table>
.......
.....
.....
</form>
make sure you include enctype="multipart/form-data" otherwise your files will not be uploaded.
make sure you have different names for filefield otherwise only one
will be saved to your model.
4. in views.py
def done(self, form_list, form_dict, **kwargs):
data = [form.cleaned_data for form in form_list]
# you can print out and inspect this data, and you will know
# the below code.
# you will need to modify data[0]['field1'] etc ...
print(data)
mypost = MyPost()
mypost.field1 = data[0]['field1']
mypost.field2=data[1]['field2']
mypost.save()
print('mypost')
print(mypost)
# the below part is for saving image files to model
for form in form_list:
# check which form has files
if bool(self.get_form_step_files(form)):
uploadedfiles= form.files
print(form.files)
for key, value in uploadedfiles.items():
photo = Photo(mypost=mypost,photo=value)
photo.save()
else:
print('not bool')
return render ##### whatever template you want to render
I've been making the blog with python,flask,sqlalchemy,html.
And now I can display the articles in the page.
But I'm only able to display it in 1 row like below one with the codes below.By the way,somehow I can't use css file.
*article1
*article2
*article3
*article4
And the thing which I want to do is like below one.
*article1 *article3
*article2 *article4
{% extends "copy.html" %}
{% block body %}
{%for article in articles%}
<li>{{article.title}}
Details
</li>
{%else%}
None articles
{%endfor%}
{%endblock%}
How do I implement it?.
take a look at my posts here posts about flask and to the structure of my app in flask on pil.glitch.me or flask site if you want to get an idea...
You should create two columns in the html file and in the ptyhon file you should separate the odd from the even posts in different lists.
P.S.: I do not know if you want to put the odd posts in a column and the even in the other or you want to put first half on the left column and the other half on the other. In the second case you just want to do two lists with post1 = posts[:int(len(posts)/2)] and then post2 = posts[len(post1):].
#app.route("/")
def home():
posts = [
{"title" : "post1.",},
{"title" : "post2.",},
{"title" : "post3.",},
{"title" : "post4.",},]
post1 = [x for x in posts if x % 2 == 0]
post2 = [x for x in posts if x % 2 != 0]
return render_template("info.html", post1 = post1, post2=post2)
and then send them to the html file with something like:
{% extends 'template.html' %}
{% block page %}
<div class="container">
{% for post in posts %} <!-- iterate all posts keys/values -->
<div class="row">
<div class="col-md-6"> <h3>{{ post1.title }}</h3> </div>
<div class="col-md-6"> <h3>{{ post2.title}}</h3> </div>
</div>
{% endfor %}
</div>
{% endblock %}
To use bootstrap copy this code in the template:
<link href="https://fonts.googleapis.com/css?family=Literata&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
I am working on a django website which includes a form for contact information and I am currently using bootstrap to make it "look pretty". I want to use bootstrapvalidator http://bootstrapvalidator.com/ to make the form easy to use for my users. I have heavily researched using django and bootstrapvalidator together and have found several different plugins or other ways to validate information entered into a form but they only give errors after the form is submitted, and what I want is live validation that shows the user appropriate messages as they type.
My biggest problem has been figuring out how/where to call the Javascript. I think the correct way to do this is by using a widget in the form, but nothing I have tried has done the job. Currently my page is displaying "emailval(parent_or_guardian_email)" where the email field should be.
Would anyone be able to tell me what I'm doing wrong or how to get my desired result? This is my first time using django or python at all.
relevant parts of my models.py
from django.db import models as db_models
from django.db import models
from django.contrib.auth.models import User
from django import forms
from django.contrib.admin import widgets
from django.forms import extras
import datetime
from django.core.validators import *
from django.forms import ModelForm
from django.contrib import admin
import logging
class EmailWidget(forms.TextInput):
def render(self, name, value, attrs=None):
out = super(EmailWidget,self).render(name, value, attrs=attrs)
return out + '<script type="text/javascript">emailval(parent_or_guardian_email) </script>'
class Media:
js = ('../validator.js')
class PersonForm(forms.Form):
ready_to_play = forms.BooleanField(initial = True )
first_name = forms.CharField(max_length=35)
last_name = forms.CharField(max_length=35)
phone_number = forms.CharField(widget =forms.TextInput(attrs={'type':'text', 'class':'form-control bfh-phone','data-format':"+1 (ddd) ddd-dddd",}), required = False)
grade = forms.IntegerField(initial = 99, required = False)
age = forms.IntegerField(initial = 99, required = False)
gender = forms.ChoiceField(choices=GENDERS, required = False)
sport = forms.ChoiceField(choices=SPORTS, required = False)
#fields for parent_or_guardian and physician not autofilled
parent_or_guardian = forms.CharField(max_length=35, required = False)
parent_or_guardian_phone_number = forms.CharField(widget =forms.TextInput(attrs={'type':'text', 'class':'form-control bfh-phone','data-format':"+1 (ddd) ddd-dddd",}), required = False)
parent_or_guardian_email = forms.EmailField(widget =EmailWidget(),help_text = "Changing this field will create a new user for this email address, if you wish to change this user's contact information"
+" please ask them to do so on their page or contact a site admin ")
physician = forms.CharField(max_length=35, required = False)
physician_phone_number = forms.CharField(widget =forms.TextInput(attrs={'type':'text', 'class':'form-control bfh-phone','data-format':"+1 (ddd) ddd-dddd",}), required = False)
#Pphone = copy.deepcopy(physician.phone)
#Pphone =str(physician_phone)
#physician_phone = re.sub('.','-',str(Pphone))
physician_email = forms.EmailField(max_length=75, required = False)
in my base.html I have the appropriate file imports
<link href ="../../../../static/spotlight/assets/css/bootstrap-responsive.css" rel="stylesheet">
<link href ="../../../../static/spotlight/assets/css/bootstrapValidator.min.css" rel="stylesheet">
<script src="../../../../../static/spotlight/assets/js/jquery-1.11.1.min.js"></script>
<script src="../../../../static/spotlight/assets/js/bootstrap-tab.js"></script>
<script src="../../../../static/spotlight/assets/js/bootstrap.js"></script>
<script src="../../../../static/spotlight/assets/js/bootstrap.min.js"></script>
<script src="../../../../static/spotlight/assets/js/bootstrap-formhelpers.min.js"></script>
<script type="text/javascript" src="../../../../static/spotlight/assets/js/bootstrapValidator.min.js"></script>
the html file for the page with the form
{% extends "spotlight/base.html" %}
{% block content %}
<h3>Update {{ athlete }}</h3>
<br>
<form class="form-horizonal" role="form" action="{% url 'spotlight:athleteedit' athlete.id %}" method="post" id="PersonForm">
{% for field in form %}
<div class="form-group"><p>
{{ field.label_tag }} {{ field }}
{% for error in field.errors %}
<font color="Red">{{ error }}</font>
{% endfor %}
</p></div>
{% endfor %}
{% csrf_token %}
<input class="btn btn-default" type="submit" value="Submit" />
</form>
{% endblock content %}
validators.js
$(document).ready(function emailval() {
$('#PersonForm').bootstrapValidator({
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
parent_or_guardian_email: {
validators: {
emailAddress: {
message: 'The value is not a valid email address'
excluded: [':disabled'],
}
}
}
}
});
});
Ok, I figured it out, it was really quite simple. I included this javascript as the last thing before the closing html tag in my base.html file:
<body>
<script type="text/javascript">
$(document).ready(function() {
$('#PersonForm').bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
parent_or_guardian_email: {
validators: {
notEmpty: {
message: 'The email address is required and can\'t be empty'
},
emailAddress: {
message: 'The input is not a valid email address'
}
}
},
}
});
});
</script>
</body>
above which (in base.html) I made sure to include the correct files (order does matter)
<link href ="../../../../static/spotlight/assets/css/bootstrap-responsive.css" rel="stylesheet">
<link href ="../../../../static/spotlight/assets/css/bootstrap.css" rel="stylesheet">
<link href ="../../../../static/spotlight/assets/css/bootstrapValidator.min.css" rel="stylesheet">
and made my html for the page containing the form look like this
{% extends "spotlight/base.html" %}
{% block content %}
<h3> Add Athlete</h3>
<br>
<form class="form-horizonal" role="form" action="{% url 'spotlight:addstu' person_id team_id %}" method="post" >
{% for field in form %}
<div class="fieldWrapper"><p>
{% if field.label = "Parent or guardian email" %}
<div class="col-lg-5" id="PersonForm">
{{ field.label_tag }} {{ field }}
</div>
{% else %}
{{ field.label_tag }} {{ field }}
{% for error in field.errors %}
<font color="Red">{{ error }}</font>
{% endfor %}
{% endif %}
</p></div>
{% endfor %}
{% csrf_token %}
<input class="btn btn-default" type="submit" value="add athlete" />
</form>
{% endblock content %}
and I didn't need to create a widget outside the form, just include it like this
parent_or_guardian_email = forms.EmailField(widget =forms.TextInput(attrs={'type':'text', 'class':'form-control','name':"parent_or_guardian_email",'class':"col-lg-5",}),help_text = "Changing this field will create a new user for this email address, if you wish to change this user's contact information"
+" please ask them to do so on their page or contact a site admin ",max_length=75)
for some reason the feedbackIcons aren't showing, but the validation messages are displaying as the user fills in the field, which is what I really needed. Hope someone else finds this so they don't have to bag their head for as long as I did.