Skip to content
Tobias von Klipstein edited this page Jun 6, 2012 · 12 revisions

How to enable Dojo's form functionality in dojango.

Note: The form integration just works with Django version >= 1.0.2

Since version 0.4 dojango provides the capability to use Dojo form elements the same as you would use normal forms in Django. The big advantage of this is, that you can e.g. let the user enter a date via a date-picker, let him format a descripton with a rich text editor or let him select an integer value with a number spinner or a slider. Another benefit of using Dojango forms is, that Django's form validation is passed to the Dojo widgets so the entered data can be validated in the frontend with the same validation rules without needing to define them in your JavaScript code again. Of course you also can define the look and feel of your Dojo widgets by defining DOJANGO_DOJO_THEME in your settings.py (see Configuration).

Dojango let you define those enhanced Dojo widgets within your Django code. There is not much new to learn, if you use Dojango forms. All form fields, widgets and other form functionality that is available in Django (e.g. forms for models, formsets, ...) is now implemented (extended) within dojango. If you would like to enhance your normal django forms with more enhanced Dojo form elements, you now just simply have to import the forms library from dojango:

# instead of
# from django.forms import *
# do this:
from dojango.forms import *

To use the form integration, you first have to follow the GettingStarted guide and additionaly have to enable the following middleware in your settings.py:

MIDDLEWARE_CLASSES = (
    'dojango.middleware.DojoCollector',
    # (not named DojoAutoRequireMiddleware anymore!)
    # ...
)

This middleware initializes a collector module for the current request thread, where each individual widget can add its used Dojo modules. All collected modules of one request are then available in the template context DOJANGO.COLLECTOR. If you extend your template from `dojango/base.html` or `dojango/base_i18n.html` you don't have to care about it. Just generate your dojango form and place it in the template block dojango_content:

