CSS for Flask wtforms - python

I have a the following code for a Form that I have in my Flask application using Wtforms. I use FieldList to use two fields for one part.
class A(Form)
additional = FieldList(FormField(Additional), 'Additional', min_entries=1)
submit = SubmitField('Submit')
class Additional(Form):
choices = [('Funding Mechanism', 'Funding Mechanism'), ('Study Section Name', 'Study Section Name')]
critera = SelectField('Additional Criteria', choices=choices)
input = StringField()
The template uses wtf.quick_form:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Grants - Find Grant{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Specify</h1>
</div>
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
Currently the forms render in a squished and overlapping way like so:
How can I change the code so that it is formated in one line like below? It is a screenshot of #Niklas in Stockholm 's form from his question.
Thank you!

Since your form class A is calling class Additional as a FormField and only adding submit to the field, i added the submit button the Additional form itself and then called it in the view.
In the template, use
{{ wtf.quick_form(form, form_type="inline") }}
It outputs the page like this:
The form_type argument adds the .form-inline to the class attribute.
This is just a hack, surely your form will have more inputs than this, for that, you'll be writing the whole form template yourself.

The issue is that {{ wtf.quick_form(form) }} is calling wtf.form_field() on your FieldList additional in A instead of calling it on additional's subfields. Because of this, I don't think you will be able to use wtf.quick_form() on your particular form.
Instead, try templating your form like this:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Grants - Find Grant{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Specify</h1>
</div>
<div class="col-md-4">
<form class="form form-horizontal" method="post" role="form">
{{ form.hidden_tag() }}
{{ wtf.form_errors(form, hiddens="only") }}
{% for subfield in form.additional %}
{{ wtf.form_field(subfield) }}
{% endfor %}
{{ wtf.form_field(form.submit) }}
</form>
</div>
{% endblock %}
You can read more about wtf.form_field() on the Flask-Bootstrap documentation site.

Related

Using Flask_wtf inside angularJS ng-app

I have a form created with Flask_wtf. Now I trying to add in angularJS to do the username/password min-length validation etc on the form.
I tried:
Flask-WTF to create the form and handle submit button press
_form = LoginForm() # Flask-WTF: Construct a LoginForm
if _form.validate_on_submit(): # POST request with valid data?
# Retrieve POST parameters
_username = _form.username.data
_passwd = _form.passwd.data
I tried:
Form.html
{% import 'macros.html' as macros %}
{% extends "base.html" %}{# in app_main's templates folder #}
{% block title %}Login{% endblock %}
{% block content %}
{{ super() }}{# Render the contents of the parent block #}
<h1>Login</h1>
<!-- loginpage -->
<form method="POST">
{{ form.hidden_tag() }}{# Render any hidden fields, including the CSRF #}
<div class="field">{{ form.username.label }} {{ form.username }}</div>
{{ macros.show_field_errors(form.username.errors) }}
<div class="field">{{ form.passwd.label }} {{ form.passwd }}</div>
{{ macros.show_field_errors(form.passwd.errors) }}
<div class="field">{{ form.submit }}</div>
</form>
<div ng-app="mainApp" ng-controller="loginController">
........
</div><!--end of ng-app-->
{% endblock %}
Issue:
Putting my loginpage outside the ng-app < div > and submit button works well. But when I put it inside ng-app < div > the submit button will no longer work. Am I missing something?
I already changed Angular $interpolateProvider
var app = angular.module('mainApp', []).config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
I already checked other questions ,it does not resolve my issue by changing interpolate.
Thanks for your time!

Template not rendering properly with if user.is_authenticated for Django

I'm trying to incorporate an template tag/inclusion tag into my sidebar for the site. The main section of the page updates properly when I put:
{% if user.is_authenticated %}
<h1> Hello {{ user.username }}
{% else %}
<h1> Hello </h1>
{% endif %}
When I try to use the same principle in my template tag/sidebar, it seems to ignore user.is_authenticated and will always show 'login' and 'register', when it should be just showing 'logout'.
The body of the html (main index page):
{% load Kappa_extras %}
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-2" id="side_section">
{% block sidebar %}
{% get_game_list %}
{% endblock %}
</div>
<!--Main section-->
<div class="col-sm-10" id="main_section">
{% block body %}
{% endblock %}
</div>
</div>
</div>
The get_game_list function from 'Kappa_extras':
from django import template
from Kappa.models import Game, Game_Page
from django.contrib.auth.models import User
register = template.Library()
#register.inclusion_tag('Kappa/sidebar.html')
def get_game_list():
return {'game_list': Game.objects.all()}
and the 'Kappa/sidebar.html':
<div id="side_default_list">
<ul class="nav">
<li>Kappa</li>
{% if user.is_authenticated %}
<li>Log Out</li>
{% else %}
<li>Log In</li>
<li>Register</li>
{% endif %}
</div>
I checked a few older inquires though none of them are working properly. I tried putting request into def get_game_list(request): but it just said did not receive value for the argument. How do I get the sidebar to update properly when user.is_authenticated?
You need to pass the user to your inclusion tag.
#register.inclusion_tag('Kappa/sidebar.html')
def get_game_list(user):
return {'game_list': Game.objects.all(), 'user': user}
Then in your template, call the tag with
{% get_game_list user %}
Alternatively, you can set takes_context=True in your inclusion tag, so that you can access the user from the template context.
#register.inclusion_tag('Kappa/sidebar.html', takes_context=True)
def get_game_list(context):
return {'game_list': Game.objects.all(), 'user': context['user']}
In this case, you don't need to pass the user to the template tag any more.
{% get_game_list %}
See the docs for more information and other examples.

Django forms adding <div> after form field

Below is my form code :
class FMessage(forms.Form):
From = forms.CharField()
To = forms.CharField()
Subject = forms.CharField()
Message = forms.CharField()
and this is my html code:
<form method='POST' action='.'>
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='submit'>
</form>
The code works fine by displaying forms and has not any issue in functionality, but now I need to wrap my form fields in html by a div like this:
<div id='mydiv'>
<input ... />
<div>
How can I fix it?
Seems like you do not really want to use the inbuilt <p> or <table> wrapped forms and rather want to display the fields wrapped within a <div>'s. You can simply iterate over fields in the form as follows.
{% if form %}
<!-- Form Errors -->
{% if form.errors %}
<ul class="errors">
{% for error in form.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<!-- Display Form -->
<form>
{% csrf_token %}
{% for field in form %}
<div class="mydiv">
<label class="mylabel">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
</form>
{% endif %}
Dont render the form by using form.as_p. You need to show each field of the form, for example, by using form.to. By using this way, you can wrap the field 'to' into a div
<div>{{ form.To}} </div>
For more detail, view this link

Django doesn't seem to detect my login.html, block problem?

I'm creating a web app with django 1.2.4.
I am using contrib.auth.views.login, I have followed every step but it seems I have forgotten something cause I don't see the login form. Here is my folder structure:
/templates/
base.html
/myapp/
object_list.html
...
/registration/
login.html
...and here is my login.html:
{% extends "base.html" %}
{% block mylogin %}
<div class="horizontal">
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form action="{% url django.contrib.auth.views.login %}" method="post">
{% csrf_token %}
<div class="login_box">
<div class="login_text">{{ form.username.label_tag }}</div><div class="login_input">{{ form.username }}</div>
<div class="password_text">{{ form.password.label_tag }}</div><div class="password_input">{{ form.password }}</div>
<input id="button_login" type="submit" value="" />
</div>
</form>
</div>
{% endblock %}
...and in my base.html I have:
<div id="some_div">
{% block mylogin %} {% endblock %}
</div>
I have a basestyle.css included in base.html and the other templates inherit correctly too... it seems to be a block problem...
Any solution??
Thnak you
Instead of inserting of a block I used the include tag in base.html, just like this:
{% include "registration/login.html" %}
If you’d prefer not to call default (django provided) template registration/login.html, you can pass the template_name parameter via the extra arguments to the view in your URLconf.
For example, this URLconf line would use myapp/login.html instead:
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
Reference : Django official documentation
It solves my problem. Hope this works for others.

How to extend the comments framework (django) by removing unnecessary fields?

I've been reading on the django docs about the comments framework and how to customize it (http://docs.djangoproject.com/en/1.1/ref/contrib/comments/custom/)
In that page, it shows how to add new fields to a form. But what I want to do is to remove unnecesary fields, like URL, email (amongst other minor mods.)
On that same doc page it says the way to go is to extend my custom comments class from BaseCommentAbstractModel, but that's pretty much it, I've come so far and now I'm at a loss. I couldn't find anything on this specific aspect.
I recently implemented the solution that Ofri mentioned, since I only wanted to accept a solitary "comment" field for a comment (like SO does, no "name", no "email" and no "url").
To customize the default comment form and list display, I created a "comments" directory in my root "templates" directory and overrode the two default comment templates.
My "/templates/comments/form.html" is:
{% load comments i18n %}
{% if user.is_authenticated %}
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.name != "name" and field.name != "email" and field.name != "url" %}
{% if field.errors %}{{ field.errors }}{% endif %}
<p {% if field.errors %} class="error"{% endif %} {% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
{{ field }}
</p>
{% endif %}
{% endif %}
{% endfor %}
<input type="submit" name="post" class="submit-post" value="{% trans "Add Comment" %}" />
</form>
{% else %}
I'm sorry, but you must be logged in to submit comments.
{% endif %}
Which is only slightly different from the default comments form, primarily suppressing the display of the not-required "name", "email" and "url" inputs.
My "/templates/comments/list.html" is:
<div class="comment_start"></div>
{% for comment in comment_list %}
<div class="comment">
{{ comment.comment }}
(from {{ comment.user }} - {{ comment.submit_date|timesince }} ago)
</div>
{% endfor %}
On the page I want the form, I first call {% load comments %} and then {% render_comment_form for [object] %} to show the form, or {% render_comment_list for [object] %} to generate a list of the comments on the object (replace [object] with your appropriate object name).
This is working great for me, and still giving me all the other "free" stuff that comes with django comments (moderation, flagging, feeds, polymorphic associations, etc...)
A tidy summary of how to do this elegantly, through the actual comments framework subclassing approach, rather than hiding elements in a form/other untidy hacks, can be found Django Comments: Want to remove user URL, not expand the model. How to?
Essentially, you subclass the CommentForm, and change its get_comment_create_data(self) method, and then pop out the attributes you don't want (e.g. email, url, etc.)
J
You can try overriding the comment form with a custom template that only shows the fields you want.

Categories