JavaScript Module with Absctract factory pattern realization
var MYAPP = MYAPP || {}; //isolated namespace
if (MYAPP.company){
console.warn('WARNING: MYAPP.company is already defined!');
}else{
MYAPP.company = (function() {
// variables
var that = {};
// factory for on page form objects
function Forms(){}
// methods to perform ajax responses to send and receive data from the server
Forms.prototype = {
/**
* submit() realization
*/
// ajax request realization
submit: function (dataToSend) {
var self = this;
if(!dataToSend){
dataToSend = '';
}
$.ajax({
type: 'POST',
url: self.ajaxPath,
data:dataToSend,
processData: false,
contentType: false,
success: function(data) {
self.afterSubmit(data);
}
});
},
// check if there exists custom data manipulation handler and evaluate it
beforeSubmit: function (data, formName) {
var handler = this.beforeSubmitHandler,
formData = data;
this.formData = JSON.parse('{"' + decodeURI(formData).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}');
this.formId = formName;
if(typeof handler == 'function'){
// if particular data change required
this.formData = handler(data, formName);
this.submit(data);
} else{
this.submit(data);
}
},
afterSubmit: function (data) {
var handler = this.afterSubmitHandler;
if(typeof handler == 'function'){
handler(data);
} else{
throw{
name: 'Error',
message: " handler function for processing response after form submit not defined, please define it!"
};
}
},
/**
* refreshes form state: if value was entered by user, then there will be label with rhis value
* or there will be prompt to enter value
* @function
* @public
*/
refreshHtml: function () {
var pureText = $.trim( this.$staticValue.text()).replace(/[^0-9a-zA-Zа-я\s]/g,'').replace( /(\d)\s/, '' ).replace(/\s+/g,'');
if(($.trim( this.$staticValue.text()) == '' || pureText == 'NoneNone') && this.$wrapper.length && this.refrashable){
this.$editable.addClass('hidden');
this.$editable.removeClass("active");
this.$description.removeClass('hidden');
}else if(this.$wrapper.length && this.refrashable){
this.$editable.removeClass('hidden');
this.$description.addClass('hidden');
}
}
};
/**
* factory object directly
* @param {String} type - type of fabricated object
* @param {String} ajaxpath - attribute action from each form html element
*/
Forms.factory = function (type, ajaxpath) {
var constr = type,
newForm;
if (typeof Forms[constr] !== 'function'){
throw{
name: 'Error',
message: constr + "doesen't exist"
};
}
if(typeof Forms[constr].prototype.beforeSubmit !== "function"){
Forms[constr].prototype = new Forms();
}
newForm = new Forms[constr](ajaxpath);
return newForm;
};
/**
* set of child objects that will override the factory default
*/
Forms.name_form = function (path) {
this.afterSubmitHandler = function (data) {
if (data.success){
$('#static-name-value').text($('#id_name').val());
this.refreshHtml();
}else{
this.$editable.addClass('err');
}
};
this.ajaxPath = path;
};
Forms.email_form = function (path) {
var mailValue;
this.afterSubmitHandler = function (data) {
if (data.success){
mailValue = $('#id_email').val();
$('#static-email-value').attr('href', 'mailto:'+mailValue).text(mailValue);
this.refreshHtml();
}else{
this.$editable.addClass('err');
}
};
this.ajaxPath = path;
};
Forms.found_form = function (path) {
var currValue,
$input;
this.afterSubmitHandler = function (data) {
if (data.success){
var $fullComplete = $('.full-complete',this.$staticValue);
$input = $('#id_foundation');
currValue = $.trim($input.val());
$fullComplete.text(currValue);
this.refreshHtml();
}
};
this.refreshHtml = function () {
var $fullComplete = $('.full-complete',this.$staticValue),
$notComplete = $('.not-complete',this.$staticValue);
if($.trim($fullComplete.text()) == ''){
$fullComplete.addClass('hidden');
$notComplete.removeClass('hidden');
}else{
$fullComplete.removeClass('hidden');
$notComplete.addClass('hidden');
}
return false;
};
this.ajaxPath = path;
};
/**
* initialize and configure the whole module
*/
that.init = function(options) {
$.extend(this.lang, options.lang);
$.extend(this.opt, options);
this.forms = {};
$(function () {
//forms init
$('.ajax-form').each(function () {
var formName = $(this).attr('id'),
path = $(this).attr('action'),
inputData,
$wrapper = $(this).closest('.'+self.opt.formWrapperClass),
$staticValue = $('.'+self.opt.staticValueClass, $wrapper),
$description = $('.'+self.opt.descriptionClass, $wrapper),
$editable = $('.'+self.opt.editableClass, $wrapper),
$closeButton = $('.'+self.opt.closeButtonClass, $wrapper),
//make and initialize form objects
/**
* It is where is magic happen
* Forms.factory(formName,path) factory method call
*/
self.forms[formName] = Forms.factory(formName,path);
/*
* form object properties assignation
*/
self.forms[formName].$form = $(this);
self.forms[formName].$wrapper = $wrapper;
self.forms[formName].$staticValue = $staticValue;
self.forms[formName].$description = $description;
self.forms[formName].$editable = $editable;
// submit events handler
$(this).off('submit');
$(this).on('submit', function () {
inputData = $(this).serialize();
self.forms[formName].beforeSubmit(inputData, formName);
});
$closeButton.on('click', function() {
$editable.removeClass(self.opt.formCurrentClass);
self.forms[formName].refreshHtml();
return false;
});
});
});
};
return that;
}());
}