Last active
December 17, 2015 08:35
-
-
Save jab3z/d098986ecc116dd2d6f5 to your computer and use it in GitHub Desktop.
Handle form submissions via Ajax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function AjaxHandler() { | |
this.init = function(config) { | |
this.config = config; | |
this.bindEvents(); | |
}; | |
this.hideFormErrors = function($form) { | |
$.each($form.find(':input.required.error'), function(index, field) { | |
$form.find(field) | |
.removeClass('required error') | |
.next().remove() | |
}) | |
}; | |
this.renderFormErrors = function($form, payload) { | |
// show form errors received from server | |
$.each(payload, function(key, value) { | |
var fieldId = '#id_' + key; | |
var $error = $("<label>").attr({id: key + '-error', class: 'error', for: key}).text(value); | |
$field = $form.find(fieldId); | |
$field.addClass('required error') | |
.after($error) | |
}); | |
}; | |
this.handleSubmitResponse = function($form, payload) { | |
// hide form errors if exist | |
this.hideFormErrors($form); | |
if (payload.__all__) { | |
// means we have a general error | |
$.notify(payload.__all__, 'error') | |
}; | |
if (payload.error_message && _.isUndefined(payload.__all__)) { | |
// means we have an error msg from server | |
$.notify(payload.error_message, 'error'); | |
this.renderFormErrors($form, payload); | |
}; | |
if (payload.success_message) { | |
$.notify(payload.success_message, 'success') | |
}; | |
if (payload.redirect_url) { | |
window.location.replace(payload.redirect_url); | |
}; | |
}; | |
this.onDoneCallback = function($form, payload) { | |
this.handleSubmitResponse($form, payload); | |
}; | |
this.onFailCallback = function(response) { | |
console.log(response) | |
}; | |
this.beforeSubmission = function($form) { | |
// disable submit button | |
// $form.find('input[type="submit"]').attr('disabled', true) | |
}; | |
this.submitForm = function(e) { | |
var self = e.data.self; | |
e.preventDefault(); | |
var $form = $(this); | |
self.beforeSubmission($form); | |
$.ajax({ | |
url: $form.attr('action'), | |
type: 'post', | |
dataType: 'json', //always expect json on POST | |
data: $form.serialize() | |
}) | |
.done(function (payload) { | |
return self.onDoneCallback($form, payload) | |
}) | |
.fail(self.onFailCallback) | |
}; | |
}; | |
// Example | |
$(document).ready(function() { | |
function AccountHandler() { | |
this.bindEvents = function() { | |
this.config.registrationForm.on('submit', {self: this}, this.submitForm); | |
this.config.loginForm.on('submit', {self: this}, this.submitForm); | |
}; | |
}; | |
AccountHandler.prototype = new AjaxHandler(); | |
var account = new AccountHandler(); | |
account.init({ | |
registrationForm: $('#registration-form'), | |
loginForm: $('#login-form'), | |
}) | |
// Rules on backend | |
1. Error responses and success response must have 200 status and to be json encoded | |
2. For having a easy life on encoding the form errors as json, below you'll find a django abstract form class | |
3. General errors has to be under key '__all__'. Raising forms.ValidationError in clean method does that by default. IE 'This account is inactive' is a general error | |
4. If you are having a specific error message alongside with field errors, put it under 'error_message' key. IE 'An error has occured during form validation' (The below example of django form does that by default) | |
5. If needed to show a success mesage after form was saved successfully on the send a 'success_message' key, or if redirection to another page is required send the url to redirect under key 'redirect_url' | |
class AjaxBaseForm(forms.BaseForm): | |
def errors_as_dict(self, strip_tags=True): | |
errors = {} | |
for error in self.errors.iteritems(): | |
errors.update({error[0]: unicode(striptags(error[1]) if strip_tags else error[1])}) | |
errors['error_message'] = _('Errors has occurred during form validation.') | |
return errors | |
def form_invalid(self, form): | |
return JsonResponse(form.errors_as_dict()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment