Skip to content

Instantly share code, notes, and snippets.

@jab3z
Last active December 17, 2015 08:35
Show Gist options
  • Save jab3z/d098986ecc116dd2d6f5 to your computer and use it in GitHub Desktop.
Save jab3z/d098986ecc116dd2d6f5 to your computer and use it in GitHub Desktop.
Handle form submissions via Ajax
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