/* * Form validators. They'll find, render and focus error/s and * prevent form submission. */ /* * Calls specified validator along with the arguments on form submition. */ $.fn.onSubmitValidator = function(validatorCb) { var params = Array.prototype.slice.call(arguments, 1); var $form = $(this); if ($form.length) { $form.submit(function (ev) { $form.clearFormErrors(); params.unshift(ev); validatorCb.apply(this, params); }); } }; var TextLimitEnum = Object.freeze({ OPTIONAL: 0, REQUIRED: 1, NAME_MIN_LENGTH: '<%= NAME_MIN_LENGTH %>', NAME_MAX_LENGTH: '<%= NAME_MAX_LENGTH %>', TEXT_MAX_LENGTH: '<%= TEXT_MAX_LENGTH %>' }); /* * @param {boolean} clearErr Set clearErr to true if this is the only * error that can happen/show. */ function textValidator(ev, textInput, textLimitEnumMin, textLimitEnumMax, clearErr) { clearErr = _.isUndefined(clearErr) ? false : clearErr; var text = $(textInput).val().trim(); $(textInput).val(text); var nameTooShort = text.length < textLimitEnumMin; var nameTooLong = text.length > textLimitEnumMax; var errMsg; if (nameTooShort) { if (textLimitEnumMin === TextLimitEnum.REQUIRED) { errMsg = I18n.t("general.text.not_blank"); } else { errMsg = I18n.t("general.text.length_too_short", { min_length: textLimitEnumMin }); } } else if (nameTooLong) { errMsg = I18n.t("general.text.length_too_long", { max_length: textLimitEnumMax }); } var noErrors = _.isUndefined(errMsg); if (!noErrors) { renderFormError(ev, textInput, errMsg, clearErr); } return noErrors; } function checklistsValidator(ev, checklists, editMode) { var noErrors = true; // For every visible (i.e. not removed) checklist $(checklists).each(function() { var $checklist = $(this); if ($checklist.css('display') != 'none') { // For every visible (i.e. not removed) ckecklist item anyChecklistItemFilled = false; $(" .checklist-item-text", $checklist).each(function() { var $itemInput = $(this); var $item = $itemInput.closest("fieldset"); if ($item.css('display') != 'none') { if ($itemInput.val()) { var itemNameValid = textValidator(ev, $itemInput, TextLimitEnum.REQUIRED, TextLimitEnum.TEXT_MAX_LENGTH); if (!itemNameValid) { noErrors = false; } anyChecklistItemFilled = true; } else { // Remove empty checklist item input $item.remove(); } } }) var $checklistInput = $checklist.find(".checklist_name"); // In edit mode, checklist's name can't be blank if any items present var allowBlankChklstName = !(anyChecklistItemFilled || editMode); var textLimitEnumMin = allowBlankChklstName ? TextLimitEnum.OPTIONAL : TextLimitEnum.REQUIRED; var checklistNameValid = textValidator(ev, $checklistInput, textLimitEnumMin, TextLimitEnum.TEXT_MAX_LENGTH); if (!checklistNameValid) { noErrors = false; } else if (allowBlankChklstName) { // Hide empty checklist (remove would break server-side logic) $checklist.hide(); } } }); return noErrors; } var FileTypeSizeEnum = Object.freeze({ FILE: '<%= FILE_MAX_SIZE.megabytes %>', AVATAR: '<%= AVATAR_MAX_SIZE.megabytes %>' }); function filesValidator(ev, fileInputs, fileTypeEnum, canBeEmpty) { canBeEmpty = (typeof canBeEmpty !== 'undefined') ? canBeEmpty : false; var filesValid = true; if (fileInputs.length) { var filesPresentValid = canBeEmpty || filesPresentValidator(ev, fileInputs); var filesSizeValid = filesSizeValidator(ev, fileInputs, fileTypeEnum); // File spoof check is done on server-side only filesValid = filesPresentValid && filesSizeValid; } return filesValid; } function filesPresentValidator(ev, fileInputs) { var filesPresentValid = true; _.each(fileInputs, function(fileInput) { if (!fileInput.files[0]) { assetError = I18n.t("general.file.blank"); renderFormError(ev, fileInput, assetError, false, "data-error='file-missing'"); filesPresentValid = false; } }); return filesPresentValid; } function filesSizeValidator(ev, fileInputs, fileTypeEnum) { function getFileTooBigError(file) { if (!file) { return ; } if (file.size > fileTypeEnum) { switch (fileTypeEnum) { case FileTypeSizeEnum.FILE: return "<%= I18n.t 'general.file.size_exceeded', file_size: FILE_MAX_SIZE %>".strToErrorFormat(); case FileTypeSizeEnum.AVATAR: return "<%= I18n.t 'general.file.size_exceeded', file_size: AVATAR_MAX_SIZE %>".strToErrorFormat(); } } }; // Check if any file exceeds allowed size limit var filesSizeValid = true; _.each(fileInputs, function(fileInput) { var file = fileInput.files[0]; var assetError = getFileTooBigError(file); if (assetError) { renderFormError(ev, fileInput, assetError, false, "data-error='file-size'"); filesSizeValid = false; } }); if(filesSizeValid) { // Check if there is enough free space for the files filesSizeValid = enoughSpaceValidator(ev, fileInputs); } return filesSizeValid; } /* * Overriden in billing module for checking whether enough * organization space is free. */ function enoughSpaceValidator(ev, fileInputs) { return true; }