{% extends "subscribe-form.html" %} {% load static sekizai_tags djng_tags tutorial_tags %} {% block form_title %}Django Form Model as Scope{% endblock %} {% block form_header %}Django Form's two-way data-binding with an AngularJS controller{% endblock %} {% block form_tag %}name="{{ form.form_name }}" method="post" action="." validate ng-controller="MyFormCtrl"{% endblock %} {% block container %} {{ block.super }} {% addtoblock "js" %}{% endaddtoblock %} {% addtoblock "ng-requires" %}ngFileUpload{% endaddtoblock %} {% addtoblock "js" %}{% endaddtoblock %} {% addtoblock "ng-requires" %}djng.urls{% endaddtoblock %} {% addtoblock "ng-config" %}['$httpProvider', function($httpProvider) { $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; $httpProvider.defaults.headers.common['X-CSRFToken'] = '{{ csrf_token }}'; }]{% endaddtoblock %} {% endblock container %} {% block form_submission %}   {% endblock %} {% block form_foot %} {% verbatim %}
MyFormCtrl's scope:
subscribe_data = {{ subscribe_data | json }}
{% endverbatim %} {% endblock form_foot %} {% block demo_scripts %} {{ block.super }} {% endblock %} {% block tutorial_intro %}

This example shows how to reflect Django's form data into a AngularJS controller.

When working with Django Forms and AngularJS, it is a common use case to access the form's model from within an Angular controller. If the directive ng-model is added to an input field, then the controller's $scope object, always contains the actual field's content for further disposal.

If a form inherits from the mixin class NgModelFormMixin, then Django renders each Field with the directive ng-model="fieldname". To prevent the pollution of the scope's namespace, it is common practice to encapsulate all the form fields into a separate JavaScript object. The name of this encapsulating object can be set during the form definition, using the class member scope_prefix. Furthermore, set the class member form_name to a different name. Otherwise the mixin class will invent a unique form name for you. The form_name must be different from scope_prefix, because AngularJS's internal form controller adds its own object to the scope, using the form's name and this must be different from the scope's content.

In this example, an additional server-side validations has been added to the form: The method clean() rejects the combination of “John” and “Doe” for the first- and last name respectively. Errors for a failed form validation are send back to the client and displayed on top of the form.

Form data submitted by Ajax, is validated by the server using the same functionality. Errors detected during such a validation, are sent back to the client using a JSON object. In JavaScript, the controller submitting the form, shall use the returned data and pass it to the special function djangoForm.setErrors(), so that all validation errors can be displayed as usual. {% endblock tutorial_intro %} {% block tutorial_code %} {% autoescape off %}

{% pygments "forms/model_scope.py" %}
{% pygments "views/model_scope.py" %}
{% pygments "tutorial/model-scope.html" %}
{% pygments "static/js/model-scope.js" %}
{% endautoescape %} {% verbatim %}

Note: The AngularJS app is configured inside Django's HTML template code, since template tags, such as {​{ csrf_token }​} can't be expanded in pure JavaScript.

{% endverbatim %} {% endblock tutorial_code %}