# Django Forms

# File Imports

Starts with the imports

from django import forms
from django.contrib.auth.models import User
from .models import *
from tinymce.widgets import TinyMCE

# Basic Form Code

Modify date input

class DateInput(forms.DateInput):
    input_type = 'date'

Take what you need 🎉 💯

#Character field with form validation bootstrap - make sure you install the JS and write the code on the front end for the validation
title = forms.CharField(
                    required = False,
                    label='Label for title',
                    widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter title', 'maxlength': '60', 'id': 'defaultconfig'}),
                    )

#Text Area Field 
description = forms.CharField(
                       required = True,
                       label='Enter Description',
                       widget=forms.Textarea(attrs={'class': 'form-control', 'placeholder': 'Enter full description ....', 'maxlength': '500', 'id': 'maxlength-textarea'}),
                       )


#Character field with input mask - make sure you write the accompanying code on the front end
#Input mask for phone number
phone = forms.CharField(
                    required = False,
                    label='Phone Number',
                    widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Phone Number', 'data-inputmask': "'mask': '+27(0)99-999-9999'"}),
                    )
#input mask for Email Address
email = forms.CharField(
                    required = False,
                    label='Email Address',
                    widget=forms.TextInput(attrs={'class': 'form-control input-mask', 'placeholder': 'Email Address', 'data-inputmask': "'alias': 'email'"}),
                    )

#Input for select choices
THE_OPTIONS = [
('option1', 'option1'),
('option2', 'option2'),
('option3', 'option3'),
]
options = forms.ChoiceField(
                    choices = THE_OPTIONS,
                    required = False,
                    label='Select an Option',
                    widget=forms.Select(attrs={'class': 'form-control'}),
                    )

#Tiny MCE Widget
from tinymce.widgets import TinyMCE
text = forms.CharField(required = False, widget=TinyMCE())

#Number Input
number = forms.CharField(
                    label='Enter the number beloe',
                    required = False,
                    widget=forms.NumberInput(attrs={'class': 'form-control'}),)

#File input that only accepts PDF
file = forms.FileField(
                      required=False,
                      label='Upload your File',
                      widget=forms.FileInput(attrs={'class': 'form-control', 'accept': '.pdf'}))

#Image Upload Field
image = forms.ImageField(
                      required=False,
                      label='Upload Image',
                      widget=forms.FileInput(attrs={'class': 'form-control'})
                      )

#Boolean checkbox imput
check  = forms.BooleanField(
                    required = False,
                    label='Does the question apply',
                    widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}))

#Date Field - Make Sure you import and edit DateField first
date = forms.DateField(
                        required = False,
                        label='Meeting Date',
                        widget=DateInput(attrs={'class': 'form-control', 'placeholder': 'Date of Meeting '}),
                        )

# Form Meta

At the bottom of the form

class Meta:
        model=XxxxModel
        fields=['all', 'the', 'fields']

# Form with Initiation Variables

In cases where you need to include in the form initiation reference to other models. In this case, we will need the contacts from Contact Model inside this form.

def __init__(self,*args,**kwargs):
        self.form_space = kwargs.pop('form_space')
        self.CONTACT_LIST = Contact.objects.filter(space=self.form_space)

        self.CONTACT_CHOICES = [('-----', '---Please Select---')]

        for contact in self.CONTACT_LIST:
            d_t = (contact.uniqueId, '{} {}'.format(contact.contactFirstName, contact.contactLastName))
            self.CONTACT_CHOICES.append(d_t)


        super(HustleForm,self).__init__(*args,**kwargs)

        self.fields['contact'] = forms.ChoiceField(
                                        label='Choose a related contact',
                                        choices = self.CONTACT_CHOICES,
                                        widget=forms.Select(attrs={'class': 'form-control mb-3'}),)

When you instantiate the form

form = TheForm(form_space=xxxxx)

Edit the form init to create a layout structure for Crispy Form (Saves tons of time)

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column


STATES = (
    ('option1', 'option1'),
    ('option2', 'option2'),
    ('option3', 'option3'),
)

class XxxxxForm(forms.Form):

  #Enter the Form Variables


    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Row(
                Column('email', css_class='form-group col-md-6'),
                Column('password', css_class='form-group col-md-6'),
                css_class='form-row'
            ),
            'address_1',
            'address_2',
            Row(
                Column('city', css_class='form-group col-md-6'),
                Column('state', css_class='form-group col-md-4),
                Column('zip_code', css_class='form-group col-md-2'),
                css_class='form-row'
            ),
            'check_me_out',
            Submit('submit', 'Sign in')
        )


When you render the HTML include the following

{% load crispy_forms_tags %}

{% crispy example_form %}

Make sure you download and install Crispy forms in your project. Read more fom the Crispy forms layout documentation (opens new window)