I currently have a login.html, which has inside it a form for login. All my forms need to look similar, however will have different content. At the moment my code for it looks like this:
<form enctype="multipart/form-data" method="POST" action="">
<fieldset>
<legend>{{ legend }}</legend>
<div style="line-height:18px">{% block top %}{% endblock %}<br></div>
<table class="form">
{% for text,name,inputtype in formcontent %}
<tr>
<td class="right">
<label>{{ text }}:</label><br/>
</td><td style="float:left">
<input name="{{ name }}" type="{{inputtype}}">
</td>
</tr>
{% endfor %}
</table>
<input value="{{ button }}" type="submit">
<div style="line-height:18px">
<div class="err">
{{ err }}
</div>
{{ bottom }}
</div>
</fieldset></form>
I was wondering if there was a better way to do it than to put variables into my urls.py (given that there may be multiple forms on hte page, I don't believe that this would work under all circumstances). A nice solution would be to create a class, but I don't know how to call this class from a page. I know it would involve making a tag, but I don't see how you can provide a 2d array as an argument from a template.
Django Crispy Forms were made for this exact reason. I think they are exactly what you need.
Related
I want to add a custom form to a django admin-site change list view. As soon as I add a submit button it asking to select the custom action from the drop-down list. I created a separate form with a unique id. Still it look for a action be select. How can I overcome this?
Here is my template code.
{% extends "admin/change_list.html" %}
{% load staticfiles %}
{% block content %}
<div align="right">
<form id="generate-form" method="POST">
{% csrf_token %}
<select>
<option value="">-- section name --</option>
{% for section in sections %}
<option value="{{ section.short_name }}">{{ section.name }}</option>
{% endfor %}
</select>
<input type="text" name="from_date" class="vTextField" placeholder="from">
<input type="text" name="to_date" class="vTextField" placeholder="to">
<input type="submit" value="Generate" class="default" id="gen-schedules"
style="margin:0; height: 30px; padding-top: 5px;">
<form>
</div>
{{ block.super }}
{% endblock %}
Assuming you copy/pasted without changing it, you have this because the form tag isn't properly closed: <form> should be replaced by </form>:
...
</form>
</div>
{{ block.super }}
{% endblock %}
Because it's not closed, the browser thinks it's the same form as the the next form, the actions one.
To avoid this kind of problems, I'd recommend relying on Django's forms to generate the right HTML for you, when possible. To help with complex layouts, django-crispy-forms is a great library that is very helpful.
I'm working with Django and I'm trying to line up a Bootstrap button with a select field. I've got the form inline where I'd like it to be, but I can't seem to make the button smaller to make it align properly. I'm sure there is a simple solution but I've been struggling with this for hours and can't seem to find anything that works for me. Here is a picture as it is currently to give you a better idea of the problem: button not aligned
And here is my current code in my template:
<form class="form-inline" action="{% url 'displayStats:proindvleaders'%}" method="post">
{% csrf_token %}
<div class="row">
{{ form.as_p }}
<button id="submit" type="submit" class="btn btn-primary btn-sm">Submit</button>
</div>
I've tried just setting height on the button ID with css but it doesn't seem to be working for me. Any ideas?
By default bootstrap btn class has padding. Inspect the code in a browser and remove that padding, either by adding a new padding class, or use custom styling class and remove btn, btn-primary etc, but all the same, its better to edit the form, rather than button. Bootstrap default buttons are perfect for most scenario, and most probably you need form styling. I suggest form styling. Below is an example from code.
Ps: i'm replying from phone, code may not be formatted
{% for field in form %}
<div class="fieldWrapper">{{ field.errors }}
<input type="{{ field.field.widget.input_type }}" name="{{ field.html_name }}" id="{{field.id_for_label}}" class="col-12 input-login" placeholder="{{field.label}}" >
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
I have a template as below (the second column of the table is wrong, which is my question):
{% for thing in things %}
<tr><td>See the lovely {{ thing.name }}!</td>
<td><form method="POST" action="">
{% csrf %}
<input type="hidden" name="id" value="{{ thing.id }}">
<input type="submit" name="submit" value="Kill me!">
</form></td>
</tr>
{% endfor %}
And I'm a bit stumped how to make an array of forms like this. Of course, the above form works great modulo the csrf, so maybe all I need to do is figure out how to make the csrf work in that context and then I think I can just look at request.POST.get('id') (I think...).
Many thanks for any pointers.
I think the error is csrf. Use
{% csrf_token %}
Just started to fuse JQuery UI with my app. Apparently the slider only works on div elements. I have a form based on a model(ModelForm). One of the fields is a Decimal Field like so:
class mymodel(models.Model):
rating = models.DecimalField(max_digits = 5, decimal_places = 2)
...
being created like so:
class modelCreate(generic.CreateView):
template_name = 'form.html'
model = mymodel
form.html:
{% extends "base.html" %}
{% block content %}
{% load staticfiles %}
<!--<script src='http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js'></script>-->
<link rel="stylesheet" href="{% static 'Content/css/startTheme/jquery-ui-1.10.4.custom.css' %}" />
<script src={% static 'Scripts/js/jquery-1.10.2.js' %} ></script>
<script src={% static 'Scripts/js/jquery-ui-1.10.4.custom.js' %} ></script>
<div class="form_container">
<form action="" id="myform" method="post">{% csrf_token %}
{{ form.non_field_errors }}
<table>
<tr class="fieldWrapper">
<td class="label">
<label for="id_rating">Your number:</label>
</td>
<td class="field">
{{ form.rating }}
<div class="error">
{{ form.rating.errors }}
</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="btnContainer">
<input type="submit" class='btn' value="Create" />
</div>
</td>
</tr>
</table>
</form>
</div>
{% endblock %}
Using the slider on a normal div that I created works correctly.
But in the form if used on an input element it just changes the color of the border of the input box. It becomes a glorified input box.
Another approach I've thought of is to remove the decimal field on the page, replace with a div, and save that value to the model before commit (throught Form_valid()).
But I'm keeping that solution as a last resort.
A customizable slider is very important for this app. Any help would be appreciated.
The easiest way would be to hide the rating input field and add a <div> for the slider that updates the rating value. I've created a simple demo (below) to demonstrate this idea.
Note: The demo has a max value of 5. However, declaring your field, DecimalField(max_digits=5, decimal_places=2) allows you to store numbers up to 999. This would obviously make it difficult to get the exact number you wanted using a slider.
DEMO
More specifically for your form.html:
...
<td class="field">
{{ form.rating.as_hidden }}
<div id="rating_slide"></div>
<div class="error">
{{ form.rating.errors }}
</div>
</td>
...
If you want a more integrated method you could create a mixin class for your view or inclusion-tag for your template.
I am using the FOSUserBundle in my Symfony application which is really great. They have the login and register forms in a separate template. I want both in one template to display them next to each other.
Therefore I created app/Resources/FOSUserBundle/Security/login.html.twig and app/Resources/FOSUserBundle/Registration/register.html.twig to override both templates. In login.html.twig I call the register controller to render its template.
app/Resources/FOSUserBundle/Security/login.html.twig:
{% extends "FOSUserBundle::layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %}
{% if error %}
<div>{{ error|trans }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<input type="text" id="username" name="_username" value="{{ last_username }}" placeholder="{{ 'security.login.username'|trans }}" required="required" />
<input type="password" id="password" name="_password" placeholder="{{ 'security.login.password'|trans }}" required="required" />
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" />
</form>
{{ render(controller('FOSUserBundle:Registration:register')) }}
{% endblock fos_user_content %}
app/Resources/FOSUserBundle/Registration/register.html.twig:
{% include "FOSUserBundle:Registration:register_content.html.twig" %}
But then I get the following error:
FatalErrorException: Error: Maximum function nesting level of '100' reached, aborting! in /private/var/www/symfony/My_UserBundle/vendor/twig/twig/lib/Twig/Node/Expression/Array.php line 31
I don't know why I get this error message. If I look into the Security:login and Registration:register controller, the templates get rendered in different ways:
$this->renderLogin(...
and
$this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html....
So basically I have two questions:
What does the error message mean and how can I solve it?
Maybe this approach is not ideal, is there a better solution for this?
You could use (as #Sidali Hallak said)
{% render url('fos_user_registration_register') %}
{% render url('fos_user_security_login') %}
But use your own versions of the FOSUserBundle:Registration:register.html.twig and FOSUserBundle:Security:login.html.twig templates that don't extend FOSUserBundle::layout.html.twig
To be compliant with newer Symfony versions, you should avoid using {% render %} tag and use {{ render(controller('MyBundle:ControllerClass:action')) }} instead:
{{ render(controller('FOSUserBundle:Security:login')) }}
{{ render(controller('FOSUserBundle:Registration:register')) }}
use :
{% render url('fos_user_security_login') %}
{% render url('fos_user_Registration_register') %}
The max nesting level comes from xdebug and can be resolved setting ...
xdebug.max_nesting_level = 200
... in your php.ini.