Skip to content

Instantly share code, notes, and snippets.

@dimusik
Created December 7, 2016 17:55
Show Gist options
  • Save dimusik/84242e048c67e7508820a97e2c5d0902 to your computer and use it in GitHub Desktop.
Save dimusik/84242e048c67e7508820a97e2c5d0902 to your computer and use it in GitHub Desktop.
$(function() {
$.fn.serializeObject = function(options) {
options = jQuery.extend({}, options);
var self = this,
json = {},
push_counters = {},
patterns = {
"validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
"key": /[a-zA-Z0-9_]+|(?=\[\])/g,
"push": /^$/,
"fixed": /^\d+$/,
"named": /^[a-zA-Z0-9_]+$/
};
this.build = function(base, key, value) {
base[key] = value;
return base;
};
this.push_counter = function(key) {
if (push_counters[key] === undefined) {
push_counters[key] = 0;
}
return push_counters[key]++;
};
jQuery.each(jQuery(this).serializeArray(), function() {
if(!patterns.validate.test(this.name)) {
return;
}
var k,
keys = this.name.match(patterns.key),
merge = this.value,
reverse_key = this.name;
while ((k = keys.pop()) !== undefined) {
reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');
if (k.match(patterns.push)) {
merge = self.build([], self.push_counter(reverse_key), merge);
} else if(k.match(patterns.fixed)) {
merge = self.build([], k, merge);
} else if(k.match(patterns.named)) {
merge = self.build({}, k, merge);
}
}
json = jQuery.extend(true, json, merge);
});
return json;
};
$.fn.increment = function (from, to, duration, easing, complete) {
var params = $.speed(duration, easing, complete);
return this.each(function(){
var self = this;
params.step = function(now) {
self.innerText = now << 0;
};
$({number: from}).animate({number: to}, params);
});
};
});
function Form(form, messenger, messages, successCallback) {
var $form = form,
messenger = messenger,
messages = messages,
successCallback = successCallback,
errorBox = '<label class="error">{{ error }}</label>';
this.cleanErrors = function() {
$form.find('input').each(function() {
$(this).parent().removeClass('has-error');
});
$('.error').each(function() {
$(this).remove();
});
};
this.post = function() {
$.ajax({
context: this,
url: $form.attr('action'),
type: $form.attr('method'),
data: JSON.stringify($form.serializeObject()),
contentType: "application/json; charset=utf-8",
dataType: 'json',
beforeSend: function () {
this.blockSubmitButton();
this.cleanErrors();
messenger.post({
message: messages.beforeSend,
hideAfter: 3,
showCloseButton: true
});
},
success: function (data, status, request) {
messenger.post(messages.success);
$form.find('input').each(function() {
$(this).val('');
});
if (request.status == 201
&& request.getResponseHeader('Content-Disposition') == 'attachment'
) {
$.fileDownload(request.getResponseHeader('Location'));
}
typeof successCallback === 'function'
? successCallback(data) : window.location.reload();
},
error: function (data) {
switch (data.status) {
case 500:
messenger.post({
message: messages.error,
type: 'error',
showCloseButton: true
});
break;
case 200:
break;
default:
this.renderErrors(data);
}
},
complete: function () {
this.unblockSubmitButton();
}
});
};
this.blockSubmitButton = function() {
$form.find('#submit-form').prop('disabled', true);
};
this.unblockSubmitButton = function() {
$form.find('#submit-form').prop('disabled', false);
};
this.renderErrors = function(data) {
data = data.responseJSON;
messenger.post({ message: data.message, type: 'error', showCloseButton: true });
if (!data.hasOwnProperty('errors')) {
return;
}
$.each(data.errors, function (field, error) {
var $parent = '',
fieldAsArray = field.split('.'),
fieldName = fieldAsArray.shift();
if (fieldAsArray.length > 0) {
$.each(fieldAsArray, function (key, value) {
fieldName += '[' + value + ']';
})
}
$('[name="' + fieldName + '"]').parent().addClass('has-error');
$parent = $('[name="' + fieldName + '"]').parent();
$parent.after(errorBox.replace(/{{ error }}/, error));
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment