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'](); } };