Package: django-forms-ajaxified
A reusable Django app that allows to submit forms via AJAX.This is useful for two usecases:You have a very long form and you want to signal to your users that each
field they fill out is saved immediately and you want to show validation
errors immediately.You have a number of different forms that all have their own small
AJAX-views and partial templates and you all include them in one bigger
template. Each form should be able to communicate with it’s own AJAX-view
independently.Features:Error messages are displayed next to the field, when they happenA visual indicator is displayed on the field that has just been changed to
indicate that this value has been saved.InstallationTo get the latest stable release from PyPipipinstalldjango-forms-ajaxifiedTo get the latest commit from GitHubpipinstall-egit+git://github.com/bitmazk/django-forms-ajaxified.git#egg=forms_ajaxifiedAddforms_ajaxifiedto yourINSTALLED_APPSINSTALLED_APPS=(...,'django_libs','forms_ajaxified',)Adddjango_libs.middleware.AjaxRedirectMiddlewareto yourMIDDLEWARE_CLASSESMIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware',...'django_libs.middleware.AjaxRedirectMiddleware',]In yourbase.htmlinclude the jQuery plugin that loads your forms and
handles the AJAX responses. You should place it somewhere below your jQuery
include:{% load staticfiles %}
...<scriptsrc="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script><scriptsrc="{% static "forms_ajaxified/js/forms_ajaxified.js"%}"></script>At the bottom of yourbase.htmlor whereever you run global
initialisations, activate the jQuery plugin:<script>$(document).ready(function(){$('[data-class="form_ajaxified"]').formsAjaxified();});</script>If you are using Bootstrap, you can add a green border around an input element
via CSS transitions similar to the blue border when the element is focused.
Simply add the following to your project’s styles:input.success,textarea.success,select.success{@color-rgba:rgba(red(@brand-success),green(@brand-success),blue(@brand-success),.6);border-color:@color-rgba;.box-shadow(~"inset01px1pxrgba(0,0,0,.075),008px@{color-rgba}");}UsageThis example assumes that you have a bigTemplateViewthat contains one
or more small partial templates with forms. You could just as well just use
one bigFormView, as usual.First you should write a TemplateView that renders the whole template and
reserves some space for its one or many forms to be loaded:fromdjango.views.genericimportTemplateViewclassMyTemplateView(TemplateView):template_name='myapp/my_template_view.html'The template for this view should look something like this:{% extends "base.html" %}<formmethod="post"action="{% url "my_form_view"%}"data-class="form_ajaxified"></form>As you can see, the form is empty but thanks to thedata-classattribute,
our jQuery plugin will be able to find all such forms on your template. It will
read theactionattribute and send an AJAX GET request to theactionview and initially retrieve the returned partial.Now you should write a simple Form and a FormView that returns the partial
template that renders this form. By adding theAjaxFormViewMixinyou
enable your view to return proper JSON responses when handling POST requests.
We only show a code snippet for one such FormView but you could have many of
them and load them all in a TemplateView that ties everything together:fromdjango.views.genericimportFormViewfromforms_ajaxified.viewsimportAjaxFormViewMixinfrommyapp.formsimportMyFormclassMyFormView(AjaxFormViewMixin,FormView):form_class=MyFormtemplate_name='myapp/partials/my_form.html'The partial template for your form should look something like below. Note that
the template does not contain aformtag because we already have that in
the “outer” template of the TemplateView above:{% for field in form %}
    {% include "django_libs/partials/form_field.html" %}
{% endfor %}<inputtype="submit"name="btn_submit"value="Submit"/>If everything is setup correctly, the jQuery plugin will initially load all
forms and then monitor all changes in their fields. On every data change, it
will send a POST request to the corresponding AJAX-view. If validation errors
happen, they will appear next to their fields. If data was saved successfully,
a visual indicator will inform the user about this. In theory, the form would
not even need a submit button, it is up to the developer to decide if it should
be there or not.RedirectingSometimes a successful POST to your form changes thing so drastically that
you need to redirect to another page (i.e. when you change the title of an
object, which also changes it’s slug and you need to redirect to a new URL with
the new slug).In this case, please add the following hidden input to your form:<inputtype="hidden"name="form_valid_redirect"value="1"/>Make sure that you have theAjaxRedirectMiddlewarein yourMIDDLEWARE_CLASSESsetting. Now your form will always redirect on a
successful submit.If you want your form to only redirect in certain situations (i.e. only
when the slug has been changed), you can do something like this in your view:classMyFormView(AjaxFormViewMixin,FormView):defform_valid(self,form):form_valid_redirect=self.request.POST.get('form_valid_redirect')ifsome_condition:form_valid_redirect=Falsereturnsuper(MyFormView,self).form_valid(form,form_valid_redirect=form_valid_redirect)As you can see, theform_validimplementation ofAjaxFormViewMixinallows an additional kwargform_valid_redirect. When you don’t pass in that
kwarg, the mixin will try to get that value from the POST data (from your
hidden field) but when you pass in that kwarg, it will override the POST data.jQuery Plugin OptionsThe jQuery plugin supports the following options:default_loading_textDefault:Submitting…Set this if you want to use a different text to be shown on submit buttons when
submitting the form. The original button text will be replaced with this one
and the button will be disabled. When the request returns, the changes will
be undone.jQuery Plugin Data AttributesThe following data attributes allow to adjust the behaviour of the plugin:data-id=”form_ajaxified”Set this attribute on all forms that should be controlled by this app.data-loading-text=”Loading…”Set this attribute on submit buttons that should have special loading texts.
This overrides the plugin optiondefault_loading_text.data-autosave=”1”Set this attribute on input elements and they will trigger a form submit every
15 seconds.data-autosave-interval=”1000”Set this attribute alongsidedata-autosaveto override the default interval
of 15 seconds. The value represents milliseconds.data-ajax-add-wrapper=”[data-id=’some-element’]”If you have an “Add item” button somewhere on your page that should create
a new item and display a new partial form to edit that new item, you can
add this attribute to the button element. The value of the attribtue should
be a selector that selects the wrapper element that should get the new form
partial appended.data-ajax-delete-element=”[data-id=’some-element’]”If you have “Delete item” buttons on your page that should delete a form
partial from your page, you can add this attribute to the button element. The
value of the attribtue should be a selector that selects the element that
should be deleted. The form that contains the delete button will be deleted as
well.ContributeIf you want to contribute to this project, please perform the following steps# Fork this repository
# Clone your forkmkvirtualenv-ppython2.7django-forms-ajaxifiedmakedevelopgitco-bfeature_branchmaster# Implement your feature and testsgitadd.&&gitcommitgitpush-uoriginfeature_branch# Send us a pull request for your feature branch