Prepend or append icon in field of django-crispy-forms - django

I have the following field in a Form:
<div class="form-group ">
<div class="input-group">
<input class="form-control" id="To" name="To" placeholder="To" type="text"/>
<i class="glyphicon glyphicon-map-marker form-control-feedback"></i>
</div>
</div>
which looks like
and I am trying to have a similar result using crispy-forms.
I tried
self.helper.layout = Layout(
Fieldset(
'Title',
PrependedText(
'From',
<i class="glyphicon glyphicon-map-marker"></i>
),
'To',
'Date',
ButtonHolder(
Submit('submit', 'Search', css_class='button white')
)
)
)
but I get a SyntaxError: invalid syntax.
Is it possible to add an icon as PrependedText in crispy-forms?
If not, is there any alternative?
(Edit)
Trying
self.helper.layout = Layout(
Field(PrependedText('From', HTML('<span class="glyphicon glyphicon-map-marker"></span>')), placeholder='From'),
'To',
'Date',
ButtonHolder(
Submit('submit', 'Search', css_class='button white')
)
)
does not raise any error, but no icon is shown.

self.helper.layout = Layout(
Div(HTML('''
<div class="input-group">
<input class="form-control" id="To" name="To" placeholder="To" type="text"/>
<i class="glyphicon glyphicon-map-marker form-control-feedback"></i>
</div>'''),
class="form-group")

This works with placeholders:
self.helper = FormHelper()
self.helper.form_show_labels = False
self.helper.layout = Layout(
Field(
PrependedText('email',
mark_safe('<span class="glyphicon glyphicon-envelope"></span>'),
placeholder=_("Enter Email"), autofocus="")
),
Field(
PrependedText('name',
mark_safe('<span class="glyphicon glyphicon-user"></span>'),
placeholder=_("Enter Full Name"))
),

An alternative to using glyphicons would be using similar unicode symbols:
self.helper.layout = Layout(
Field(PrependedText('From', '&#x1f4cc'), placeholder='From'),
Field(PrependedText('To', '&#x1f4cc'), placeholder='To'),
Field(PrependedText('Date', '&#x1f4c5'), placeholder='Date'),
FormActions(ButtonHolder(Submit('submit', 'Search', css_class='btn btn-primary')))
)
Problem here is that placer holder is for some reason not working...
Note also that appending '︎' to the unicode symbols to force that it is not rendered to emojis, as suggested here, does not seem to work.

just use django's mark_safe helper like this:
from django.utils.safestring import mark_safe
Field(PrependedText('From',
mark_safe('<span class="glyphicon glyphicon-map-marker"></span>')),
placeholder='From')

Related

I am using crispy form to render the form. In my form there is one multiple checkbox field.I want to show some options as selected.How to do that

I am using django-crispy-forms. One of the form field is multiple choice checkbox. In this checkbox i wanted to show some options as checked. How to do that.
choices are declared as:-
documents_req = (
('1', 'TC'),
('2', 'Marksheet'),
('3', 'Char Cert'),
('4', 'Caste Cert')
)
Form is created as following:-
class AddStudentForm(forms.Form):
....
....
documents_required =
forms.MultipleChoiceField(choices=documents_req,required=False,
widget=forms.CheckboxSelectMultiple)
def init(self, *args, **kwargs):
super().init(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-horizontal'
self.helper.form_tag = False
self.helper.label_class = 'col-lg-3'
self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(
Div(
Div('email', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('password', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('address_1', css_class='form-group col-sm-4 mb-0
border border-secondary'),
css_class='form-row'),
Div(
Div('address_2', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('city', css_class='form-group col-sm-4 mb-0
border border-secondary'),
Div('state', css_class='form-group col-sm-4 mb-0
border border-secondary'),
css_class='form-row'),
Div(
Div(InlineCheckboxes('documents_required'),css_class='form-group col-sm-6 mb-0 border border-secondary'),
Div('zip_code', css_class='form-group col-sm-3 mb-0 border border-secondary'),
Div('check_me_out', css_class='form-group col-sm-3 mb-0 border border-secondary'),
css_class='form-row')
)
It is perfectly showing the checkboxes. But I wanted some choices let's say option 1 and 2 to be checked. How to achieve that.
form_field = forms.MultipleChoiceField(choices=[("1", "option 1"),("2", "optiom 2")])

Is it possible to create an edit form using crispy form?

I've a form named "CarForm". I 've created a "Create Form" to create car record using crispy form. I would like to ask is it possible to display the detail and update the car record using the same form?
Here is the code for CarForm:
from .models import *
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, HTML, Row, Column
from crispy_forms.bootstrap import PrependedAppendedText, PrependedText, FormActions
from django.urls import reverse
class CarForm(forms.ModelForm):
note = forms.CharField(widget=forms.Textarea())
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['note'].required = False
self.fields['policy_num'].required = False
self.helper = FormHelper()
self.helper.form_method = 'POST'
self.helper.form_action = reverse('create')
self.helper.layout = Layout(
Row(
Column('reg_num', css_class='form-group col-md-6 mb-0'),
Column('make', css_class='form-group col-md-6 mb-0'),
Column('year', css_class='form-group col-md-4 mb-0'),
Column('color', css_class='form-group col-md-4 mb-0'),
Column('cc', css_class='form-group col-md-4 mb-0'),
Column('engine_num', css_class='form-group col-md-6 mb-0'),
Column('chasis_num', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
'note',
Row(
Column(PrependedAppendedText('price_buy', 'RM','.00'), css_class='form-group col-md-6 mb-0'),
Column(PrependedAppendedText('price_sell','RM','.00'), css_class='form-group col-md-6 mb-0'),
Column('policy_num', css_class='form-group col-md-12 mb-0'),
Column('owner_name', css_class='form-group col-md-4 mb-0'),
Column('owner_ic',css_class='form-group col-md-4 mb-0'),
Column('owner_phone', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
FormActions(
Submit('submit', 'Create'),
)
)
class Meta:
model = Car
exclude = ['date']
Code in views.py.
I've added instance in the edit function, but there is an error for all the field this field is required
def edit(request,id):
car = Car.objects.get(id=id)
form = CarForm(request.POST,instance=car)
context = { 'car':car ,'form':form }
return render(request,'cars/edit.html',context)
def update(request,id):
car = Car.objects.get(id=id)
car.reg_num = request.POST['reg_num']
car.make = request.POST['make']
car.color = request.POST['color']
car.year = request.POST['year']
car.engine_num = request.POST['engine_num']
car.chasis_num = request.POST['chasis_num']
car.note = request.POST['note']
car.price_buy = request.POST['price_buy']
car.price_sell = request.POST['price_sell']
car.policy_num = request.POST['policy_num']
car.owner_name = request.POST['owner_name']
car.owner_ic = request.POST['owner_ic']
car.owner_phone = request.POST['owner_phone']
car.save()
messages.success(request,'Car "%s" updated successfully' % car.reg_num)
return redirect('/cars/list/')
Here is the code for edit.html:
{% block title %}Edit Car Record{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<h1 align="center">Edit Car Record</h1>
{% crispy form %}
{% endblock %}

Django login from in modal window

I have a login form and I want to put in modal window in header.
Urls.py
url(r'^account/login/$', appuser_views.LoginView.as_view(template_name = 'account/login/index.html', form_class = appuser_forms.LoginForm, target_url = LOGIN_TARGET_URL)),
views.py
class LoginView(ResendEmailToUsersMixin, AjaxFormView):
def process_form(self, request, form):
data = form.cleaned_data
a = AppUserCredential.objects.select_related('appuser').filter(
data1 = data['email_address'],
credential_type = AppUserCredential.CREDENTIAL_TYPES.EMAIL_PASSWORD,
appuser__status = AppUser.STATUS_TYPES.Active
).first()
force_error = False
if a is None:
response = self.resend_email_to_users(data = data)
if response is not None:
return response
#If no email exists force the error and don't check the password
force_error = True
if force_error or not a.check_password(data['password']):
return AjaxErrorResponse(code="login_error", title="Username or Password Error", message="The username or password you have provided don’t match our records. Please check your entries and try again.")
a.appuser.login(request)
forms.py
class LoginForm(AjaxForm):
email_address = forms.EmailField(label = "Email Address", required = True, max_length = 100,
widget = forms.TextInput(attrs = {'placeholder': 'email#domain.com', 'autocomplete':'off'}))
password = forms.CharField(label = "Password", required = True, max_length = 100,
widget = forms.PasswordInput(attrs = {'placeholder': 'Password', 'autocomplete':'off'}))
def setup_form_helper(self, helper):
helper.form_id = 'login_form'
helper.layout = Layout(
'email_address',
'password',
Div(
Submit('submit', 'Login', css_class='btn btn-primary'),
css_class="form-group text-center"
),
HTML('<p class="pull-right light-top-bottom-padding">Forgot Password?</p>')
)
/templates/account/login/index.html
...
{% crispy form form.helper %}
...
I have created modal window in /templates/layouts/header.html
How can I put {% crispy form form.helper %} in the modal window?
Thanks.
UPD1:
If I put {% crispy form form.helper %} in header.html I got the error
VariableDoesNotExist at / Failed lookup for key [form] in u'[{\'False\': False, \'None\': None, \'True\': True},
UPD2:
Modal form:
login
<div id="login" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
<div class="panel-body">
<header class="section-title text-center normal-top-bottom-padding">
<h1>Login</h1>
</header>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Link to login should be in every page.
If you want to display the form in all pages, you need to add the form (better call it login_form so it doesn't conflict with other forms you may have) to every View's context.
To avoid doing that repeatedly in all Views, Django has Context Processors. You include them in settings.py's TEMPLATES variable. Example
TEMPLATES = [{
...
'OPTIONS': {
'context_processors': [
...
'myapp.context_processors.add_my_login_form',
],
}]
Then, create a file called context_processors.py and add the add_my_login_form() function in there. The function returns the login_form to the request context of all requests.
def add_my_login_form(request):
return {
'login_form': LoginForm(),
}
Since you are rendering the form in every page, it maybe good to use template caching.

django-crispy-forms: form_class appears but label_class and field_class does not

This is my first time using crispy-forms and I am trying to make a horizontal crispy-form based on a ModelForm using bootstrap 3. In the output to the template "horizontal-form" shows up but "label_class" and "field_class". I've looked through many the documentation and stackoverflow, including this question and nothing seems to work.
My Form:
from django.forms import ModelForm
from panews.models import Story
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout
class StoryForm(ModelForm):
class Meta:
model = Story
fields = ['title', 'subtitle', 'content', 'variables']
def __init__(self, *args, **kwargs):
super(StoryForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = "POST"
self.helper.form_class = "horizontal-form"
self.helper.label_class = "col-lg-2"
self.helper.field_class = "col-lg-8"
self.helper.layout = Layout(
'title',
'subtitle',
'content',
'variables',
)
Here's the template:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block main %}
<div class="container">
{% crispy form %}
</div>
{% endblock %}
Here's the output:
<main>
<div class="container">
<form class="horizontal-form" method="post" ><input type='hidden' name='csrfmiddlewaretoken' value='phDTwXgeNifQ8DJT8VWtG2stLEDA4LQS' /> <div id="div_id_title" class="control-group"><label for="id_title" class="control-label requiredField">
Title<span class="asteriskField">*</span></label><div class="controls"><input class="textinput textInput" id="id_title" maxlength="50" name="title" type="text" /> </div></div><div id="div_id_subtitle" class="control-group"><label for="id_subtitle" class="control-label ">
Subtitle
</label><div class="controls"><input class="textinput textInput" id="id_subtitle" maxlength="50" name="subtitle" type="text" /> </div></div><div id="div_id_content" class="control-group"><label for="id_content" class="control-label ">
Content
</label><div class="controls"><textarea class="textarea" cols="40" id="id_content" name="content" rows="10"></textarea></div></div><div id="div_id_variables" class="control-group"><label for="id_variables" class="control-label ">
Variables
</label><div class="controls"><textarea class="textarea" cols="40" id="id_variables" name="variables" rows="10"></textarea></div></div></form>
</div>
</main>
This is my first question on stack overflow so please let me know how I can improve future questions or my research methods.
Thanks,
Nathan
Append to settings.py
CRISPY_TEMPLATE_PACK = 'bootstrap3'

how to apply Django crispy_forms to create an attractive layout?

i tried the following code to create a form using Django crispy_forms but when it rendered gives simple html for layout
forms.py
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class SimpleForm(forms.Form):
username = forms.CharField(label="Username", required="True")
password = forms.CharField(label="Password", required="True", widget=forms.PasswordInput)
remember = forms.BooleanField(label="Remember Me !")
helper = FormHelper()
helper.form_method = 'POST'
helper.add_input(Submit('login', 'login', css_class='btn-primary'))
index.html
{% load crispy_forms_tags %}
<html>
<head>
<link rel="stylesheet" type="text/css" href="/home/vish/demo/new_form/form_demo/templates/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
{% crispy form %}
</div>
</div>
</body>
</html>
what's I'm doing wrong ? Please suggest the necessary improvements.
You can define the layout, for example:
self.helper.layout = layout.Layout(
Div(
Div(
Fieldset('',
Div(
Div(
'first_name',
css_class="col-sm-6",
),
Div(
'last_name',
css_class="col-sm-6",
),
css_class="row",
),
),
css_class='row'
),
)
Obs: I used bootstrap classes in this example, that what you should do!