{% extends "dojango/base.html" %}
{% block dojango_content %}
    {# PLACE YOUR FORMS HERE #}
{% endblock %}

If you use `include.html` or `include_i18n.html` you have to deal with the Dojo collector in your template on your own:

<script type="text/javascript">
    {% for require in DOJANGO.COLLECTOR %}
        dojo.require("{{ require }}");
    {% endfor %}		
</script>

Form fields and widgets

The main difference between the Django form fields and the Dojango ones is, that all validation attributes are passed to the widgets. Dojo's form elements can also validate individual form elements in the browser and dojango just populates the validation of the form fields to each widget. Thus the following possible form field attributes are forwarded to the assigned widget:

  • required
  • help_text
  • min_value
  • max_value
  • max_length
  • max_digits
  • decimal_places
  • js_regex

The widget itself then decides, how each attribute is assigned to the Dojo widget. In the following table you see, which widget is assigned as default to a form field and which validation parameters are possible within that form field:

dojango.forms.fields (extended django.forms.fields) dojango.forms.widgets possible parameters
CharField ValidationTextInput required, help_text, max_length, min_length
ChoiceField Select required, help_text
TypedChoiceField Select required, help_text
IntegerField NumberTextInput required, help_text, max_value, min_value
BooleanField CheckboxInput required, help_text
FileField FileInput required, help_text
ImageField FileInput required, help_text
DateField DateInput required, help_text, min_value, max_value
TimeField TimeInput required, help_text, min_value, max_value
DateTimeField DateTimeInput required, help_text, min_value, max_value
SplitDateTimeField DateTimeInput required, help_text, min_value, max_value
RegexField ValidationTextInput required, help_text, js_regex
DecimalField NumberTextInput required, help_text, max_value, min_value, max_digits, decimal_places
FloatField ValidationTextInput required, help_text, max_value, min_value
FilePathField Select required, help_text
MultipleChoiceField SelectMultiple required, help_text
NullBooleanField NullBooleanSelect
EmailField EmailTextInput required, help_text
IPAddressField IPAddressTextInput required, help_text
URLField URLTextInput required, help_text
SlugField ValidationTextInput required, help_text

Dojango widgets utilizing Dojo widgets

As described above several field attributes are now passed to the widget and the widget evaluates what attribute can be set within the assigned Dojo widget (see Field attribute => Widget attribute column). Dojo widgets support more attributes (for possible attributes see the documentation of each Dojo widget in the Dojo API or the User documentation of Dojo) than just validation attributes and it is possible to define those separately. The following example shows, how a form field can be defined with a Dojo widget that has additional attributes (same as for normal html form elements in django):

from dojango.forms import *
my_field = DateField(
    required=True, 
    help_text="Enter a valid date!", 
    widget=DateInput(
        attrs={
            'invalidMessage': 'The date is invalid!', 
            'class': 'customClass'
        }
    ))

As you can see in this example we pass in two additional parameters (`invalidMessage`, `class`) to the widget. The `required` and the `help_text` attributes itself are passed automatically to the widget and it is not nescessary to define that as an additional parameter.

The resulting HTML for that field would look like this (Dojango is defining Dojo widgets declaratively):

<input dojoType="dijit.form.DateTextBox" 
    promptMessage="Enter a valid date!" 
    name="my_field" 
    invalidMessage="The date is invalid!" 
    id="id_my_field" 
    required="true" 
    type="text" 
    class="customClass"/>

Overwritten Django's default widgets

dojango.forms.widgets (extended django.forms.widgets) Dojo widget Field attribute => Widget attribute Notes
Widget dijit._Widget
Input
TextInput dijit.form.TextBox max_length => maxLength
PasswordInput dijit.form.TextBox max_length => maxLength
HiddenInput dijit.form.TextBox
MultipleHiddenInput dijit.form.TextBox
FileInput dojox.form.FilenInput additional CSS: dojox/form/resources/FileInput.css
Textarea dijit.form.Textarea max_length => maxLength
DateInput dijit.form.DateTextBox required => required
help_text => promptMessage
min_value => constraints["min"]
max_value => constraints["max"]
TimeInput dijit.form.TimeTextBox required => required
help_text => promptMessage
min_value => constraints["min"]
max_value => constraints["max"]
CheckboxInput dijit.form.CheckBox
Select dijit.form.FilteringSelect (Dojo <= 1.3.2)
dijit.form.Select (since Dojo 1.4.0)
required => required
help_text => promptMessage (just with Dojo <= 1.3.2)
NullBooleanSelect dijit.form.FilteringSelect (Dojo <= 1.3.2)
dijit.form.Select (since Dojo 1.4.0)
required => required
help_text => promptMessage (just with Dojo <= 1.3.2)
SelectMultiple dijit.form.MultiSelect
RadioInput identical to Django's RadioInput
RadioFieldRenderer identical to Django's RadioInput
RadioSelect dijit.form.RadioButton
CheckboxSelectMultiple dijit.form.CheckBox
MultiWidget
SplitDateTimeWidget using DateInput and TimeInput
DateTimeInput same as SplitDateTimeWidget
SplitHiddenDateTimeWidget dijit.form.TextBox

Additional widgets

The following widgets don't have an equivalent Django widget.

dojango.forms.widgets Dojo widget Field attribute => Widget attribute Notes
SimpleTextarea dijit.form.SimpleTextarea max_length => maxLength
EditorInput dijit.Editor
HorizontalSliderInput dijit.form.HorizontalSlider min_value => minimum
max_value => maximum
VerticalSliderInput dijit.form.VerticalSlider min_value => minimum
max_value => maximum
ValidationTextInput dijit.form.ValidationTextBox required => required
help_text => promptMessage
js_regex => regExp
max_length => maxLength
ValidationPasswordInput dijit.form.ValidationTextBox required => required
help_text => promptMessage
js_regex => regExp
max_length => maxLength
EmailTextInput dijit.form.ValidationTextBox required => required
help_text => promptMessage
js_regex => regExp
max_length => maxLength
using the following regex: dojox.validate.regexp.emailAddress
IPAddressTextInput dijit.form.ValidationTextBox required => required
help_text => promptMessage
js_regex => regExp
max_length => maxLength
using the following regex: dojox.validate.regexp.ipAddress
URLTextInput dijit.form.ValidationTextBox required => required
help_text => promptMessage
js_regex => regExp
max_length => maxLength
using the following regex: dojox.validate.regexp.url
NumberTextInput dijit.form.NumberTextBox required => required
help_text => promptMessage
min_value => constraints["min"]
max_value => constraints["max"]
decimal_places => constraints["places"]
RangeBoundTextInput dijit.form.RangeBoundTextBox required => required
help_text => promptMessage
min_value => constraints["min"]
max_value => constraints["max"]
decimal_places => constraints["places"]
NumberSpinnerInput dijit.form.DateTextBox required => required
help_text => promptMessage
min_value => constraints["min"]
max_value => constraints["max"]
decimal_places => constraints["places"]
RatingInput dojox.form.Rating max_value => numStars
DateInputAnim dijit.form.DateTextBox required => required
help_text => promptMessage
min_value => constraints["min"]
max_value => constraints["max"]
additional CSS: dojox/widget/Calendar/Calendar.css
DropDownSelect dojox.form.DropDownSelect required => required
help_text => promptMessage
additional CSS: dojox/form/resources/DropDownSelect.css
CheckedMultiSelect dojox.form.CheckedMultiSelect required => required
help_text => promptMessage
additional CSS: dojox/form/resources/CheckedMultiSelect.css. The option _multiple_ can't be used on that widget.
FilteringSelect dijit.form.FilteringSelect required => required
help_text => promptMessage
ComboBox dijit.form.ComboBox required => required
help_text => promptMessage
FilteringSelectStore dijit.form.FilteringSelect required => required
help_text => promptMessage
This form widget requires a URL (that is providing a dojo data source) as first parameter. It uses dojo.data.ItemFileReadStore as default store, which can be changed by passing an additional store attribute. Also additional store attributes can be passed via store_attrs.
ComboBoxStore dijit.form.ComboBox required => required
help_text => promptMessage
This form widget requires a URL (that is providing a dojo data source) as first parameter. It uses dojo.data.ItemFileReadStore as default store, which can be changed by passing an additional store attribute. Also additional store attributes can be passed via store_attrs.
ListInput dojox.form.ListInput