var Qs_Form = {
message: new qs.Message({
'en': {
'invalidInformationEntered': 'Please review the comments marked in red and make appropriate corrections.',
'alertInvalidInformationEntered': 'Please make the following corrections:',
'alertFromErrors': '',
'pleaseCorrectTheseFields': ''
},
'es': {
'invalidInformationEntered': 'Por favor, revise los comentarios marcados en rojo y hacer las correcciones apropiadas.',
'alertInvalidInformationEntered': 'Por favor, haga las siguientes correcciones:',
'alertFromErrors': '',
'pleaseCorrectTheseFields': ''
}
}),
options: {
elementsErrorsDisplayMethod: 'HTML',
formErrorsDisplayMethod: 'HTML',
formErrorsPlacement: 'prepend',
errorAlertEnabled: true
},
formOptions: {},
init: function (idForm, options)
{
var form = document.getElementById(idForm);
if (!form) {
alert('Form (id = ' + idForm + ') is not available');
return false;
}
if (!form.tagName || form.tagName != 'FORM') {
alert('Element (id = ' + idForm + ') is not a form - tagName = ' + form.tagName);
return false;
}
if (options) {
Qs_Form.formOptions[idForm] = options;
}
if (true == Qs_Form.getFormOption(idForm, 'errorAlertEnabled')
&& true == Qs_Form.getFormOption(idForm, 'isErrors')
) {
Qs_Form.displayErrorsAlert();
Qs_Form.setErrorFocus(form);
}
$(form).unbind('submit.form-plugin').bind('submit.form-plugin', Qs_Form.onSubmit);
$(':submit,input:image', form).unbind('click.form-plugin').bind('click.form-plugin', Qs_Form.buttonOnClick);
},
buttonOnClick: function (e)
{
var form = this.form;
form.clk = this;
if (this.type == 'image') {
if (e.offsetX != undefined) {
form.clk_x = e.offsetX;
form.clk_y = e.offsetY;
} else if (typeof $.fn.offset == 'function') { /* try to use dimensions plugin */
var offset = $(this).offset();
form.clk_x = e.pageX - offset.left;
form.clk_y = e.pageY - offset.top;
} else {
form.clk_x = e.pageX - this.offsetLeft;
form.clk_y = e.pageY - this.offsetTop;
}
}
$('input.hidden-btn-value', form).remove();
$(e.target).after($('').attr('name', e.target.name).val(e.target.value));
setTimeout(function() {
form.clk = form.clk_x = form.clk_y = null;
}, 10);
},
getOption: function (name)
{
return Qs_Form.options[name];
},
setElementsErrorsDisplayMethod: function (idForm, value)
{
Qs_Form.setFormOption(idForm, 'elementsErrorsDisplayMethod', value);
},
getElementsErrorsDisplayMethod: function (idForm)
{
return Qs_Form.getFormOption(idForm, 'elementsErrorsDisplayMethod');
},
setFormErrorsDisplayMethod: function (idForm, value)
{
Qs_Form.setFormOption(idForm, 'formErrorsDisplayMethod', value);
},
getFormErrorsDisplayMethod: function (idForm)
{
return Qs_Form.getFormOption(idForm, 'formErrorsDisplayMethod');
},
setFormErrorsPlacement: function (idForm, value)
{
Qs_Form.setFormOption(idForm, 'formErrorsPlacement', value);
},
getFormErrorsPlacement: function (idForm)
{
return Qs_Form.getFormOption(idForm, 'formErrorsPlacement');
},
setFormOption: function (idForm, name, value)
{
if (typeof Qs_Form.formOptions[idForm] == 'undefined') {
Qs_Form.formOptions[idForm] = {};
}
Qs_Form.formOptions[idForm][name] = value;
},
getFormOption: function (idForm, name)
{
if (typeof Qs_Form.formOptions[idForm] == 'undefined' || typeof Qs_Form.formOptions[idForm][name] == 'undefined' ) {
return Qs_Form.getOption(name);
}
return Qs_Form.formOptions[idForm][name];
},
onSubmitSuccess: function (response, form)
{
if (response.sessionExpired) {
if (response.loginUrl) {
qs.openPopupByLocation(response.loginUrl, 'qsPopup', 900, 400);
}
return true;
}
var $form = $(form);
var id = $form.attr('id');
if (!_.isArray(response.formErrors)) {
response.formErrors = [];
}
if (!_.isArray(response.elementsErrors)) {
response.elementsErrors = [];
}
Qs_Form.setFormOption(id, 'response', response);
$form.trigger({
type: 'qsFormSubmitSuccess',
response: response
});
//Qs_Form.setFormOption(id, 'requiredFiles', response.requiredFiles); -- reverted rev 4201 (task 21122)
if (response.isLocked) {
alert(response.error);
} else if (response.isValid && Qs_Form.isValidFiles(id)) {
if (form) {
var onSuccessCallback = Qs_Form.getFormOption($(form).attr('id'), 'onSuccessCallback');
if (typeof onSuccessCallback == 'undefined') {
form.submit();
} else {
qs.call(onSuccessCallback);
}
}
} else {
var onErrorCallback = Qs_Form.getFormOption($(form).attr('id'), 'onErrorCallback');
if (typeof onErrorCallback != 'undefined') {
qs.call(onErrorCallback);
return true;
}
Qs_Form.displayErrors(id);
}
return response;
},
displayErrors: function (id)
{
var response = Qs_Form.getFormOption(id, 'response');
if (!response.formErrors.length || response.elementsErrors.length) {
response = Qs_Form.validateFiles(id, response);
}
var displayErrorsAlert = false;
var form = document.getElementById(id);
var elementsDisplayMethod = Qs_Form.getElementsErrorsDisplayMethod(id);
var name, message, focusKey;
if (response.formErrors.length) {
var formDisplayMethod = Qs_Form.getFormErrorsDisplayMethod(id);
switch (formDisplayMethod) {
case 'ALERT':
Qs_Form.displayFromErrorsAlert(form, response.formErrors);
break;
case 'HTML':
Qs_Form.displayFromErrorsHtml(form, response.formErrors);
displayErrorsAlert = true;
break;
default:
alert('Qs_Form. Unknown formErrorsDisplayMethod "' + formDisplayMethod + '"');
}
}
if (response.elementsErrors.length) {
switch (elementsDisplayMethod) {
case 'ALERT':
message = Qs_Form.message.get('alertInvalidInformationEntered') + "\n";
message += Qs_Form.prepareErrorsAlert(response.elementsErrors);
message += '\n\n' + Qs_Form.message.get('pleaseCorrectTheseFields');
alert(message);
break;
case 'HTML':
Qs_Form.displayErrorsHtml(form, response.elementsErrors);
displayErrorsAlert = true;
break;
default:
alert('Qs_Form. Unknown elementsErrorsDisplayMethod "' + elementsDisplayMethod + '"');
}
}
if (displayErrorsAlert) {
Qs_Form.displayErrorsAlert();
Qs_Form.setErrorFocus(form);
}
if (response.elementsErrors.length) {
for (var i in response.elementsErrors) {
if (response.elementsErrors[i].type == 'captcha') {
var captchaElement = $('#' + response.elementsErrors[i].id + '-element');
if ($(captchaElement).size() != 0) {
var captchaData = response.elementsErrors[i].captcha;
var captchaId = response.elementsErrors[i].id;
$('img:first', captchaElement).attr('src', captchaData.src);
$('#' + captchaId + '-hidden', captchaElement).attr('value', captchaData.id);
$('#' + captchaId + '-input', captchaElement).attr('value', '');
$('#' + captchaId + '-input', captchaElement).blur();
if (typeof captchaData.href != 'undefined') {
$('a.captcha_refresh', captchaElement).attr('href', captchaData.href);
}
}
}
}
}
if (response.elementsErrors.length) {
$(form).trigger({
type: 'qsFormAfterSubmitSuccess',
response: response
});
}
},
setErrorFocus: function (form)
{
var id = $(form).attr('id');
var response = Qs_Form.getFormOption(id, 'response');
var focusKey = null;
var scrollToKey = null;
if (response.formErrors.length) {
scrollToKey = id;
} else if (response.elementsErrors.length) {
var element = response.elementsErrors[0];
if (0 == $('#' + element.id, form).size()) {
// check if it is radio button
var radio = $('#' + element.id + '-element input[id^=' + element.id + '][type=radio]', form).first();
if ($(radio).size()) {
scrollToKey = element.id + '-label';
}
} else {
if ($('#' + element.id, form).prop('focus')) {
focusKey = element.id;
scrollToKey = element.id + '-label';
}
}
}
if (focusKey && $('#' + focusKey + ':visible', form).size()) {
$('#' + focusKey, form).focus();
}
if (scrollToKey && $('#' + scrollToKey + ':visible').size()) {
$.scrollTo('#' + scrollToKey);
}
},
displayFromErrorsAlert: function (form, errors)
{
var message = Qs_Form.message.get('alertFromErrors') + "\n";
for (var i in errors) {
message += ' - ' + errors[i] + '\n';
}
alert(message);
},
displayFromErrorsHtml: function (form, errors)
{
var html = '';
for (var i in errors) {
html += '
' + errors[i] + '';
}
if (html != '') {
html = '';
var formId = $(form).attr('id');
if ('prepend' == Qs_Form.getFormOption(formId, 'formErrorsPlacement')) {
$('#' + formId).prepend(html);
} else {
$('#' + formId).append(html);
}
}
},
getFirstName: function (errors, subitem)
{
var name = _.keys(errors)[0];
var result = name;
if (typeof subitem != 'undefined' && subitem == true) {
result = '[' + result + ']';
}
if (typeof errors[name] == 'object') {
result += Qs_Form.getFirstName(errors[name], true);
}
if (typeof subitem == 'undefined') {
var pos = result.lastIndexOf('[');
if (pos > 0) {
result = result.substring(0, pos);
}
}
return result;
},
displayErrorsAlert: function ()
{
var message = Qs_Form.message.get('invalidInformationEntered') + '\n' + Qs_Form.message.get('pleaseCorrectTheseFields');
alert(_.str.trim(message));
},
prepareErrorsAlert: function (elementsErrors)
{
var messages = '';
for (var elementIndex in elementsErrors) {
var message = '';
for (var errorIndex in elementsErrors[elementIndex].errors) {
message += '\n - ' + elementsErrors[elementIndex].errors[errorIndex];
}
if (message != '') {
messages += '\n' + elementsErrors[elementIndex].label + ':' + message;
}
}
return messages;
},
displayErrorsHtml: function (form, elementsErrors)
{
for (var elementIndex in elementsErrors) {
var html = '';
for (var errorIndex in elementsErrors[elementIndex].errors) {
html += '' + elementsErrors[elementIndex].errors[errorIndex] + '';
}
if (html != '') {
var element = elementsErrors[elementIndex];
var ulId = element.id + '-errors';
html = '';
$('#' + element.id).attr('aria-describedby', ulId);
var idForm = $(form).attr('id');
$('#' + elementsErrors[elementIndex].id + '-element').append(html);
}
}
},
isValidFiles: function(idForm)
{
var isValid = true;
var files = Qs_Form.getFormOption(idForm, 'requiredFiles');
if (_.isArray(files)) {
var form = $('form#' + idForm);
for (var i in files) {
if ('' == _.str.trim($('input[type=file][name=' + files[i]['name'] + ']', form).val())) {
isValid = false;
break;
}
}
}
return isValid;
},
validateFiles: function (idForm, response)
{
var files = Qs_Form.getFormOption(idForm, 'requiredFiles');
if (_.isArray(files)) {
var form = $('form#' + idForm);
if (typeof response.errors == 'undefined') {
response.errors = {};
}
if (typeof response.elements == 'undefined') {
response.elements = {};
}
for (var i in files) {
var fileObj = $('input[type=file][name=' + files[i]['name'] + ']', form);
if ('' == _.str.trim($(fileObj).val())) {
var error = {
'type' : 'file',
'id' : $(fileObj).attr('id'),
'label' : files[i]['label'],
'errors' : {'isEmpty': 'This is a required field'}
};
response.isValid = false;
response.elementsErrors.push(error);
}
}
}
return response;
},
onSubmitError: function (request, textStatus, errorThrown)
{
alert(textStatus + ' ' + errorThrown);
},
onSubmitComplete: function (XMLHttpRequest, textStatus, form)
{
var idForm = $(form).attr('id');
Qs_Form.formOptions[idForm]['processRequest'] = false;
var onAfterSubmit = Qs_Form.getFormOption(idForm, 'onAfterSubmit');
if (typeof onAfterSubmit != 'undefined') {
qs.call(onAfterSubmit);
}
},
removeElementsErrors: function (form)
{
$('ul.errors', form).remove();
},
editorsTriggerSave: function (form)
{
if (typeof tinyMCE != 'undefined') {
tinyMCE.triggerSave();
}
var name;
if (typeof CKEDITOR != 'undefined') {
for (var i = 0; i < form.elements.length; i++) {
name = form.elements[i].name;
if (form.elements[i].tagName == 'TEXTAREA') {
if (name && 'undefined' === typeof CKEDITOR.instances[name]) {
name = name.replace(/\[/g, '-').replace(/\]/g, '');
}
if (typeof CKEDITOR.instances[name] != 'undefined') {
if (CKEDITOR.instances[name].checkDirty()) {
CKEDITOR.instances[name].updateElement();
}
}
}
}
}
},
releaseAutocompleteElements: function ()
{
if (typeof Qs_AutocompleteElement != 'undefined') {
var instances = Qs_AutocompleteElement.getInstances();
for (var i in instances) {
instance = instances[i];
instance.onChange(null, null);
}
}
},
onSubmit: function (spec)
{
var form;
if (this.tagName == 'FORM') {
form = this;
} else {
form = spec;
}
var idForm = $(form).attr('id');
var onBeforeSubmit = Qs_Form.getFormOption(idForm, 'onBeforeSubmit');
if (typeof onBeforeSubmit != 'undefined') {
qs.call(onBeforeSubmit);
}
Qs_Form.editorsTriggerSave(form);
Qs_Form.releaseAutocompleteElements();
Qs_Form.removeElementsErrors(form);
if (typeof Qs_Form.formOptions[idForm]['processRequest'] == 'undefined'
|| Qs_Form.formOptions[idForm]['processRequest'] != true
) {
Qs_Form.formOptions[idForm]['processRequest'] = true;
var deferred = qs.ajax($(form).attr('action'), Qs_Form.toObject(form), {
type: String($(form).attr('method')).toUpperCase(),
qsShowLoading: false,
qsDefaultCallbacks: false
});
deferred.done(function (data) {
Qs_Form.onSubmitSuccess(data, form);
});
deferred.fail(function (request, textStatus, errorThrown) {
Qs_Form.onSubmitError(request, textStatus, errorThrown);
});
deferred.always(function (XMLHttpRequest, textStatus) {
Qs_Form.onSubmitComplete(XMLHttpRequest, textStatus, form);
});
}
return false;
},
getNormalizedName: function (name)
{
if (name.substring(name.length - 2) == '[]') {
name = name.substr(0, name.length - 2);
}
return name;
},
setValue: function(/*Object*/obj, /*String*/name, /*String*/value)
{
var index = Qs_Form.getNormalizedName(name);
var isMultiple = (name.substr(name.length - 2) == '[]');
if (typeof obj[index] == 'undefined') {
if (isMultiple) {
obj[index] = [];
} else {
obj[index] = '';
}
}
if (_.isArray(obj[index])) {
obj[index].push(value);
} else {
obj[index] = value;
}
},
toObject: function (/*DOMNode||String*/ formNode)
{
var ret = {};
var exclude = 'file|submit|image|reset|button|';
if (_.isString(formNode)) {
formNode = document.getElementById(formNode);
}
for (var i = 0; i < formNode.elements.length; i++) {
var item = formNode.elements[i];
if (!item) {
continue;
}
var _in = item.name;
var type = (item.type || "").toLowerCase();
if (_in && type && exclude.indexOf(type) == -1 && !item.disabled) {
if (type == "radio" || type == 'checkbox') {
if (item.checked) {
Qs_Form.setValue(ret, _in, item.value);
}
} else if (item.multiple) {
ret[Qs_Form.getNormalizedName(_in)] = [];
var nodes = [item.firstChild];
while (nodes.length) {
for (var node = nodes.pop(); node; node = node.nextSibling) {
if (node.nodeType == 1 && node.tagName.toLowerCase() == "option") {
if (node.selected ) {
Qs_Form.setValue(ret, _in, node.value);
}
} else {
if (node.nextSibling) {
nodes.push(node.nextSibling);
}
if (node.firstChild) {
nodes.push(node.firstChild);
}
break;
}
}
}
} else {
Qs_Form.setValue(ret, _in, item.value);
if (type == 'image') {
ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
}
}
}
}
if (formNode.clk && !formNode.clk.disabled && formNode.clk.name) {
if (formNode.clk.type == 'image') {
ret[formNode.clk.name + '.x'] = formNode.clk_x;
ret[formNode.clk.name + '.y'] = formNode.clk_y;
} else {
ret[formNode.clk.name] = formNode.clk.value;
}
}
return ret; // Object
},
updatePart: function(form, formPart, request, options) {
options = options || {};
options = $.extend({
url: qs.constant('BASE_URL') + '/' + qs.constant('CURRENT_PAGE'),
success: Qs_Form.updatePartOnSuccess
}, options);
request = request || {};
request = $.extend({}, Qs_Form.toObject(form), {action: 'renderFormPart'}, request);
request.formPart = formPart;
qs.ajax(options.url, request).success(options.success);
},
updatePartOnSuccess: function (response) {
var element = $('dd:first', response.html);
$('#' + element.attr('id')).html(element.html());
if (response.scripts) {
$.globalEval(response.scripts);
}
},
/**
* Returns element selector
* @param {String} formId
* @param {String} id
* @return {Array} '#{id}' | ['#{id}-{id}_{lang}']
*/
getElementSelectorList: function (formId, id) {
var options, languageList;
if ((options = Qs_Form.formOptions[formId])) {
if (options.prependId) {
id = formId + '-' + id;
}
if (options.translateExtension && (languageList = options.translateExtension.languageList)) {
id = '#' + id + '-' + id + '_';
return _.map(languageList, function (lang) {
return id + lang;
});
}
}
return ['#' + id];
},
/**
* Return selector for element with containers
* @param {String} formId
* @param {String} id
*/
getElementWrapSelector: function (formId, id) {
var selector = Qs_Form.getElementSelectorList(formId, id), list = [];
_.forEach(selector, function (part) {
list.push(part + '-label');
list.push(part + '-element');
});
return list.join(', ');
},
/**
* Show/Hide element with containers by id
* @param {String} formId
* @param {String} id
* @param {Boolean} state true|false
*/
toggleElement: function (formId, id, state) {
var selector = Qs_Form.getElementWrapSelector(formId, id);
return $(selector)[state ? 'show' : 'hide']();
}
};