4012 lines
117 KiB
JavaScript
4012 lines
117 KiB
JavaScript
/*
|
|
The following errors were found when attempting to minify this file:
|
|
- Line 37: Parse error. missing : after property id
|
|
- Line 37: Parse error. illegal character
|
|
- Line 37: Parse error. missing ; before statement
|
|
- Line 37: Parse error. illegal character
|
|
- Line 37: Parse error. syntax error
|
|
- Line 38: Parse error. syntax error
|
|
- Line 39: Parse error. syntax error
|
|
- Line 40: Parse error. syntax error
|
|
- Line 42: Parse error. syntax error
|
|
- Line 43: Parse error. illegal character
|
|
- Line 43: Parse error. missing ) after argument list
|
|
- Line 43: Parse error. illegal character
|
|
- Line 43: Parse error. syntax error
|
|
- Line 44: Parse error. syntax error
|
|
- Line 45: Parse error. syntax error
|
|
- Line 46: Parse error. syntax error
|
|
- Line 47: Parse error. syntax error
|
|
- Line 49: Parse error. syntax error
|
|
- Line 51: Parse error. missing ; before statement
|
|
- Line 59: Parse error. syntax error
|
|
- Line 61: Parse error. syntax error
|
|
- Line 66: Parse error. invalid return
|
|
- Line 67: Parse error. syntax error
|
|
- Line 69: Parse error. missing ; before statement
|
|
- Line 73: Parse error. syntax error
|
|
- Line 74: Parse error. syntax error
|
|
- Line 75: Parse error. syntax error
|
|
- Line 77: Parse error. syntax error
|
|
- Line 79: Parse error. missing ; before statement
|
|
- Line 85: Parse error. illegal character
|
|
- Line 85: Parse error. missing ; before statement
|
|
- Line 85: Parse error. illegal character
|
|
- Line 86: Parse error. syntax error
|
|
- Line 87: Parse error. syntax error
|
|
- Line 90: Parse error. syntax error
|
|
- Line 93: Parse error. illegal character
|
|
- Line 93: Parse error. missing ; before statement
|
|
- Line 93: Parse error. illegal character
|
|
- Line 97: Parse error. invalid return
|
|
- Line 98: Parse error. syntax error
|
|
- Line 100: Parse error. missing ; before statement
|
|
- Line 101: Parse error. syntax error
|
|
- Line 102: Parse error. syntax error
|
|
- Line 103: Parse error. syntax error
|
|
- Line 108: Parse error. invalid return
|
|
- Line 113: Parse error. missing ; after for-loop initializer
|
|
- Line 113: Parse error. missing ; before statement
|
|
- Line 120: Parse error. syntax error
|
|
- Line 127: Parse error. syntax error
|
|
- Line 129: Parse error. syntax error
|
|
- Line 131: Parse error. syntax error
|
|
- Line 132: Parse error. syntax error
|
|
- Line 133: Parse error. syntax error
|
|
- Line 423: Parse error. missing ; before statement
|
|
*/
|
|
// Gets Json object using a given url.
|
|
function GetJson(url) {
|
|
var result;
|
|
$.ajaxSetup({ async: false });
|
|
$.post(url, function (data) {
|
|
result = data;
|
|
});
|
|
$.ajaxSetup({ async: true });
|
|
return result;
|
|
}
|
|
|
|
function maxLength(field, maxChars) {
|
|
if (field.value.length >= maxChars) {
|
|
event.returnValue = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function maxLengthPaste(field, maxChars) {
|
|
var copyText = field.value + window.clipboardData.getData("Text");
|
|
field.value = copyText.substr(0, maxChars);
|
|
if ((copyText.length) > maxChars) {
|
|
return false;
|
|
}
|
|
event.returnValue = true;
|
|
}
|
|
|
|
function appendFilesToInput(appendInput, mainFileInput) {
|
|
const valid = validateMultiFileUpload(appendInput, true);
|
|
if (!valid) {
|
|
alert("The file you are trying to upload is not an allowed file type or has an invalid file name. These are the accepted characters: A-z 0-9 ~ ! ( ) - + = [ ] { } , . _");
|
|
appendInput.value = null;
|
|
return;
|
|
}
|
|
const dt = new DataTransfer();
|
|
const originalFiles = Array.from(mainFileInput.files);
|
|
const existingSet = new Set(originalFiles.map(({ name, size, lastModified }) => `${name}-${size}-${lastModified}`));
|
|
originalFiles.forEach(file => {
|
|
dt.items.add(file);
|
|
})
|
|
const addedFiles = Array.from(appendInput.files);
|
|
addedFiles.forEach(file => {
|
|
if (!existingSet.has(`${file.name}-${file.size}-${file.lastModified}`)) {
|
|
dt.items.add(file);
|
|
}
|
|
})
|
|
mainFileInput.files = dt.files;
|
|
mainFileInput.dispatchEvent(new Event("change"));
|
|
}
|
|
|
|
function fileAppender(mainFileInput) {
|
|
const li = document.createElement("li");
|
|
const label = document.createElement("label");
|
|
label.innerHTML = '<span class="visuallyhidden">Add Files</span><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" aria-hidden="true"><path d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z"/></svg>'
|
|
const appendInput = document.createElement("input");
|
|
appendInput.type = "file";
|
|
appendInput.multiple = true;
|
|
appendInput.className = "visuallyhidden";
|
|
appendInput.addEventListener("change", e => {
|
|
appendFilesToInput(appendInput, mainFileInput);
|
|
});
|
|
label.appendChild(appendInput);
|
|
const placeholder = document.createElement("span");
|
|
li.appendChild(placeholder);
|
|
li.appendChild(label);
|
|
return li;
|
|
}
|
|
|
|
function removeFileFromInput(input, idx) {
|
|
const dt = new DataTransfer();
|
|
const files = Array.from(input.files);
|
|
files.splice(idx, 1);
|
|
files.forEach(file => {
|
|
dt.items.add(file);
|
|
});
|
|
input.files = dt.files;
|
|
}
|
|
|
|
function listItemFile(input, file, idx) {
|
|
const li = document.createElement("li");
|
|
const fileNameSpan = document.createElement("span");
|
|
fileNameSpan.textContent = file.name;
|
|
li.appendChild(fileNameSpan);
|
|
const removeButton = document.createElement("button");
|
|
removeButton.title = `Remove ${file.name}`;
|
|
removeButton.addEventListener("click", e => {
|
|
e.preventDefault();
|
|
removeFileFromInput(input, idx);
|
|
input.dispatchEvent(new Event("change"));
|
|
});
|
|
removeButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" fill="darkred" aria-hidden="true"><path d="m336-280 144-144 144 144 56-56-144-144 144-144-56-56-144 144-144-144-56 56 144 144-144 144 56 56ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"></path></svg>';
|
|
const removeButtonSpan = document.createElement("span");
|
|
removeButtonSpan.textContent = `Remove ${file.name}`;
|
|
removeButtonSpan.className = "visuallyhidden";
|
|
removeButton.appendChild(removeButtonSpan);
|
|
li.appendChild(removeButton);
|
|
return li;
|
|
}
|
|
|
|
function listFileInputFiles(fileInput) {
|
|
if (fileInput.nextElementSibling?.className === "file-list") {
|
|
fileInput.nextElementSibling.remove();
|
|
}
|
|
const files = fileInput.files || [];
|
|
const valid = files.length && validateMultiFileUpload(fileInput, true)
|
|
if (!valid) {
|
|
fileInput.value = null;
|
|
return;
|
|
}
|
|
if (files.length > 1) {
|
|
const ul = document.createElement("ul");
|
|
ul.className = "file-list";
|
|
for (let i = 0; i < files.length; i++) {
|
|
const li = listItemFile(fileInput, files[i], i);
|
|
ul.appendChild(li);
|
|
}
|
|
const fileAppenderLi = fileAppender(fileInput);
|
|
ul.appendChild(fileAppenderLi);
|
|
fileInput.after(ul);
|
|
}
|
|
}
|
|
|
|
function initFileInputs() {
|
|
if (!window.FeatureToggles.isActive("CMS.FormCenter.MultipleFileUploadEnhancement")) {
|
|
return;
|
|
}
|
|
document.querySelectorAll(".FileUpload input[type='file']").forEach(fileInput => {
|
|
listFileInputFiles(fileInput);
|
|
fileInput.addEventListener("change", e => {
|
|
listFileInputFiles(fileInput)
|
|
})
|
|
});
|
|
}
|
|
;
|
|
/// <reference path="../../../../Scripts/jquery-1.3.2-vsdoc.js">
|
|
/// <reference path="../../../../Scripts/json2.js">
|
|
/// <reference path="../../../../Scripts/HtmlExtensionSupport.js">
|
|
/// <reference path="../../../../Scripts/UrlLibrary.js">
|
|
/// <reference path="../../../../Common/GlobalJSFunctionsDetail.js" />
|
|
/// <reference path="Conditions.js" />
|
|
/// <reference path="Validation.js" />
|
|
/// <reference path="/Assets/Scripts/DynamicForm/PrintSubmission.js" />
|
|
/// <reference path="../../../../Assets/Scripts/DateTimePicker/cp.datetimepicker.js" />
|
|
|
|
//////// ENUMERATIONS ///////////
|
|
var FormCenterHomeJS = (function ($) {
|
|
var self = this;
|
|
|
|
// This value is set on the ItemDetailFE.ascx page, using a value from the
|
|
// View Model.
|
|
self.submissionURL = '';
|
|
|
|
return self;
|
|
}(jQuery));
|
|
|
|
var FormCenterHomeScriptResources = GetJson("/FormCenter/Localization");
|
|
|
|
// Field formats.
|
|
var FieldValidation = {
|
|
Any: 0,
|
|
Letters: 1,
|
|
Numeric: 2,
|
|
PhoneNumber: 3,
|
|
PostalCode: 4,
|
|
EmailAddress: 5,
|
|
RegEx: 6,
|
|
Currency: 7,
|
|
Date: 8,
|
|
Time: 9,
|
|
DateTime: 10,
|
|
DateSpan: 11,
|
|
TimeSpan: 12,
|
|
DateTimeSpan: 13
|
|
};
|
|
|
|
// Supported field types.
|
|
var FieldTypes = {
|
|
ShortAnswer: 1,
|
|
LongAnswer: 2,
|
|
Checkboxes: 3,
|
|
RadioButtons: 4,
|
|
Dropdown: 5,
|
|
FileUpload: 6,
|
|
ReplyEmail: 10,
|
|
Password: 11,
|
|
DateTime: 18,
|
|
EPayment: 23
|
|
};
|
|
|
|
//////// GLOBALS ////////////////
|
|
|
|
// Stores instantiated form validator/condition instances for the current form.
|
|
var formValidators = null;
|
|
var formConditions = null;
|
|
|
|
// Use with form submissions.
|
|
var redirectNewWindow = null;
|
|
|
|
//////// SUPPORT METHODS ////////f
|
|
|
|
// Shows extra information for a form detail.
|
|
function moreInfo(id) {
|
|
changeInfo(id, 'addClass', 'removeClass');
|
|
}
|
|
|
|
// Hides extra information for a form detail.
|
|
function lessInfo(id) {
|
|
changeInfo(id, 'removeClass', 'addClass');
|
|
}
|
|
|
|
// Internal. Hides or shows extra information.
|
|
function changeInfo(id, lessFn, moreFn) {
|
|
$([document.getElementById('spnLess' + id), document.getElementById('lnkMore' + id)])[lessFn]('hidden');
|
|
$(document.getElementById('spnMore' + id))[moreFn]('hidden');
|
|
}
|
|
|
|
// Used to expand and collapse category sections.
|
|
function expandCollaspseCategory(catID) {
|
|
var $elem = $('#section' + catID);
|
|
var $elemArrow = $('#span' + catID);
|
|
var supportSlide = !isie7; // If we can find a better way to detect the incorrect behavior IE7 mode is exhibiting, go for it...
|
|
|
|
if ($elem.is(':visible')) {
|
|
$elemArrow.html('►');
|
|
|
|
if (supportSlide)
|
|
$elem.slideUp(150);
|
|
else
|
|
$elem.hide();
|
|
}
|
|
else {
|
|
$elemArrow.html('▼');
|
|
|
|
if (supportSlide)
|
|
$elem.slideDown(150);
|
|
else
|
|
$elem.show();
|
|
}
|
|
}
|
|
|
|
// Assigns bulk action checkbox group to jQuery expression.
|
|
function assignBulkCheckGroup($children, $parent) {
|
|
// Isolate children from parent in event of overlap ($children containing the $parent).
|
|
// Vastly simplifies the logic in the event handlers by doing this.
|
|
var $isolatedChildren = $children.filter(
|
|
function (index) {
|
|
return $parent.filter(this).length == 0;
|
|
}
|
|
);
|
|
|
|
// Cache current number of checked children.
|
|
$isolatedChildren.lengthChecked = $isolatedChildren.filter(':checked').length;
|
|
|
|
// Hook childen change.
|
|
$isolatedChildren.change(function (event) {
|
|
$isolatedChildren.lengthChecked += (this.checked ? 1 : -1);
|
|
|
|
var allChildrenChecked = ($isolatedChildren.lengthChecked == $isolatedChildren.length);
|
|
|
|
$parent.each(function () {
|
|
this.checked = allChildrenChecked;
|
|
});
|
|
});
|
|
|
|
// Hook parent change.
|
|
$parent.change(function (event) {
|
|
var parentChecked = this.checked;
|
|
|
|
$isolatedChildren.lengthChecked = this.checked ? $isolatedChildren.length : 0;
|
|
|
|
$isolatedChildren.each(function () {
|
|
this.checked = parentChecked;
|
|
});
|
|
});
|
|
}
|
|
|
|
function initCommon() {
|
|
// Hack: Internet Explorer 7 mode bizarre display bugs.
|
|
$('.sidebar .search.noStyles').css('zoom', '1');
|
|
|
|
// Hook search category bulk checks.
|
|
var $bulkCheck = $('#categoryFilter_0');
|
|
var $bulkGroup = $('.categoryList input[type="checkbox"]');
|
|
|
|
assignBulkCheckGroup($bulkGroup, $bulkCheck);
|
|
|
|
// Get input jQuery refs.
|
|
var $inputFCTerm = $('#inputFCTerm');
|
|
var $inputFCSearch = $('#inputFCSearch');
|
|
|
|
// Hook search button and textbox to capture enter key.
|
|
$inputFCTerm.keydown(function (event) {
|
|
// If user presses enter, submit for search.
|
|
switch (event.which) {
|
|
case 10: // LF
|
|
case 13: // CR
|
|
event.preventDefault();
|
|
$inputFCSearch.click();
|
|
break;
|
|
}
|
|
});
|
|
|
|
$inputFCSearch.click(function (event) {
|
|
event.preventDefault();
|
|
|
|
// Build search querystring.
|
|
var qs = {};
|
|
var formID = extractFormIDFromURL(location.href);
|
|
var categoryID = extractCategoryIDFromURL(location.href);
|
|
|
|
var searchTerm = $.trim(isNull($inputFCTerm.val(), ''));
|
|
|
|
if (formID)
|
|
qs.formID = formID;
|
|
|
|
if (categoryID)
|
|
qs.categoryID = categoryID;
|
|
|
|
if (searchTerm != '')
|
|
qs.term = searchTerm;
|
|
|
|
if (!$bulkCheck[0].checked) {
|
|
var values = [];
|
|
|
|
$bulkGroup.filter(':checked').each(function () {
|
|
values.push(this.value);
|
|
});
|
|
|
|
if (values.length > 0)
|
|
qs.categoryFilter = values.join(',');
|
|
}
|
|
|
|
// Set search URL and go.
|
|
window.location = '/FormCenter/Search' + (new QueryStringBuilder(qs)).toString();
|
|
});
|
|
|
|
// Hook search category dropdown.
|
|
var $catList = $('#categoryList');
|
|
var $catListToggle = $('a.mega');
|
|
|
|
$catListToggle.click(function (e) {
|
|
e.preventDefault();
|
|
|
|
if ($catList.hasClass('open'))
|
|
$catList.slideUp(300);
|
|
else
|
|
$catList.slideDown(300);
|
|
|
|
$catListToggle.toggleClass('active');
|
|
$catList.toggleClass('open');
|
|
});
|
|
|
|
// Show print dialog if URL contains standard print query string.
|
|
if (containsPrint(location.href))
|
|
window.print();
|
|
}
|
|
|
|
// Initialization for search (Search.aspx view).
|
|
function initSearch() {
|
|
if (this.wasInit)
|
|
return;
|
|
|
|
this.wasInit = true;
|
|
|
|
attachCategoryVisibilityTogglers();
|
|
|
|
initCommon();
|
|
}
|
|
|
|
// Initialization for category/form list (Index.aspx view).
|
|
function initCategoryList() {
|
|
if (this.wasInit)
|
|
return;
|
|
|
|
this.wasInit = true;
|
|
|
|
attachCategoryVisibilityTogglers();
|
|
|
|
initCommon();
|
|
}
|
|
|
|
// Initialization for confirmation (Confirmation.aspx view).
|
|
function initConfirmation() {
|
|
if (this.wasInit)
|
|
return;
|
|
|
|
this.wasInit = true;
|
|
|
|
initCommon();
|
|
}
|
|
|
|
function initPostSubmissionSpam() {
|
|
initCommon();
|
|
}
|
|
|
|
|
|
// Causes current form to be submitted for printing.
|
|
function printForm(saveData) {
|
|
if (formValidate()) { //check for valid responses before creating print window
|
|
var frm = document.aspnetForm;
|
|
var $form = $(document.aspnetForm);
|
|
var printPrevType = (getPrintPreviewType() == 1 ? 'Print' : 'Preview');
|
|
var formID = extractFormIDFromURL(location.href);
|
|
|
|
$form.attr('target', 'PrintWindow');
|
|
// Change target/action to print data.
|
|
frm.action = '/FormCenter/Print?formID=' + formID + '&' + printPrevType + '=YES&Save=' + (saveData ? 'True' : 'False');
|
|
|
|
var savedProgressID = $('#hdnSavedProgressID').val();
|
|
|
|
if (savedProgressID != null) {
|
|
frm.action = frm.action + '&savedProgressID=' + savedProgressID;
|
|
}
|
|
|
|
submitForm($form, true, saveData, formID);
|
|
} else {
|
|
enableDisableSubmit(true);
|
|
}
|
|
}
|
|
|
|
function submitFormHandler(e) {
|
|
try {
|
|
let json = JSON.parse(this.response);
|
|
|
|
if (this.status !== 200 || json.Success !== true) {
|
|
$('.submissionConfirmationMessage').html("Something went wrong with the submission. Please try again.");
|
|
$('.submissionConfirmation').show();
|
|
enableDisableSubmit(true);
|
|
return;
|
|
}
|
|
|
|
const responseUrl = this.responseURL && new URL(this.responseURL);
|
|
const saveSubmission = responseUrl && responseUrl.searchParams.get('save') && responseUrl.searchParams.get('save').toLowerCase() === 'true';
|
|
const doPrint = responseUrl && responseUrl.searchParams.get('print') && responseUrl.searchParams.get('print').toLowerCase() === 'true';
|
|
const redirectAfterSubmissionSaved = json.Redirect && json.Redirect === true && saveSubmission === true;
|
|
|
|
if (redirectAfterSubmissionSaved)
|
|
{
|
|
if (json.IsHttps === false) {
|
|
json.Message = json.Message.replace("https://", "http://");
|
|
}
|
|
|
|
location.href = json.Message;
|
|
}
|
|
else {
|
|
if (saveSubmission === true) {
|
|
$('.submissionConfirmationMessage').html(json.Message);
|
|
typeof displayStep === "function" && displayStep(1);
|
|
$('.submitForm').hide();
|
|
$('.submissionConfirmation').show();
|
|
}
|
|
|
|
enableDisableSubmit(true);
|
|
}
|
|
|
|
if (doPrint === true) {
|
|
window.open("/FormCenter/Print?formId=" + json.FormId.toString() + '&save=' + (saveSubmission ? 'True' : 'False'));
|
|
}
|
|
|
|
if (json.Success === true) {
|
|
document.aspnetForm.reset();
|
|
|
|
if (typeof (grecaptcha) !== "undefined")
|
|
{
|
|
grecaptcha.reset();
|
|
}
|
|
}
|
|
|
|
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
|
|
} catch (ex) {
|
|
console.log(ex);
|
|
}
|
|
}
|
|
|
|
function submitForm($form, print, saveSubmission, formID) {
|
|
var submittedViaWidget = $form.parents(".widgetBody").length > 0;
|
|
|
|
serializeSpecialFields();
|
|
|
|
if (submittedViaWidget !== true) {
|
|
var printWindow;
|
|
|
|
if (print === true)
|
|
{
|
|
printWindow = window.open("", "PrintWindow");
|
|
|
|
// Deferred object at the window level, this becomes available on the opened window via window.opener
|
|
// Whichever view gets rendered will resolve it and pass the appropriate status code.
|
|
window.deferredStatus = $.Deferred();
|
|
}
|
|
|
|
if (printWindow) {
|
|
window.deferredStatus.done(function (status) {
|
|
if (status === CP_DynamicForm_PrintSubmission.StatusCodes.Success) {
|
|
if (saveSubmission && saveSubmission === true) {
|
|
window.location = '/FormCenter/Confirmation?formID=' + formID;
|
|
}
|
|
} else {
|
|
printWindow.close();
|
|
|
|
if (saveSubmission) {
|
|
window.location = '/FormCenter/ErrorSubmittingForm?formID=' + formID;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
$form.submit();
|
|
}
|
|
else {
|
|
var submissionUrl = FormCenterHomeJS.submissionURL + (saveSubmission ? '&save=True' : "");
|
|
submissionUrl = submissionUrl + (print ? '&print=True' : '');
|
|
|
|
var formData = new FormData($form[0]);
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.onload = submitFormHandler;
|
|
xhr.onloadend = ajaxPostBackEnd;
|
|
xhr.onerror = function() { console.log("A network error occurred with the transaction."); };
|
|
xhr.open("POST", submissionUrl);
|
|
ajaxPostBackStart('Loading');
|
|
xhr.send(formData);
|
|
}
|
|
}
|
|
|
|
function serializeSpecialFields()
|
|
{
|
|
submitCheckboxHandler();
|
|
|
|
submitRadioHandler();
|
|
|
|
submitDateTimeHandler();
|
|
}
|
|
|
|
// Initialization for form item printing (Print.aspx view).
|
|
function initFormPrint() {
|
|
if (this.wasInit)
|
|
return;
|
|
|
|
this.wasInit = true;
|
|
|
|
initCommon();
|
|
|
|
initValidationAndConditions();
|
|
|
|
registerFormPrintEvents();
|
|
}
|
|
|
|
function initValidationAndConditions() {
|
|
// Register validation.
|
|
if (typeof getFormValidatorData !== 'undefined') {
|
|
formValidators = FieldValidator.createMulti(getFormValidatorData());
|
|
} else {
|
|
formValidators = [];
|
|
}
|
|
|
|
// Register conditions.
|
|
if (getFormConditionData) {
|
|
formConditions = FieldConditions.createMulti(getFormConditionData(), formValidators);
|
|
} else {
|
|
formConditions = FieldConditions.createMulti([], formValidators);
|
|
}
|
|
|
|
// Register condition runner and make initial condition check.
|
|
formConditionsRunner = new FieldConditionsRunner(formConditions, $.noop, true, false); // TODO: Finish up, put debugCondRunnerLogResults for $.noop.
|
|
formConditionsRunner.run();
|
|
}
|
|
|
|
// Initialization for form item (Item.aspx view).
|
|
function initForm() {
|
|
|
|
if (this.wasInit)
|
|
return;
|
|
|
|
this.wasInit = true;
|
|
|
|
initCommon();
|
|
initValidationAndConditions();
|
|
initDatePickers();
|
|
initTimePickers();
|
|
initFileInputs();
|
|
registerFormEvents(); // Hook up buttons (submit/cancel/etc).
|
|
}
|
|
|
|
function initDatePickers() {
|
|
if ($('.telerikDatePicker').length > 0) {
|
|
$('.telerikDatePicker').each(function () {
|
|
if (typeof (cp) !== 'undefined')
|
|
cp.datetimepicker && cp.datetimepicker.createDatePicker(this);
|
|
});
|
|
}
|
|
}
|
|
|
|
function initTimePickers() {
|
|
if ($('.formCenterTimePicker').length > 0) {
|
|
$('.formCenterTimePicker').focusout(function () {
|
|
var text = $(this).val().toLowerCase();
|
|
if (text != '' && (text.indexOf('am') < 0 && text.indexOf('pm') < 0)) {
|
|
text = $(this).val().trim() + ' AM';
|
|
$(this).val(text);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
$('.telerikTimePicker').each(function () {
|
|
if (typeof (cp) !== 'undefined')
|
|
cp.datetimepicker && cp.datetimepicker.createTimePicker(this,
|
|
{
|
|
format: 'h:i A'
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
// Registers event handlers for form.
|
|
function registerFormPrintEvents() {
|
|
$('#btnFormContinue').click(function (event) {
|
|
event.preventDefault();
|
|
|
|
var frm = document.aspnetForm;
|
|
var formID = extractFormIDFromURL(location.href);
|
|
var $form = $(document.aspnetForm);
|
|
|
|
// Change target/action to confirmation page.
|
|
frm.action = '/FormCenter/Confirmation?formID=' + formID;
|
|
|
|
$form.trigger("submit");
|
|
});
|
|
}
|
|
|
|
// Registers event handlers for form.
|
|
function registerFormEvents() {
|
|
// Remove troublemakers (prevent the jQuery submit handler from ever firing, and not needed for this screen anyways).
|
|
document.aspnetForm.removeAttribute('onsubmit');
|
|
document.aspnetForm.onsubmit = null;
|
|
|
|
var $form = $(document.aspnetForm);
|
|
|
|
// TODO: Plug this into other validation.
|
|
var wantCopyAddr, $wantCopyAddrLI;
|
|
var wantCopy = document.getElementById('wantCopy');
|
|
|
|
if (wantCopy) {
|
|
wantCopyAddr = document.getElementById('wantCopyAddress');
|
|
$wantCopyAddrLI = $(wantCopyAddr.parentNode.parentNode);
|
|
|
|
$(wantCopy).change(function (event) {
|
|
if (this.checked)
|
|
$wantCopyAddrLI.show();
|
|
else
|
|
$wantCopyAddrLI.hide();
|
|
});
|
|
}
|
|
|
|
/* #2378*/
|
|
$(document).keydown(function (event) {
|
|
if ((event.keyCode == 13) &&
|
|
(event.target.id != 'btnFormSubmit') &&
|
|
(event.target.tagName != 'TEXTAREA') &&
|
|
(event.target.getAttribute('data-enable-enter-keypress') != 'true')) {
|
|
event.preventDefault();
|
|
return false;
|
|
}
|
|
if (event.keyCode === 32 &&
|
|
event.target.tagName === 'A' &&
|
|
event.target.getAttribute('role') === 'button') {
|
|
$(event.target).trigger('click');
|
|
event.preventDefault();
|
|
return false;
|
|
}
|
|
});
|
|
|
|
$form.submit(function () {
|
|
// Run validation, stop data submission if necessary.
|
|
if (!formValidate()) {
|
|
enableDisableSubmit(true);
|
|
return false;
|
|
}
|
|
|
|
if (isNull(redirectNewWindow, '').trimEnd() != '')
|
|
window.open(redirectNewWindow);
|
|
|
|
// Field types requiring special serialization code (radio/check/file).
|
|
// The deserialization of dictionaries from forms in MVC 2 is somewhat sensitive.
|
|
serializeSpecialFields();
|
|
return true;
|
|
});
|
|
|
|
$('#btnFormSubmit').click(function (event) {
|
|
event.preventDefault();
|
|
if (formValidate()) {
|
|
processSubmit(handleSubmitClick);
|
|
}
|
|
});
|
|
|
|
$('#btnFormPrint').click(function (event) {
|
|
event.preventDefault();
|
|
printForm(false);
|
|
});
|
|
|
|
$('#btnFormSubmitPrint').click(function (event) {
|
|
event.preventDefault();
|
|
if (formValidate()) {
|
|
processSubmit(handleSubmitPrintClick);
|
|
}
|
|
});
|
|
|
|
$('#btnCalculateTotals').click(function (e) {
|
|
e.preventDefault();
|
|
|
|
submitCheckboxHandler();
|
|
submitRadioHandler();
|
|
|
|
if (formValidate()) {
|
|
var $form = $(document.aspnetForm);
|
|
|
|
$.ajax({
|
|
url: '/FormCenter/Home/CalculateTotal?formID=' + $('#hdnFormID').val(),
|
|
type: 'POST',
|
|
data: $(document.aspnetForm).serializeArray(),
|
|
success: function (response) {
|
|
openCpModal({
|
|
title: FormCenterHomeScriptResources.CalculateTotals,
|
|
className: 'modalCalculateTotal',
|
|
isFrontEnd: window.location.href.indexOf('/Admin/FormCenter') == -1,
|
|
htmlContent: response
|
|
});
|
|
},
|
|
error: function (xhr, textStatus, exception) {
|
|
alert('Error: ' + xhr.statusText + '\nStatus: ' + xhr.status);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$('#btnProceedToCheckOut').click(function (e) {
|
|
proceedToCheckOut(e);
|
|
});
|
|
|
|
if ($('.submissionConfirmationOk').length > 0)
|
|
{
|
|
$('.submissionConfirmationOk').unbind('click').click(function () {
|
|
$('.submitForm').show();
|
|
$('.submissionConfirmation').hide();
|
|
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
|
|
})
|
|
}
|
|
}
|
|
|
|
function onRecaptchaLoadCallback() {
|
|
window.gRecaptchaClientId = grecaptcha.render('inline-recaptcha', {
|
|
'sitekey': document.querySelector('#inline-recaptcha').dataset.sitekey,
|
|
'badge': 'inline',
|
|
'size': 'invisible'
|
|
});
|
|
}
|
|
|
|
function processSubmit(callback) {
|
|
const recaptcha = document.querySelector('.recaptcha');
|
|
if (!recaptcha) {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
if (!window.FeatureToggles.isActive("CMS.FormCenter.RecaptchaV3Enabled")) {
|
|
window.recaptchaCallback = callback;
|
|
grecaptcha.execute();
|
|
return;
|
|
}
|
|
|
|
grecaptcha.ready(function() {
|
|
grecaptcha.execute(window.gRecaptchaClientId, { action: 'submit' }).then(callback);
|
|
});
|
|
}
|
|
|
|
function enableDisableSubmit(enable) {
|
|
if (enable) {
|
|
if ($('#btnFormSubmitPrint').length > 0) {
|
|
$('#btnFormSubmitPrint').removeClass('inactive');
|
|
$('#btnFormSubmitPrint').click(function (event) {
|
|
handleSubmitPrintClick();
|
|
});
|
|
}
|
|
if ($('#btnFormSubmit').length > 0) {
|
|
$('#btnFormSubmit').removeClass('inactive');
|
|
$('#btnFormSubmit').click(function (event) {
|
|
event.preventDefault();
|
|
if (formValidate()) {
|
|
closeModalDialog('editItemBehavior');
|
|
processSubmit(handleSubmitClick);
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
if ($('#btnFormSubmitPrint').length > 0) {
|
|
$('#btnFormSubmitPrint').addClass("inactive");
|
|
$('#btnFormSubmitPrint').unbind();
|
|
}
|
|
if ($('#btnFormSubmit').length > 0) {
|
|
$('#btnFormSubmit').addClass("inactive");
|
|
$('#btnFormSubmit').unbind();
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleSubmitClick() {
|
|
enableDisableSubmit(false);
|
|
|
|
var frm = document.aspnetForm;
|
|
|
|
frm.action = FormCenterHomeJS.submissionURL;
|
|
|
|
var $form = $(frm);
|
|
|
|
var formID = extractFormIDFromURL(location.href);
|
|
|
|
submitForm($form, false, true, formID);
|
|
}
|
|
|
|
function handleSubmitPrintClick() {
|
|
enableDisableSubmit(false);
|
|
printForm(true);
|
|
}
|
|
|
|
function proceedToCheckOut(e) {
|
|
e.preventDefault();
|
|
|
|
serializeSpecialFields();
|
|
|
|
if (formValidate()) {
|
|
var savedProgressID = $('#hdnSavedProgressID').val();
|
|
|
|
var submitUrl = '/FormCenter/Home/ProceedToCheckOut?formID=' + $('#hdnFormID').val();
|
|
|
|
if (savedProgressID != null) {
|
|
submitUrl = submitUrl + '&savedProgressID=' + savedProgressID;
|
|
}
|
|
|
|
var $form = $(document.aspnetForm);
|
|
$form.attr('action', submitUrl);
|
|
$form.submit();
|
|
}
|
|
}
|
|
|
|
function getModalDialogObjects() {
|
|
return {
|
|
iframe: document.getElementById('liveEditDialog'),
|
|
windowElement: $('.modalContainerCP')[0],
|
|
behavior: $find('editItemBehavior'),
|
|
titleElement: $('.modalTitle')[0]
|
|
};
|
|
}
|
|
|
|
function getBooleanValue(value) {
|
|
switch (value.toLowerCase()) {
|
|
case "true": case "yes": case "1": return true;
|
|
case "false": case "no": case "0": case null: return false;
|
|
default: return Boolean(string);
|
|
}
|
|
}
|
|
|
|
// Validates current form.
|
|
function formValidate() {
|
|
var assignFocus = true;
|
|
var ERROR_MSG = FormCenterHomeScriptResources.InvalidEmailAddressFormat2;
|
|
var wantCopy = document.getElementById('wantCopy');
|
|
|
|
if (wantCopy) {
|
|
wantCopyAddr = document.getElementById('wantCopyAddress');
|
|
$wantCopyAddrLI = $(wantCopyAddr.parentNode.parentNode);
|
|
|
|
if ($wantCopyAddrLI.is(":visible") && wantCopyAddr.value != "") {
|
|
if (!emailValidate(wantCopyAddr.value)) {
|
|
errorShow(ERROR_MSG);
|
|
return false;
|
|
}
|
|
}
|
|
if (wantCopy.checked == false)//if the checkbox is not checked then empty the emailaddress textbox
|
|
document.getElementById('wantCopyAddress').value = "";
|
|
}
|
|
else {
|
|
//if the checkbox is not checked then empty the emailaddress textbox
|
|
var wantCopyAddress = document.getElementById('wantCopyAddress');
|
|
if (wantCopyAddress)
|
|
document.getElementById('wantCopyAddress').value = "";
|
|
}
|
|
|
|
if (typeof formValidators.keys !== 'undefined') {
|
|
var liCurrent = $('li.current');
|
|
var step = "1";
|
|
if (liCurrent.length > 0) {
|
|
step = liCurrent.attr('id').replace('liStep', '');
|
|
}
|
|
|
|
var wizardStep = $('#wizard' + step);
|
|
|
|
if (wizardStep.length > 0) {
|
|
wizardStep = wizardStep[0];
|
|
}
|
|
|
|
var checkForInappropriateWords = new Array();
|
|
|
|
for (var i = 0, len = formValidators.keys.length; i < len; i++) {
|
|
var key = formValidators.keys[i];
|
|
|
|
if (wizardStep == null || wizardStep.length == 0 || (wizardStep != null && wizardStep.contains(formValidators[key].elemContainer))) {
|
|
if (!formValidators[key].validate(assignFocus, checkForInappropriateWords))
|
|
assignFocus = false;
|
|
}
|
|
}
|
|
|
|
if (validateInappropriateWords(checkForInappropriateWords)) {
|
|
assignFocus = false;
|
|
}
|
|
}
|
|
|
|
return assignFocus;
|
|
}
|
|
|
|
function validateInappropriateWords(checkForInappropriateWords) {
|
|
var data = {};
|
|
var j = 0;
|
|
var inappropriateWordsFound = false;
|
|
|
|
for (j = 0; j < checkForInappropriateWords.length; j++) {
|
|
data[checkForInappropriateWords[j].id.toString()] = checkForInappropriateWords[j].elemInput.value.trim();
|
|
}
|
|
|
|
var results = HasInappropriateWordsMultiple(data);
|
|
|
|
for (j = 0; j < checkForInappropriateWords.length; j++) {
|
|
if (results[checkForInappropriateWords[j].id.toString()] == true) {
|
|
checkForInappropriateWords[j].handleInappropriateWords(inappropriateWordsFound == false);
|
|
|
|
inappropriateWordsFound = true;
|
|
}
|
|
}
|
|
|
|
return inappropriateWordsFound;
|
|
}
|
|
|
|
// Displays error message if email validation failed
|
|
function errorShow(message) {
|
|
var elemContainer = $('.anonEmail');
|
|
elemContainer.addClass('error');
|
|
|
|
if (elemContainer.find('.explanation').length == 0) {
|
|
var errorElemMsg = document.createElement('p');
|
|
errorElemMsg.className = 'explanation';
|
|
errorElemMsg.innerHTML = message;
|
|
elemContainer.append(errorElemMsg);
|
|
}
|
|
}
|
|
|
|
// Determines if URL contains print querystring.
|
|
function containsPrint(url) {
|
|
return url.search(/(&|\?)print\=yes(&.*|)$/i) > -1;
|
|
}
|
|
|
|
|
|
// Extracts CategoryID identifier from URL specified.
|
|
function extractCategoryIDFromURL(url) {
|
|
|
|
url = url.toLowerCase();
|
|
var indexOfForm = url.lastIndexOf("/formcenter/");
|
|
if (indexOfForm > -1) {
|
|
//extract the categoryurl
|
|
var formURL = url.substr(indexOfForm + 12);
|
|
|
|
|
|
//check whether u have formid appended
|
|
|
|
if (formURL.indexOf("/") > -1)
|
|
formURL = formURL.substr(0, formURL.indexOf("/"));
|
|
//check wheter the url has categoryName
|
|
var indexOfHypen = formURL.lastIndexOf("-");
|
|
var categoryID = 0;
|
|
if (indexOfHypen > -1)
|
|
categoryID = formURL.substr(indexOfHypen + 1);
|
|
else
|
|
categoryID = formURL;
|
|
return categoryID;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
|
|
// Extracts form identifier from URL specified.
|
|
function extractFormIDFromURL(url) {
|
|
return $('#hdnFormID').val();
|
|
|
|
//there is some query string appended if so remove those
|
|
if (url.indexOf("/?") > -1) {
|
|
url = url.substr(0, url.indexOf("/?"));
|
|
}
|
|
|
|
url = url.toLowerCase();
|
|
var indexOfForm = url.lastIndexOf("/formcenter/");
|
|
if (indexOfForm > -1) {
|
|
//extract the url
|
|
var formURL = url.substr(indexOfForm + 12);
|
|
|
|
if (formURL.indexOf("/") > -1) {
|
|
formURL = formURL.substr(formURL.indexOf("/") + 1);
|
|
//check wheter the url has categoryName
|
|
var indexOfHypen = formURL.lastIndexOf("-");
|
|
var formID = 0;
|
|
if (indexOfHypen > -1)
|
|
formID = formURL.substr(indexOfHypen + 1);
|
|
else if (formURL == "")
|
|
return null;
|
|
else
|
|
formID = formURL;
|
|
|
|
return formID;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
// Attaches expand/collapse handlers to section headers.
|
|
function attachCategoryVisibilityTogglers() {
|
|
$('#FormCenterContent .contentMain').click(function (event) {
|
|
var target = event.target;
|
|
|
|
if (/^lnkLess[0-9]*$/.test(target.id)) {
|
|
// Form details should shrink.
|
|
lessInfo(parseInt(target.id.substr(7), 10));
|
|
event.preventDefault();
|
|
}
|
|
else if (/^lnkMore[0-9]*$/.test(target.id)) {
|
|
// Form details should expand.
|
|
moreInfo(parseInt(target.id.substr(7), 10));
|
|
event.preventDefault();
|
|
}
|
|
else {
|
|
// If the arrow glyph was clicked, treat it as if the header was clicked.
|
|
if (target.nodeName == 'SPAN' && target.className == 'arrow')
|
|
target = target.parentNode;
|
|
|
|
// If the header was clicked.
|
|
if (target.nodeName == 'H2') {
|
|
var parent = target.parentNode;
|
|
|
|
// If parent identifier matches expected pattern, get category ID and expand/collapse it.
|
|
if (parent && /^cat[0-9]*$/.test(parent.id)) {
|
|
var categoryID = parseInt(parent.id.substr(3), 10);
|
|
|
|
expandCollaspseCategory(categoryID);
|
|
|
|
// Prevent default code from executing.
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Called by form submittal to handle radio buttons for serialization.
|
|
function submitRadioHandler() {
|
|
var names = [];
|
|
var values = {};
|
|
$checkBoxSelector = null;
|
|
$webCheckBox = $('div.formWrap ol.cpForm input[type=radio]');
|
|
$mobileCheckBox = $('.mobileGuts input[type=radio]');
|
|
|
|
if ($webCheckBox.length != 0 && $mobileCheckBox.length == 0)
|
|
$checkBoxSelector = $webCheckBox;
|
|
|
|
if ($webCheckBox.length == 0 && $mobileCheckBox.length != 0)
|
|
$checkBoxSelector = $mobileCheckBox;
|
|
if ($checkBoxSelector != null) {
|
|
// Get list of radio inputs and their values.
|
|
$checkBoxSelector.each(function () {
|
|
if (!names.contains(this.name)) {
|
|
names.push(this.name);
|
|
values[this.name] = '';
|
|
}
|
|
|
|
if (this.checked)
|
|
values[this.name] = this.value;
|
|
})
|
|
}
|
|
|
|
// Map collected data to hidden inputs submitted to server.
|
|
for (var i = 0, len = names.length; i < len; i++) {
|
|
var inputName = names[i];
|
|
var id = (inputName.match(/_/g) || []).length == 2 ? inputName.substring(inputName.indexOf('_') + 1) : inputName;
|
|
document.getElementById(id).value = values[inputName];
|
|
}
|
|
}
|
|
|
|
// Called by form submittal to handle checkboxes for serialization.
|
|
function submitCheckboxHandler() {
|
|
var names = [];
|
|
var values = {};
|
|
$checkBoxSelector = null;
|
|
$webCheckBox = $('div.formWrap ol.cpForm input[type=checkbox]');
|
|
$mobileCheckBox = $('.mobileGuts input[type=checkbox]');
|
|
|
|
if ($webCheckBox.length != 0 && $mobileCheckBox.length == 0)
|
|
$checkBoxSelector = $webCheckBox;
|
|
|
|
if ($webCheckBox.length == 0 && $mobileCheckBox.length != 0)
|
|
$checkBoxSelector = $mobileCheckBox;
|
|
|
|
// Get list of checkbox inputs and their values.
|
|
if ($checkBoxSelector != null) {
|
|
$checkBoxSelector.each(function () {
|
|
if (!names.contains(this.name)) {
|
|
names.push(this.name);
|
|
values[this.name] = [];
|
|
}
|
|
|
|
if (this.checked) {
|
|
var val = this.value.replace(/\,/g, '_comma_');
|
|
if (val.trim() == '')
|
|
val = '_empty_value_';
|
|
values[this.name].push(val);
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
// Map collected data to hidden inputs submitted to server.
|
|
for (var i = 0, len = names.length; i < len; i++)
|
|
document.getElementById(names[i]).value = values[names[i]].join(',');
|
|
}
|
|
|
|
function submitDateTimeHandler() {
|
|
var names = [];
|
|
var values = [];
|
|
|
|
var $datePickers, $timePickers;
|
|
if ($('.formCenterDatePicker').length > 0) {
|
|
$datePickers = $('.formCenterDatePicker');
|
|
$timePickers = $('.formCenterTimePicker');
|
|
}
|
|
else {
|
|
$datePickers = $('.telerikDatePicker');
|
|
$timePickers = $('.telerikTimePicker');
|
|
}
|
|
|
|
$datePickers.each(function () {
|
|
if (!names.contains(this.name)) {
|
|
names.push(this.name);
|
|
values[this.name] = [this.value];
|
|
}
|
|
else {
|
|
values[this.name].push(this.value);
|
|
}
|
|
});
|
|
|
|
$timePickers.each(function () {
|
|
if (!names.contains(this.name)) {
|
|
names.push(this.name);
|
|
values[this.name] = ['', '', this.value];
|
|
}
|
|
else {
|
|
if (values[this.name].length == 1) {
|
|
values[this.name].push('');
|
|
}
|
|
values[this.name].push(this.value);
|
|
}
|
|
});
|
|
|
|
for (var i = 0, len = names.length; i < len; i++)
|
|
document.getElementById(names[i]).value = values[names[i]].join();
|
|
}
|
|
|
|
$(function () {
|
|
$('#aspnetForm,form[name=aspnetForm]').attr('enctype', "multipart/form-data");
|
|
$('#aspnetForm,form[name=aspnetForm]').addClass('submitForm');
|
|
});
|
|
;
|
|
|
|
/// <reference path="../../../../Scripts/jquery-1.3.2-vsdoc.js" />
|
|
/// <reference path="../../../../Scripts/json2.js" />
|
|
/// <reference path="../../../../Scripts/HtmlExtensionSupport.js" />
|
|
/// <reference path="../../../../Common/GlobalJSFunctionsDetail.js" />
|
|
/// <reference path="../../../../Assets/Scripts/InappropriateWords.js" />
|
|
/// <reference path="Home.js" />
|
|
|
|
// Overridden on a per-form basis. Retrieves validator information for submission validation.
|
|
//function getFormValidatorData() {
|
|
// return [];
|
|
//}
|
|
|
|
var FormCenterHomeScriptResources = GetJson("/FormCenter/Localization");
|
|
var originalTextColorRadio;
|
|
var originalTextColorCheckBox;
|
|
|
|
$.getScript("/Assets/Scripts/InappropriateWords.js");
|
|
|
|
// Used to properly localize strings.
|
|
String.prototype.format = function () {
|
|
var args = arguments;
|
|
return this.replace(/{(\d+)}/g, function (match, number) {
|
|
return typeof args[number] != 'undefined'
|
|
? args[number]
|
|
: match
|
|
;
|
|
});
|
|
};
|
|
|
|
|
|
// Performs validation for a form field.
|
|
function FieldValidator(elemInput, id, fieldType, isInternal, isRequired, formatValidation, formatValidationCustom, minAnswer, maxAnswer, maxLength) {
|
|
var self = this;
|
|
this.elemInputIsArray = $.isArray(elemInput);
|
|
|
|
if (this.elemInputIsArray) {
|
|
for (var i = 0, len = elemInput.length; i < len; i++) {
|
|
if (typeof (elemInput[i]) == "string")
|
|
elemInput[i] = document.getElementById(elemInput[i]);
|
|
}
|
|
|
|
if (elemInput.length > 0 && elemInput[0]) {
|
|
this.elemContainer = elemInput[0].parentNode.parentNode.parentNode.parentNode;
|
|
this.elemInput = elemInput;
|
|
}
|
|
}
|
|
else {
|
|
if (typeof (elemInput) == "string")
|
|
elemInput = document.getElementById(elemInput);
|
|
|
|
if (elemInput) {
|
|
if (fieldType === FieldTypes.DatePicker)
|
|
this.elemContainer = elemInput.parentNode.parentNode.parentNode.parentNode;
|
|
else
|
|
this.elemContainer = elemInput.parentNode.parentNode;
|
|
this.elemInput = elemInput;
|
|
}
|
|
}
|
|
|
|
this.enabled = true;
|
|
this.$elemContainer = $(this.elemContainer);
|
|
this.fieldType = fieldType;
|
|
if (this.fieldType === FieldTypes.FileUpload) {
|
|
//When validating <input type="file" />, we need to update the elemInput reference since it is created a new one when failing inside validateFileUpload method - LC
|
|
var validateInputFileUpload = function () {
|
|
var $this = $(this);
|
|
if (!validateMultiFileUpload($this[0], true)) {
|
|
alert("The file you are trying to upload is not an allowed file type or has an invalid file name. These are the accepted characters: A-z 0-9 ~ ! ( ) - + = [ ] { } , . _");
|
|
self.elemInput.value = null;
|
|
self.elemInput.focus();
|
|
}
|
|
};
|
|
$(this.elemInput).attr("change", "").removeAttr("onChange").unbind("change").change(validateInputFileUpload);
|
|
}
|
|
this.id = id;
|
|
this.isInternal = isInternal;
|
|
this.isRequired = isRequired;
|
|
this.formatValidation = formatValidation;
|
|
this.formatValidationCustom = formatValidationCustom;
|
|
this.elemErrorNote = null;
|
|
this.minAnswer = minAnswer;
|
|
this.maxAnswer = maxAnswer;
|
|
this.maxLength = maxLength;
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = false;
|
|
var isRequiredInfoLableDisplayed = false;
|
|
if (this.isRequired && !isRequiredInfoLableDisplayed) {
|
|
$('#liRequiredFieldInfo').show();
|
|
isRequiredInfoLableDisplayed = true;
|
|
}
|
|
}
|
|
|
|
// Static. Creates a single validation object from an options object.
|
|
FieldValidator.createSingle = function (options) {
|
|
return new FieldValidator(
|
|
options.elemInput,
|
|
options.id,
|
|
options.fieldType,
|
|
options.isInternal,
|
|
options.isRequired,
|
|
options.formatValidation,
|
|
options.formatValidationCustom,
|
|
options.minAnswer,
|
|
options.maxAnswer,
|
|
options.maxLength);
|
|
};
|
|
|
|
// Static. Creates array of validation objects from array of option objects.
|
|
FieldValidator.createMulti = function (optionsArray) {
|
|
var key = null;
|
|
|
|
var ret = {
|
|
keys: [],
|
|
add: function (validator) {
|
|
var key = validator.id;
|
|
this[key] = validator;
|
|
this.keys.push(key);
|
|
}
|
|
};
|
|
|
|
for (var i = 0, len = optionsArray.length; i < len; i++)
|
|
ret.add(FieldValidator.createSingle(optionsArray[i]));
|
|
|
|
return ret;
|
|
};
|
|
|
|
// Internal. Used by validation() to ensure the input does not exceed the max length.
|
|
FieldValidator.prototype.validateMaxLength = function (errorMsg) {
|
|
var ERROR_MSG = FormCenterHomeScriptResources.MaxLengthErrorMessage.format(this.maxLength);
|
|
if (this.maxLength == null)
|
|
return true;
|
|
var cleanValue = this.elemInput.value.trim();
|
|
if (cleanValue != null && cleanValue.length > this.maxLength) {
|
|
errorMsg.push(ERROR_MSG);
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
// Internal. Used by validate() to ensure user-enterable fields are phone numbers (of NANP format).
|
|
FieldValidator.prototype.validatePhone = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidPhoneNumberFormat);
|
|
var origLen = errorMsg.length;
|
|
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.Password:
|
|
var cleanValue = this.elemInput.value.trim();
|
|
if (cleanValue != '' && !phoneValidate(cleanValue, intCountryCode))
|
|
errorMsg.push(ERROR_MSG);
|
|
break;
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
// Internal. Used by validate() to ensure user-enterable fields are postal codes.
|
|
FieldValidator.prototype.validatePostal = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidPostalCode);
|
|
var origLen = errorMsg.length;
|
|
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.Password:
|
|
var cleanValue = this.elemInput.value.trim();
|
|
|
|
if (cleanValue != '' && !isZipCode(cleanValue, intCountryCode))
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
// Internal. Used by validate() to ensure user-enterable fields are email addresses.
|
|
FieldValidator.prototype.validateEmail = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidEmailAddressFormat2);
|
|
var origLen = errorMsg.length;
|
|
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.Password:
|
|
case FieldTypes.ReplyEmail:
|
|
var cleanValue = this.elemInput.value.trim();
|
|
|
|
if (cleanValue != '' && !emailValidate(cleanValue))
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
function getNumericThousandsSeparator() {
|
|
var dummy = new Number(11111111);
|
|
var thousandSep = dummy.toLocaleString().replace(/1/g, '');
|
|
return (thousandSep.length > 0 ? thousandSep.charAt(0) : ',');
|
|
}
|
|
// Internal. Used by validate() to ensure user-enterable fields match custom expression.
|
|
FieldValidator.prototype.validateCustom = function (expr, errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidGenericField);
|
|
var origLen = errorMsg.length;
|
|
|
|
var customRegExp = new RegExp(expr);
|
|
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.Password:
|
|
var cleanValue = this.elemInput.value.trim();
|
|
|
|
if (cleanValue != '' && (!customRegExp.test(cleanValue)))
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
// Internal. Used by validate() to ensure user-enterable fields are letters only.
|
|
FieldValidator.prototype.validateLetters = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.LettersOnlyField);
|
|
var origLen = errorMsg.length;
|
|
|
|
var letterRegExp = /^[a-zA-Z ]+$/;
|
|
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.Password:
|
|
var cleanValue = this.elemInput.value.trim();
|
|
|
|
if (cleanValue != '' && (!letterRegExp.test(cleanValue)))
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
// Internal. Used by validate() to ensure user-enterable fields are numeric (numbers, decimal separators, and group separators allowed).
|
|
FieldValidator.prototype.validateNumeric = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.NumericOnlyField);
|
|
var origLen = errorMsg.length;
|
|
|
|
var numericRegExp = new RegExp("^(([0-9]+?[0-9%G]+?[0-9](|%D[0-9]+))|([0-9]*(|%D[0-9]+)))$"
|
|
.replace(/%G/g, RegExp.metaEscape(getNumericThousandsSeparator()))
|
|
.replace(/%D/g, RegExp.metaEscape(getNumericDecimalSeparator())));
|
|
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.Password:
|
|
var cleanValue = this.elemInput.value.trim();
|
|
|
|
if (cleanValue != '' && (!numericRegExp.test(cleanValue)))
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.validateCurrency = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.CurrencyOnlyField);
|
|
var origLen = errorMsg.length;
|
|
|
|
var value = this.elemInput.value.trim();
|
|
|
|
if (!this.isValidMoney(value)) {
|
|
errorMsg.push(ERROR_MSG);;
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.isValidMoney = function (value) {
|
|
if (value && value != '')
|
|
return /^\$?\s*\d+(,\d{3})*(\.\d{1,2})?$/.test(value);
|
|
else
|
|
return true;
|
|
};
|
|
|
|
//#region Date Validation
|
|
|
|
FieldValidator.prototype.validateDate = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
|
|
var date = $(this.elemInput[0]).val();
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidDate);
|
|
|
|
if (!this.isValidDate(date, this.isRequired)) {
|
|
errorMsg.push(ERROR_MSG);
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.validateTime = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
|
|
var time = $(this.elemInput[0]).val();
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidTime);
|
|
|
|
if (!this.isValidTime(time, this.isRequired)) {
|
|
errorMsg.push(ERROR_MSG);
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.validateDateTime = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
|
|
var date = $(this.elemInput[0]).val();
|
|
|
|
var time = $(this.elemInput[1]).val();
|
|
|
|
var validDate = this.isValidDate(date, this.isRequired);
|
|
|
|
var validTime = this.isValidTime(time, this.isRequired);
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidDateTime);
|
|
|
|
if (!validDate && !validTime) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(ERROR_MSG);
|
|
}
|
|
else if (!validDate) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(ERROR_MSG);
|
|
}
|
|
else if (!validTime) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 1;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(ERROR_MSG);
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.validateDateSpan = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
|
|
var date = $(this.elemInput[0]).val();
|
|
|
|
var dateSpan = $(this.elemInput[1]).val();
|
|
|
|
if (!this.isValidDate(date, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidStartDate);
|
|
}
|
|
if (!this.isValidDate(dateSpan, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 1;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidEndDate);
|
|
}
|
|
if (!this.isValidDateRange(date, dateSpan, this.isRequired, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidDateSpan);
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.validateTimeSpan = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
|
|
var time = $(this.elemInput[0]).val();
|
|
|
|
var timeSpan = $(this.elemInput[1]).val();
|
|
|
|
if (!this.isValidTime(time, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidStartTime);
|
|
}
|
|
|
|
if (!this.isValidTime(timeSpan, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 1;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidEndTime);
|
|
}
|
|
|
|
if (!this.isValidTimeRange(time, timeSpan, this.isRequired, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidTimeSpan);
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.validateDateTimeSpan = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
|
|
var date = $(this.elemInput[0]).val();
|
|
|
|
var dateSpan = $(this.elemInput[1]).val();
|
|
|
|
var time = $(this.elemInput[2]).val();
|
|
|
|
var timeSpan = $(this.elemInput[3]).val();
|
|
|
|
var validDate = this.isValidDate(date, this.isRequired);
|
|
|
|
var validTime = this.isValidTime(time, this.isRequired);
|
|
|
|
if (!validDate && !validTime) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidStartDateTime);
|
|
}
|
|
else if (!validDate) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 0;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidStartDate);
|
|
}
|
|
else if (!validTime) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 2;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidStartTime);
|
|
}
|
|
|
|
var validSpanDate = this.isValidDate(dateSpan, this.isRequired);
|
|
|
|
var validSpanTime = this.isValidTime(timeSpan, this.isRequired);
|
|
|
|
if (!validSpanDate && !validSpanTime) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 1;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidEndDateTime);
|
|
}
|
|
else if (!validSpanDate) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 1;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidEndDate);
|
|
}
|
|
else if (!validSpanTime) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 3;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidEndTime);
|
|
}
|
|
var isDayBeforeMonth = getDateFormat().toLocaleLowerCase() == "dd/mm/yyyy" ? true : false;
|
|
if (!this.isValidDateTimeRange(getDateFromInput(this.elemInput[0], isDayBeforeMonth), getDateFromInput(this.elemInput[1], isDayBeforeMonth), this.isRequired, this.isRequired, time, timeSpan, this.isRequired, this.isRequired)) {
|
|
if (!this.alreadySetFocus) {
|
|
this.focusElementIndex = 1;
|
|
this.alreadySetFocus = true;
|
|
}
|
|
errorMsg.push(FormCenterHomeScriptResources.InvalidDateTimeSpan);
|
|
}
|
|
|
|
// Return false if validation check failed (nubmer of errors changed).
|
|
return origLen == errorMsg.length;
|
|
}
|
|
|
|
FieldValidator.prototype.isValidDate = function (date, dateRequired) {
|
|
var objDate = new dateValidator();
|
|
|
|
return objDate.dateValidateNew(date, dateRequired, '');
|
|
}
|
|
|
|
FieldValidator.prototype.isValidTime = function (time, timeRequired) {
|
|
var objDate = new dateValidator();
|
|
|
|
var amIndex = time.toLowerCase().indexOf('am');
|
|
var pmIndex = time.toLowerCase().indexOf('pm');
|
|
|
|
if (amIndex != -1) {
|
|
time = time.substring(0, amIndex).replace(" ", "");
|
|
|
|
if (time.trim() === "") {
|
|
return false;
|
|
}
|
|
}
|
|
else if (pmIndex != -1) {
|
|
time = time.substring(0, pmIndex).replace(" ", "");
|
|
|
|
if (time.trim() === "") {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return objDate.timeValidate(time, timeRequired, '');
|
|
}
|
|
|
|
FieldValidator.prototype.isValidTimeRange = function (startTime, endTime, startTimeRequired, endTimeRequired) {
|
|
var objDate = new dateValidator();
|
|
|
|
objDate.ysnAllowTimeOnly = true;
|
|
objDate.dtiStartTime = this.stripAMPM(startTime);
|
|
objDate.ysnStartTimeRequired = startTimeRequired;
|
|
objDate.dtiEndTime = this.stripAMPM(endTime);
|
|
objDate.ysnEndTimeRequired = endTimeRequired;
|
|
objDate.ysnDatesAreEqual = true;
|
|
objDate.strStartAMPM = this.getAMPMString(startTime);
|
|
objDate.strEndAMPM = this.getAMPMString(endTime);
|
|
objDate.timesAlreadyValidated = true;
|
|
|
|
return objDate.timeOrderValidate();
|
|
|
|
}
|
|
|
|
FieldValidator.prototype.isValidDateRange = function (startDate, endDate, startDateRequired, endDateRequired) {
|
|
var objDate = new dateValidator();
|
|
objDate.setStartDate(checkDateFormatReturnUSString(startDate, false));
|
|
objDate.setEndDate(checkDateFormatReturnUSString(endDate, false));
|
|
objDate.setStartDateRequired(startDateRequired);
|
|
objDate.setEndDateRequired(endDateRequired);
|
|
objDate.datesAlreadyValidated = true;
|
|
|
|
return objDate.dateOrderValidateNew();
|
|
}
|
|
|
|
FieldValidator.prototype.isValidDateTimeRange = function (startDate, endDate, startDateRequired, endDateRequired, startTime, endTime, startTimeRequired, endTimeRequired) {
|
|
var objDate = new dateValidator();
|
|
|
|
|
|
objDate.setStartDate(checkDateFormatReturnUSString(startDate, false));
|
|
objDate.setEndDate(checkDateFormatReturnUSString(endDate, false));
|
|
objDate.setStartDateRequired(startDateRequired);
|
|
objDate.setEndDateRequired(endDateRequired);
|
|
objDate.ysnAllowEqualDates = true;
|
|
objDate.datesAlreadyValidated = true;
|
|
|
|
var validDateOrder = objDate.dateOrderValidateNew();
|
|
|
|
objDate.strStartAMPM = this.getAMPMString(startTime);
|
|
objDate.strEndAMPM = this.getAMPMString(endTime);
|
|
objDate.ysnAllowTimeOnly = true;
|
|
objDate.ysnAllowEqualTimes = !objDate.ysnDatesAreEqual;
|
|
objDate.dtiStartTime = this.stripAMPM(startTime);
|
|
objDate.ysnStartTimeRequired = startTimeRequired;
|
|
objDate.dtiEndTime = this.stripAMPM(endTime);
|
|
objDate.ysnEndTimeRequired = endTimeRequired;
|
|
objDate.timesAlreadyValidated = true;
|
|
|
|
var validTimeOrder = objDate.timeOrderValidate();
|
|
|
|
return validDateOrder && validTimeOrder;
|
|
}
|
|
|
|
FieldValidator.prototype.stripAMPM = function (time) {
|
|
var amIndex = time.toLowerCase().indexOf('am');
|
|
var pmIndex = time.toLowerCase().indexOf('pm');
|
|
|
|
if (amIndex != -1) {
|
|
time = time.substring(0, amIndex).replace(" ", "");
|
|
}
|
|
else if (pmIndex != -1) {
|
|
time = time.substring(0, pmIndex).replace(" ", "");
|
|
}
|
|
|
|
return time;
|
|
}
|
|
|
|
FieldValidator.prototype.getAMPMString = function (time) {
|
|
var amIndex = time.toLowerCase().indexOf('am');
|
|
var pmIndex = time.toLowerCase().indexOf('pm');
|
|
|
|
var AMPM = '';
|
|
|
|
if (amIndex != -1) {
|
|
AMPM = time.substring(amIndex).replace(" ", "");
|
|
}
|
|
else if (pmIndex != -1) {
|
|
AMPM = time.substring(pmIndex).replace(" ", "");
|
|
}
|
|
return AMPM;
|
|
}
|
|
|
|
//#endregion Date Validation
|
|
|
|
//checkbox validation done for min and max answer selcted
|
|
FieldValidator.prototype.checkBoxValidation = function (errorMsg) {
|
|
var origLen = errorMsg.length;
|
|
if (this.fieldType == FieldTypes.Checkboxes && ((this.minAnswer != "" && this.minAnswer != undefined) || (this.maxAnswer != "" && this.maxAnswer != undefined))) {
|
|
var i = 0, len = this.elemInput.length;
|
|
var checkedCount = 0;
|
|
for (; i < len; i++) {
|
|
if (this.elemInput[i].checked)
|
|
checkedCount++;
|
|
}
|
|
//validation for checkbox min max fields
|
|
if (this.minAnswer != "" && this.minAnswer != undefined) {
|
|
if (checkedCount < parseInt(this.minAnswer, 10)) // the message is not localized on purpose as this has text and dynamic value
|
|
errorMsg.push("This field must have at least " + parseInt(this.minAnswer, 10) + " options selected");
|
|
}
|
|
|
|
if (origLen == errorMsg.length && this.maxAnswer != "" && this.maxAnswer != undefined) {
|
|
if (checkedCount > parseInt(this.maxAnswer, 10)) // the message is not localized on purpose as this has text and dynamic value
|
|
errorMsg.push("This field can have at most " + parseInt(this.maxAnswer, 10) + " options selected");
|
|
}
|
|
}
|
|
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
};
|
|
|
|
// Internal. Used by validate() to ensure required fields are set.
|
|
FieldValidator.prototype.validateRequired = function (errorMsg) {
|
|
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.RequiredField);//FormCenterHomeScriptResources.RequiredField;
|
|
var origLen = errorMsg.length;
|
|
switch (this.fieldType) {
|
|
case FieldTypes.ShortAnswer:
|
|
case FieldTypes.LongAnswer:
|
|
case FieldTypes.ReplyEmail:
|
|
case FieldTypes.Password:
|
|
case FieldTypes.FileUpload:
|
|
case FieldTypes.CodeSnippet:
|
|
case FieldTypes.InputLink:
|
|
case FieldTypes.DatePicker:
|
|
case FieldTypes.InputImage:
|
|
if (this.elemInput != 'undefined' && this.elemInput.value != undefined) {
|
|
if (this.elemInput.value.trim() == '')
|
|
errorMsg.push(ERROR_MSG);
|
|
}
|
|
break;
|
|
case FieldTypes.Checkboxes:
|
|
case FieldTypes.RadioButtons:
|
|
var i = 0, len = this.elemInput.length;
|
|
|
|
for (; i < len; i++) {
|
|
if (this.elemInput[i].checked)
|
|
break;
|
|
}
|
|
|
|
if (i == len)
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
case FieldTypes.Dropdown:
|
|
case FieldTypes.FormLink:
|
|
if (this.elemInput.selectedIndex <= 0)
|
|
errorMsg.push(ERROR_MSG);
|
|
|
|
break;
|
|
case FieldTypes.DateTime:
|
|
var i = 0, len = this.elemInput.length;
|
|
|
|
for (; i < len; i++) {
|
|
if (this.elemInput[i].value.trim() == '') {
|
|
errorMsg.push(ERROR_MSG);
|
|
this.focusElementIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// Return false if validation check failed (number of errors changed).
|
|
return origLen == errorMsg.length;
|
|
};
|
|
|
|
// Performs validation for field and updates format if necessary.
|
|
FieldValidator.prototype.validate = function (assignFocusOnFailure, checkForInappropriateWords) {
|
|
var errorMsg = [];
|
|
|
|
// Element not present OR disabled, pass (skipped).
|
|
if (this.elemInput == null || !this.enabled)
|
|
return true;
|
|
|
|
if (!this.isRequired || (this.isRequired && this.validateRequired(errorMsg))) {
|
|
//checkbox validation done for min and max answer selected
|
|
if (this.checkBoxValidation(errorMsg)) {
|
|
switch (this.formatValidation) {
|
|
case FieldValidation.Letters:
|
|
this.validateLetters(errorMsg);
|
|
break;
|
|
case FieldValidation.Numeric:
|
|
this.validateNumeric(errorMsg);
|
|
break;
|
|
case FieldValidation.Currency:
|
|
this.validateCurrency(errorMsg);
|
|
break;
|
|
case FieldValidation.PhoneNumber:
|
|
this.validatePhone(errorMsg);
|
|
break;
|
|
case FieldValidation.PostalCode:
|
|
this.validatePostal(errorMsg);
|
|
break;
|
|
case FieldValidation.EmailAddress:
|
|
this.validateEmail(errorMsg);
|
|
break;
|
|
case FieldValidation.RegEx:
|
|
this.validateCustom(this.formatValidationCustom, errorMsg);
|
|
break;
|
|
case FieldValidation.Date:
|
|
this.validateDate(errorMsg);
|
|
break;
|
|
case FieldValidation.Time:
|
|
this.validateTime(errorMsg);
|
|
break;
|
|
case FieldValidation.DateTime:
|
|
this.validateDateTime(errorMsg);
|
|
break;
|
|
case FieldValidation.DateSpan:
|
|
this.validateDateSpan(errorMsg);
|
|
break;
|
|
case FieldValidation.TimeSpan:
|
|
this.validateTimeSpan(errorMsg);
|
|
break;
|
|
case FieldValidation.DateTimeSpan:
|
|
this.validateDateTimeSpan(errorMsg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (this.fieldType === FieldTypes.DatePicker && this.elemInput.value.trim() != '') {
|
|
//validate date picker value (based on telerik mvc datePicker)
|
|
var datepicker = $(this.elemInput).data("tDatePicker");
|
|
if ($(this.elemInput).hasClass('t-state-error') || datepicker.parse(this.elemInput.value.trim()) == null)
|
|
errorMsg.push("Invalid date format");
|
|
}
|
|
if (this.fieldType === FieldTypes.ShortAnswer || this.fieldType === FieldTypes.LongAnswer) {
|
|
var validator = this;
|
|
|
|
if (checkForInappropriateWords != null && typeof (checkForInappropriateWords.push) == 'function') {
|
|
checkForInappropriateWords.push(validator);
|
|
} else {
|
|
if (HasInappropriateWords(this.elemInput.value.trim())) {
|
|
$(this.elemInput).addClass('t-state-error');
|
|
errorMsg.push(FormCenterHomeScriptResources.InappropriateWords);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FeatureToggles.isActive("CMS.FormCenter.EnableServerSideValidationsForSubmissions")
|
|
&& this.fieldType === FieldTypes.FileUpload
|
|
&& this.elemInput.value.trim() != '') {
|
|
if (Math.round((this.elemInput.files[0].size / 1024)) > 20480)
|
|
errorMsg.push("Files cannot be larger than 20 MB.");
|
|
}
|
|
|
|
this.validateMaxLength(errorMsg);
|
|
|
|
if (errorMsg.length > 0 && $(this.elemInput).is(":visible")) {
|
|
this.errorShow(errorMsg);
|
|
|
|
if (assignFocusOnFailure) {
|
|
this.focusErrorElement();
|
|
}
|
|
|
|
return false;
|
|
} else {
|
|
this.errorClear();
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
// Performs validation for admin edit internal only fields and updates format if necessary.
|
|
FieldValidator.prototype.validateInternal = function (assignFocusOnFailure, checkForInappropriateWords) {
|
|
if (this.isInternal) {
|
|
var errorMsg = [];
|
|
|
|
// Element not present OR disabled, pass (skipped).
|
|
if (this.elemInput == null || !this.enabled)
|
|
return true;
|
|
|
|
if (!this.isRequired || (this.isRequired && this.validateRequired(errorMsg))) {
|
|
//checkbox validation done for min and max answer selected
|
|
if (this.checkBoxValidation(errorMsg)) {
|
|
switch (this.formatValidation) {
|
|
case FieldValidation.Letters:
|
|
this.validateLetters(errorMsg);
|
|
break;
|
|
case FieldValidation.Numeric:
|
|
this.validateNumeric(errorMsg);
|
|
break;
|
|
case FieldValidation.Currency:
|
|
this.validateCurrency(errorMsg);
|
|
break;
|
|
case FieldValidation.PhoneNumber:
|
|
this.validatePhone(errorMsg);
|
|
break;
|
|
case FieldValidation.PostalCode:
|
|
this.validatePostal(errorMsg);
|
|
break;
|
|
case FieldValidation.EmailAddress:
|
|
this.validateEmail(errorMsg);
|
|
break;
|
|
case FieldValidation.RegEx:
|
|
this.validateCustom(this.formatValidationCustom, errorMsg);
|
|
break;
|
|
case FieldValidation.Date:
|
|
this.validateDate(errorMsg);
|
|
break;
|
|
case FieldValidation.Time:
|
|
this.validateTime(errorMsg);
|
|
break;
|
|
case FieldValidation.DateTime:
|
|
this.validateDateTime(errorMsg);
|
|
break;
|
|
case FieldValidation.DateSpan:
|
|
this.validateDateSpan(errorMsg);
|
|
break;
|
|
case FieldValidation.TimeSpan:
|
|
this.validateTimeSpan(errorMsg);
|
|
break;
|
|
case FieldValidation.DateTimeSpan:
|
|
this.validateDateTimeSpan(errorMsg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (this.fieldType === FieldTypes.DatePicker && this.elemInput.value.trim() != '') {
|
|
//validate date picker value (based on telerik mvc datePicker)
|
|
var datepicker = $(this.elemInput).data("tDatePicker");
|
|
if ($(this.elemInput).hasClass('t-state-error') || datepicker.parse(this.elemInput.value.trim()) == null)
|
|
errorMsg.push("Invalid date format");
|
|
}
|
|
if (this.fieldType === FieldTypes.ShortAnswer || this.fieldType === FieldTypes.LongAnswer) {
|
|
var validator = this;
|
|
|
|
if (checkForInappropriateWords != null && typeof (checkForInappropriateWords.push) == 'function') {
|
|
checkForInappropriateWords.push(validator);
|
|
} else {
|
|
if (HasInappropriateWords(this.elemInput.value.trim())) {
|
|
$(this.elemInput).addClass('t-state-error');
|
|
errorMsg.push(FormCenterHomeScriptResources.InappropriateWords);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.validateMaxLength(errorMsg);
|
|
|
|
if (errorMsg.length > 0 && $(this.elemInput).is(":visible")) {
|
|
this.errorShow(errorMsg);
|
|
|
|
if (assignFocusOnFailure) {
|
|
this.focusErrorElement();
|
|
}
|
|
|
|
return false;
|
|
} else {
|
|
this.errorClear();
|
|
return true;
|
|
}
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
FieldValidator.prototype.handleInappropriateWords = function (focus) {
|
|
var errorMsg = [];
|
|
$(this.elemInput).addClass('t-state-error');
|
|
errorMsg.push(FormCenterHomeScriptResources.InappropriateWords);
|
|
this.errorShow(errorMsg);
|
|
if (focus) {
|
|
this.focusErrorElement();
|
|
}
|
|
};
|
|
|
|
FieldValidator.prototype.focusErrorElement = function () {
|
|
var scrollIntoView = function (element) {
|
|
var offset = $(element).offset();
|
|
var elementTop = offset.top;
|
|
// Add a 50px padding to the top of the element, just for aesthetics
|
|
$(document).scrollTop(elementTop - 150);
|
|
};
|
|
|
|
if (this.elemInputIsArray) {
|
|
if ($(this.elemInput).is(":visible")) {
|
|
if (this.elemInput.length > this.focusElementIndex) {
|
|
this.elemInput[this.focusElementIndex].focus();
|
|
}
|
|
else {
|
|
this.elemInput[0].focus();
|
|
}
|
|
scrollIntoView(this.elemInput[0]);
|
|
}
|
|
this.alreadySetFocus = false;
|
|
this.focusElementIndex = 0;
|
|
}
|
|
else {
|
|
if ($(this.elemInput).is(":visible")) {
|
|
this.elemInput.focus();
|
|
scrollIntoView(this.elemInput);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Shows error message for field. Called by validate() if field value fails validation.
|
|
FieldValidator.prototype.errorShow = function (messages) {
|
|
if (this.elemErrorNote)
|
|
this.errorClear();
|
|
|
|
// Element not defined, cannot perform operation.
|
|
if (this.elemInput == null)
|
|
return;
|
|
|
|
this.$elemContainer.addClass('error');
|
|
this.elemErrorNote = [];
|
|
|
|
$('ol li.error div').addClass('selfClear');
|
|
|
|
if (this.elemInput != undefined) {
|
|
if (this.elemInput["0"] != undefined) {
|
|
//Check current element is radio
|
|
if (this.elemInput["0"].type == "radio" & !(this.$elemContainer.closest('li').hasClass('error'))) {
|
|
this.$elemContainer.closest('li').addClass('error');
|
|
originalTextColorRadio = this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color;
|
|
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = "#800000";
|
|
}
|
|
else //Check current element is checkbox
|
|
if (this.elemInput["0"].type == "checkbox" & !(this.$elemContainer.closest('li').hasClass('error'))) {
|
|
this.$elemContainer.closest('li').addClass('error');
|
|
originalTextColorCheckBox = this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color;
|
|
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = "#800000";
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var i = 0, len = messages.length; i < len; i++) {
|
|
var errorElemMsg = document.createElement('p');
|
|
|
|
errorElemMsg.className = 'explanation';
|
|
|
|
var multiSelectable = this.elemInput[0] !== undefined && this.elemInput.tagName !== "SELECT";
|
|
if (multiSelectable) {
|
|
errorElemMsg.id = 'errorMsg' + this.elemInput[0].id;
|
|
}
|
|
else {
|
|
errorElemMsg.id = 'errorMsg' + this.elemInput.id;
|
|
}
|
|
|
|
errorElemMsg.innerHTML = messages[i];
|
|
|
|
if (this.elemInput != undefined) {
|
|
if (this.elemInput["0"] != undefined) {
|
|
if (this.elemInput["0"].type == "radio" || this.elemInput["0"].type == "checkbox") {
|
|
errorElemMsg.style.backgroundColor = "#940E0D"
|
|
errorElemMsg.style.color = "#FFFFFF";
|
|
errorElemMsg.style.fontWeight = "bold"
|
|
errorElemMsg.style.lineHeight = "1.2"
|
|
errorElemMsg.style.width = "94%"
|
|
errorElemMsg.style.margin = ".5em 0 0"
|
|
errorElemMsg.style.padding = ".5em"
|
|
}
|
|
}
|
|
}
|
|
|
|
this.elemContainer.appendChild(errorElemMsg);
|
|
|
|
this.elemErrorNote.push(errorElemMsg);
|
|
}
|
|
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
|
|
};
|
|
|
|
// Clears error message for field. Called by validate() if field value passes validation.
|
|
FieldValidator.prototype.errorClear = function () {
|
|
if (this.elemInput != undefined) {
|
|
if (this.elemInput["0"] != undefined) {
|
|
var i = 0, len = this.elemInput.length;
|
|
for (; i < len; i++) {
|
|
if (this.elemInput[i].checked)
|
|
break;
|
|
}
|
|
|
|
if (i != len) {
|
|
if (this.elemInput["0"].type == "radio") {
|
|
this.$elemContainer.closest('li').removeClass('error');
|
|
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = originalTextColorRadio;
|
|
}
|
|
else if (this.elemInput["0"].type == "checkbox") {
|
|
this.$elemContainer.closest('li').removeClass('error');
|
|
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = originalTextColorCheckBox;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.elemErrorNote == null)
|
|
return;
|
|
else if (this.elemInput == null)
|
|
return;
|
|
|
|
if (this.elemErrorNote.length > 0) {
|
|
var errorParent = this.elemErrorNote[0].parentNode;
|
|
|
|
for (var i = 0, len = this.elemErrorNote.length; i < len; i++)
|
|
errorParent.removeChild(this.elemErrorNote[i]);
|
|
|
|
this.elemErrorNote = null;
|
|
}
|
|
|
|
this.$elemContainer.removeClass('error');
|
|
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
|
|
};
|
|
|
|
FieldValidator.prototype.getErrorMessage = function (errorTemplateMsg) {
|
|
var $fieldElemContainer = $(this.elemContainer);
|
|
|
|
if (!$fieldElemContainer.hasClass('formFieldContainer'))
|
|
{
|
|
$fieldElemContainer = $fieldElemContainer.parents('.formFieldContainer');
|
|
}
|
|
|
|
var $fieldLabelElem = $fieldElemContainer.find('.labelForFieldElement');
|
|
var fieldLabel = '';
|
|
|
|
if ($fieldLabelElem.length > 0)
|
|
{
|
|
fieldLabel = $fieldLabelElem.text().replace('*', '');
|
|
}
|
|
else
|
|
{
|
|
$fieldLabelElem = $fieldElemContainer.find('legend');
|
|
if ($fieldLabelElem.length > 0)
|
|
{
|
|
fieldLabel = $fieldLabelElem.text().replace('*', '');
|
|
}
|
|
}
|
|
|
|
var errorMsg = errorTemplateMsg.format(fieldLabel);
|
|
|
|
return errorMsg;
|
|
};
|
|
/// <reference path="../../../../Scripts/jquery-1.3.2-vsdoc.js"/>
|
|
/// <reference path="../../../../Scripts/json2.js"/>
|
|
/// <reference path="../../../../Scripts/HtmlExtensionSupport.js"/>
|
|
/// <reference path="../../../../Common/GlobalJSFunctionsDetail.js" />
|
|
/// <reference path="Home.js" />
|
|
|
|
// Configurable in debug console. Controls behavior of FieldConditionsRunner.log().
|
|
var condRunnerHideLogDupes = true;
|
|
|
|
// Missing methods for IE
|
|
if (!Element.prototype.matches) {
|
|
Element.prototype.matches =
|
|
Element.prototype.msMatchesSelector ||
|
|
Element.prototype.webkitMatchesSelector;
|
|
}
|
|
|
|
if (!Element.prototype.closest) {
|
|
Element.prototype.closest = function (s) {
|
|
var el = this;
|
|
|
|
do {
|
|
if (Element.prototype.matches.call(el, s)) return el;
|
|
el = el.parentElement || el.parentNode;
|
|
} while (el !== null && el.nodeType === 1);
|
|
return null;
|
|
};
|
|
}
|
|
|
|
////////// Helper Functions ///////////////
|
|
|
|
$("*").focus(function () {
|
|
var inputs = $("input[type=text][cp5ph=true], textarea[cp5ph=true]");
|
|
if (inputs != null) {
|
|
for (var i = 0; i < inputs.length; i++) {
|
|
var elementName = inputs[i].getAttribute('id');
|
|
if (elementName != null) {
|
|
var top = $('#' + elementName).offset().top;
|
|
var left = $('#' + elementName).offset().left;
|
|
if (top != -2 && left != -2)
|
|
$('#ph_' + elementName).offset({ left: (left + 5), top: (top + 5) });
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Helper that handles replacement of special characters.
|
|
// * value - variable to handle characters of.
|
|
function HandleCharacters(value) {
|
|
return value.replace(/,/g, '_d');
|
|
}
|
|
|
|
if (Array.prototype.any == null && !$.isFunction(Array.prototype.any)) {
|
|
// Returns true if callback condition returns true for any items in array.
|
|
// * callback - Callback function with single argument for current index. The 'this' reference points to the array.
|
|
Array.prototype.any = function (callback) {
|
|
if (this == null)
|
|
return false;
|
|
|
|
for (var i = 0, len = this.length; i < len; i++) {
|
|
if (callback.call(this, i))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (Array.prototype.all == null && !$.isFunction(Array.prototype.all)) {
|
|
// Returns true if callback condition returns true for all items in array.
|
|
// * callback - Callback function with single argument for current index. The 'this' reference points to the array.
|
|
Array.prototype.all = function (callback) {
|
|
if (this == null)
|
|
return false;
|
|
|
|
for (var i = 0, len = this.length; i < len; i++) {
|
|
if (!callback.call(this, i))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
}
|
|
|
|
if (Error.argNull == null || !$.isFunction(Error.argNull)) {
|
|
// Static helper that creates error when null argument that should not be null is encountered.
|
|
// * argName - Name of problematic null argument.
|
|
Error.argNull = function (argName) {
|
|
return new ReferenceError(argName + " cannot be null");
|
|
}
|
|
}
|
|
|
|
// Overridden on a per-form basis. Retrieves validator information for submission validation.
|
|
// * validators - Validator dictionary.
|
|
function getFormConditionData() {
|
|
return [];
|
|
}
|
|
|
|
// Prints useful debugging information for FieldConditionsRunner.run() results. Use as done callback.
|
|
// Note: When minifiying the JavaScript, this function can/should be removed.
|
|
// * logs - Log generated by run().
|
|
function debugCondRunnerLogResults(logs) {
|
|
if (logs == null)
|
|
throw new Error.argNull("logs");
|
|
|
|
console.log("## run() started at " + (new Date()) + " ##");
|
|
|
|
for (var i = 0, iLen = logs.length; i < iLen; i++) {
|
|
var log = logs[i];
|
|
var resultEx = log.isMet ? " (met)" : " (not met)";
|
|
|
|
console.log(
|
|
"field: " + log.id +
|
|
", condIndex: " + log.condIndex +
|
|
", action: " + ConditionActions.getName(log.actType) +
|
|
", result: " + ConditionRunnerActResult.getName(log.result) + resultEx);
|
|
|
|
if (log.needRestart)
|
|
console.log("-- restart --");
|
|
}
|
|
|
|
console.log("## run() ended ##");
|
|
console.log("\t");
|
|
}
|
|
|
|
// Helper that repositions line siblings by re-assigning left/middle/right classes.
|
|
// * liSiblingList - Array of LI elements for a form line.
|
|
function repositionLineSiblings(liSiblingList) {
|
|
if (liSiblingList == null)
|
|
throw new Error.argNull("liSiblingList");
|
|
|
|
var sibling, $sibling;
|
|
var len = liSiblingList.length;
|
|
|
|
if (len > 0) {
|
|
var operableNodes = [];
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
sibling = liSiblingList[i];
|
|
$sibling = $(sibling);
|
|
|
|
if (!$sibling.hasClass('hidden'))
|
|
operableNodes.push($sibling);
|
|
}
|
|
|
|
len = operableNodes.length;
|
|
|
|
if (len > 0) {
|
|
operableNodes[0].removeClass('middle right').addClass('left');
|
|
|
|
var j = 1;
|
|
|
|
for (; j < len - 1; j++)
|
|
operableNodes[j].removeClass('left right').addClass('middle');
|
|
|
|
if (j < len)
|
|
operableNodes[j].removeClass('left middle').addClass('right');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper that gets sibling field LI elements for a line field LI element.
|
|
// * liElem - The LI element for a form field to get line siblings LIs for.
|
|
function getLineSiblings(liElem) {
|
|
|
|
if (liElem == null && (window.location.href).toString().toLowerCase().indexOf("print") != -1)
|
|
return "";
|
|
|
|
if (liElem == null)
|
|
throw new Error.argNull("liElem");
|
|
|
|
var nodeList = [];
|
|
var startNode = liElem;
|
|
|
|
// Get start of line.
|
|
while (startNode && !$(startNode).hasClass('lineStart'))
|
|
startNode = previousElementSibling(startNode);
|
|
|
|
// Get end of line.
|
|
if (startNode) {
|
|
var endNode = startNode;
|
|
var $endNode = null;
|
|
|
|
while (endNode != null) {
|
|
$endNode = $(endNode);
|
|
|
|
if ($endNode.hasClass('lineEnd'))
|
|
break;
|
|
|
|
endNode = nextElementSibling(endNode);
|
|
}
|
|
}
|
|
|
|
if (startNode && endNode) {
|
|
var nodeEnum = startNode;
|
|
|
|
while (true) {
|
|
nodeList.push(nodeEnum);
|
|
|
|
if (nodeEnum == endNode)
|
|
break;
|
|
|
|
nodeEnum = nextElementSibling(nodeEnum);
|
|
}
|
|
}
|
|
|
|
return nodeList;
|
|
}
|
|
|
|
////////// Enumerations ///////////////////
|
|
|
|
// Condition actions.
|
|
var ConditionActions = {
|
|
None: 0,
|
|
Show: 1,
|
|
Hide: 2,
|
|
Require: 3,
|
|
RedirectTo: 4,
|
|
getName: function (value) {
|
|
for (var k in ConditionActions) {
|
|
if (ConditionActions[k] == value)
|
|
return k;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
// Condition comparison types.
|
|
var ConditionComparison = {
|
|
None: 0,
|
|
GreaterThan: 1,
|
|
LessThan: 2,
|
|
EqualTo: 3,
|
|
NotEqualTo: 4,
|
|
Contains: 5,
|
|
Available: 6,
|
|
Unavailable: 7,
|
|
Between: 8,
|
|
getName: function (value) {
|
|
for (var k in ConditionComparison) {
|
|
if (ConditionComparison[k] == value)
|
|
return k;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
// Condition runner action results.
|
|
var ConditionRunnerActResult = {
|
|
None: 0,
|
|
SuccessImplicit: 1,
|
|
SuccessExplicit: 2,
|
|
SkipDuplicate: 3,
|
|
SkipContradiction: 4,
|
|
getName: function (value) {
|
|
for (var k in ConditionRunnerActResult) {
|
|
if (ConditionRunnerActResult[k] == value)
|
|
return k;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
////////// FieldCondition Class ///////////
|
|
|
|
// Internal. Creates instance of FieldCondition class.
|
|
// * parent - Parent FieldConditions instance.
|
|
// * condInfo - Object containing properties {compType, compValue, actElemInput, actID, actType, actFieldType, actURL, actURLNewWindow}.
|
|
function FieldCondition(parent, condInfo) {
|
|
if (parent == null)
|
|
throw new Error.argNull("parent");
|
|
else if (condInfo == null)
|
|
throw new Error.argNull("condInfo");
|
|
|
|
$.extend(this, condInfo);
|
|
|
|
// Set instance parent.
|
|
this.parent = parent;
|
|
|
|
// Process actElemInput argument.
|
|
var actElemInput = this.actElemInput;
|
|
this.actElemInputIsArray = $.isArray(actElemInput);
|
|
|
|
if (this.actElemInputIsArray) {
|
|
for (var i = 0, len = actElemInput.length; i < len; i++) {
|
|
if (typeof (actElemInput[i]) == "string")
|
|
actElemInput[i] = document.getElementById(actElemInput[i]);
|
|
}
|
|
|
|
if (actElemInput.length > 0 && actElemInput[0]) {
|
|
this.actElemContainer = actElemInput[0].closest('.formFieldContainer');
|
|
this.actElemInput = actElemInput;
|
|
}
|
|
}
|
|
else {
|
|
if (typeof (actElemInput) == "string")
|
|
actElemInput = document.getElementById(actElemInput);
|
|
|
|
if (actElemInput) {
|
|
this.actElemContainer = actElemInput.closest('.formFieldContainer');
|
|
this.actElemInput = actElemInput;
|
|
}
|
|
}
|
|
|
|
// Get shared container.
|
|
this.$actElemContainer = $(this.actElemContainer);
|
|
}
|
|
|
|
// Static. Creates multiple instances from list of condition information.
|
|
FieldCondition.createMulti = function (parent, condList) {
|
|
if (parent == null)
|
|
throw new Error.argNull("parent");
|
|
else if (condList == null)
|
|
throw new Error.argNull("condList");
|
|
|
|
var ret = [];
|
|
|
|
for (var i = 0, len = condList.length; i < len; i++)
|
|
ret.push(new FieldCondition(parent, condList[i]));
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Checks if condition is met and performs any necessary action.
|
|
// * updateUI - Determines if UI is updated after check. Treated as true if null/unspecified.
|
|
FieldCondition.prototype.check = function (updateUI) {
|
|
// TODO: Handle checkboxes/radios/dropdowns when Akila gets that done on back-end.
|
|
var thisValue = [];
|
|
var compValue = this.compValue;
|
|
var isMet = false;
|
|
|
|
switch (this.actFieldType) {
|
|
case FieldTypes.Checkboxes:
|
|
for (var i = 0, len = this.actElemInput.length; i < len; i++) {
|
|
if (this.actElemInput[i].checked)
|
|
thisValue.push(this.actElemInput[i].value.replace(/\,/g, '_comma_'));
|
|
}
|
|
break;
|
|
case FieldTypes.RadioButtons:
|
|
for (var i = 0, len = this.actElemInput.length; i < len; i++) {
|
|
if (this.actElemInput[i].checked) {
|
|
thisValue = [this.actElemInput[i].value];
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case FieldTypes.DateTime:
|
|
var tempArray = new Array();
|
|
for (var i = 0, len = this.actElemInput.length; i < len; i++) {
|
|
tempArray.push([this.actElemInput[i].value])
|
|
}
|
|
thisValue = [tempArray.join(',')];
|
|
break;
|
|
default:
|
|
thisValue = [this.actElemInput.value];
|
|
}
|
|
|
|
var extractMoneyValue = function (v) {
|
|
var stringBeginsWith = function (val, beginString) {
|
|
return val.substring(0, beginString.length) === beginString
|
|
}
|
|
if (v && v != '') {
|
|
if (stringBeginsWith(v, '$')) {
|
|
return v.substring(1).replace(',', '');
|
|
}
|
|
}
|
|
return v.replace(',', '');
|
|
};
|
|
|
|
|
|
var isNum = function (val) {
|
|
var extracted = extractMoneyValue(val);
|
|
return parseFloat(extracted) === +extracted;
|
|
};
|
|
|
|
var checkAgainst = function (compValue) {
|
|
switch (this.compType) {
|
|
case ConditionComparison.GreaterThan:
|
|
return thisValue.any(function (index) {
|
|
if (isNum(this[index]) && isNum(HandleCharacters(compValue))) {
|
|
return parseFloat(extractMoneyValue(this[index])) > parseFloat(extractMoneyValue(HandleCharacters(compValue)));
|
|
}
|
|
return false;
|
|
});
|
|
case ConditionComparison.LessThan:
|
|
return thisValue.any(function (index) {
|
|
if (isNum(this[index]) && isNum(HandleCharacters(compValue))) {
|
|
return parseFloat(extractMoneyValue(this[index])) < parseFloat(extractMoneyValue(HandleCharacters(compValue)));
|
|
}
|
|
return false;
|
|
});
|
|
case ConditionComparison.EqualTo:
|
|
if (this.actFieldType == FieldTypes.DateTime) {
|
|
if (this.actIsDateTimeSpan) {
|
|
return this.checkDateEqualSpan(thisValue[0], compValue);
|
|
}
|
|
else {
|
|
return this.checkDateEqualTo(thisValue[0], compValue);
|
|
}
|
|
}
|
|
else {
|
|
return thisValue.any(function (index) {
|
|
return (isNull(HandleCharacters(this[index]), '') == isNull(HandleCharacters(compValue), ''));
|
|
});
|
|
}
|
|
case ConditionComparison.NotEqualTo:
|
|
return thisValue.any(function (index) { return (isNull(this[index], '').toUpperCase() != isNull(HandleCharacters(compValue), '').toUpperCase()); });
|
|
break;
|
|
case ConditionComparison.Contains:
|
|
var containsExp = new RegExp(RegExp.metaEscape(HandleCharacters(compValue)), 'i');
|
|
|
|
return thisValue.any(function (index) {
|
|
return containsExp.test(this[index]);
|
|
});
|
|
case ConditionComparison.Unavailable:
|
|
return this.$actElemContainer.hasClass('unavailable');
|
|
case ConditionComparison.Available:
|
|
return !this.$actElemContainer.hasClass('unavailable');
|
|
case ConditionComparison.Between:
|
|
return this.checkDateBetween(thisValue[0], compValue);
|
|
return;
|
|
case ConditionComparison.None:
|
|
default:
|
|
return true;
|
|
}
|
|
};
|
|
|
|
switch (this.actFieldType) {
|
|
case FieldTypes.Checkboxes:
|
|
var compArr = compValue.split(',');
|
|
|
|
isMet = true;
|
|
|
|
for (var i = 0, len = compArr.length; i < len; i++) {
|
|
|
|
if (!checkAgainst.call(this, compArr[i])) {
|
|
isMet = false;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
isMet = checkAgainst.call(this, compValue);
|
|
}
|
|
|
|
if (updateUI)
|
|
this.doAction(isMet);
|
|
|
|
return isMet;
|
|
};
|
|
|
|
// Performs changes to applying field based on condition action and comparison result.
|
|
FieldCondition.prototype.doAction = function (isMet) {
|
|
var validator = (this.parent.validators ? this.parent.validators[this.parent.id] : null);
|
|
|
|
switch (this.actType) {
|
|
case ConditionActions.Show:
|
|
this.doActionShow(isMet, validator);
|
|
break;
|
|
case ConditionActions.Hide:
|
|
this.doActionHide(isMet, validator);
|
|
break;
|
|
case ConditionActions.Require:
|
|
this.doActionRequire(isMet, validator);
|
|
break;
|
|
case ConditionActions.RedirectTo:
|
|
this.doActionRedirect(isMet, validator);
|
|
break;
|
|
}
|
|
};
|
|
|
|
FieldCondition.prototype.doActionShow = function (isMet, validator) {
|
|
if (isMet) {
|
|
this.parent.$elemContainer.removeClass('hidden');
|
|
this.parent.$elemContainer.removeClass('unavailable');
|
|
|
|
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
|
|
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
|
|
|
|
if (this.parent.$elemContainer.find('label > span') != null && this.parent.$elemContainer.find('label > span').length > 0)
|
|
$('#liRequiredFieldInfo').show();
|
|
|
|
if (validator)
|
|
validator.enabled = true;
|
|
}
|
|
else {
|
|
this.parent.$elemContainer.addClass('hidden');
|
|
this.parent.$elemContainer.addClass('unavailable');
|
|
|
|
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
|
|
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
|
|
|
|
if (validator)
|
|
validator.enabled = false;
|
|
}
|
|
};
|
|
|
|
FieldCondition.prototype.doActionHide = function (isMet, validator) {
|
|
if (isMet) {
|
|
this.parent.$elemContainer.addClass('hidden');
|
|
this.parent.$elemContainer.addClass('unavailable');
|
|
|
|
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
|
|
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
|
|
|
|
if (validator)
|
|
validator.enabled = false;
|
|
}
|
|
else {
|
|
this.parent.$elemContainer.removeClass('hidden');
|
|
this.parent.$elemContainer.removeClass('unavailable');
|
|
|
|
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
|
|
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
|
|
|
|
if (validator)
|
|
validator.enabled = true;
|
|
}
|
|
};
|
|
|
|
FieldCondition.prototype.doActionRequire = function (isMet, validator) {
|
|
if (isMet) {
|
|
this.parent.$elemReq.removeClass('hidden');
|
|
|
|
if (validator == null) {
|
|
validator = new FieldValidator(this.parent.elemInput, this.parent.id, this.parent.fieldType, this.parent.isInternal, true, FieldValidation.Any);
|
|
this.parent.validators.add(validator);
|
|
}
|
|
|
|
this.parent.$elemContainer.find('label.labelForFieldElement > span').show();
|
|
$('#liRequiredFieldInfo').show();
|
|
if (validator)
|
|
validator.isRequired = true;
|
|
}
|
|
else {
|
|
this.parent.$elemReq.addClass('hidden');
|
|
this.parent.$elemContainer.find('label.labelForFieldElement > span').hide();
|
|
|
|
if (validator)
|
|
validator.isRequired = false;
|
|
}
|
|
};
|
|
|
|
FieldCondition.prototype.doActionRedirect = function (isMet, validator) {
|
|
// TODO: Some point alter this to pass in references for submitRedirect/redirectNewWindow. Not ideal at moment to ref. global vars.
|
|
var submitRedirect = document.getElementById('submitRedirect');
|
|
|
|
redirectNewWindow = null;
|
|
submitRedirect.value = '';
|
|
|
|
if (isMet) {
|
|
if (this.actURLNewWindow) {
|
|
redirectNewWindow = this.actURL;
|
|
submitRedirect.value = '';
|
|
}
|
|
else
|
|
submitRedirect.value = this.actURL;
|
|
}
|
|
};
|
|
|
|
// Attachs event handler to field to monitor changes.
|
|
// * condRunner - FieldConditionsRunner instance to attach.
|
|
// Note: Calling more than once will have no effect.
|
|
FieldCondition.prototype.attachRunner = function (condRunner) {
|
|
if (condRunner == null)
|
|
throw new Error.argNull("condRunner");
|
|
|
|
// Do not try to bind this if it is an internal field condition and we are not running internal field
|
|
// conditions.
|
|
if (this.parent.isInternal && !condRunner.runInternal)
|
|
return;
|
|
|
|
if ($.data(this.actElemInput, "runner_chghook") == null) {
|
|
var changeHook = function (event) {
|
|
condRunner.run(true);
|
|
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
|
|
};
|
|
$.data(this.actElemInput, "runner_chghook", changeHook);
|
|
$(this.actElemInput).change(changeHook);
|
|
}
|
|
};
|
|
|
|
// Removes event handler that monitors changes.
|
|
// Note: Calling more than once will have no effect.
|
|
FieldCondition.prototype.detachRunner = function () {
|
|
var changeHook = $.data(this.actElemInput, "runner_chghook");
|
|
|
|
if (changeHook) {
|
|
$(this.actElemInput).unbind('change', changeHook);
|
|
$.removeData(this.actElemInput, "runner_chghook");
|
|
}
|
|
};
|
|
|
|
FieldCondition.prototype.checkDateCommon = function (thisValue, compValue) {
|
|
var defaultDate = '1/1/70';
|
|
var defualtDateObj = new Date(defaultDate);
|
|
|
|
var compArr = compValue.split(',');
|
|
var valueArr = thisValue.split(',');
|
|
|
|
var hasTimeOfDayStart = false;
|
|
var hasTimeOfDayEnd = false;
|
|
|
|
var compareStartDate;
|
|
var compareEndDate;
|
|
|
|
if (compArr[0] == '') {
|
|
compareStartDate = new Date(defaultDate + ' ' + compArr[2]);
|
|
}
|
|
else {
|
|
compareStartDate = new Date(compArr[0] + ' ' + compArr[2]);
|
|
}
|
|
|
|
if (compArr[1] == '') {
|
|
compareEndDate = new Date(defaultDate + ' ' + compArr[3]);
|
|
}
|
|
else {
|
|
compareEndDate = new Date(compArr[1] + ' ' + compArr[3]);
|
|
}
|
|
|
|
var validStartDate = new Date(defaultDate);
|
|
var validEndDate = new Date(defaultDate);
|
|
var timeOfDayStart = '';
|
|
var timeOfDayEnd = '';
|
|
|
|
if (valueArr.length == 4) {
|
|
if (valueArr[0] == '') {
|
|
validStartDate = new Date(defaultDate + ' ' + valueArr[2]);
|
|
}
|
|
else {
|
|
validStartDate = new Date(valueArr[0] + ' ' + valueArr[2]);
|
|
}
|
|
|
|
timeOfDayStart = this.getAMPMString(valueArr[2]);
|
|
|
|
if (timeOfDayStart != '')
|
|
hasTimeOfDayStart = true;
|
|
|
|
if (valueArr[1] == '') {
|
|
validEndDate = new Date(defaultDate + ' ' + valueArr[3]);
|
|
}
|
|
else {
|
|
validEndDate = new Date(valueArr[1] + ' ' + valueArr[3]);
|
|
}
|
|
|
|
timeOfDayEnd = this.getAMPMString(valueArr[3]);
|
|
|
|
if (timeOfDayEnd != '')
|
|
hasTimeOfDayEnd = true;
|
|
}
|
|
else if (valueArr.length == 2) {
|
|
timeOfDayStart = this.getAMPMString(valueArr[0]);
|
|
|
|
if (timeOfDayStart == '') {
|
|
if (valueArr[0] != '') {
|
|
validStartDate = new Date(valueArr[0]);
|
|
hasTimeOfDayStart = true;
|
|
}
|
|
}
|
|
else {
|
|
validStartDate = new Date(defaultDate + ' ' + valueArr[0]);
|
|
hasTimeOfDayStart = true;
|
|
}
|
|
|
|
timeOfDayEnd = this.getAMPMString(valueArr[1]);
|
|
|
|
if (timeOfDayEnd == '') {
|
|
if (valueArr[1] != '') {
|
|
validEndDate = new Date(valueArr[1]);
|
|
hasTimeOfDayEnd = true;
|
|
}
|
|
}
|
|
else {
|
|
validEndDate = new Date(defaultDate + ' ' + valueArr[1]);
|
|
hasTimeOfDayEnd = true;
|
|
}
|
|
}
|
|
|
|
return {
|
|
validStartDate: validStartDate,
|
|
compareStartDate: compareStartDate,
|
|
compareEndDate: compareEndDate,
|
|
hasTimeOfDayStart: hasTimeOfDayStart,
|
|
validEndDate: validEndDate,
|
|
hasTimeOfDayEnd: hasTimeOfDayEnd
|
|
};
|
|
};
|
|
|
|
FieldCondition.prototype.checkDateBetween = function (thisValue, compValue) {
|
|
var checkDateCommonData = this.checkDateCommon(thisValue, compValue);
|
|
|
|
return (checkDateCommonData.validStartDate.getTime() >= checkDateCommonData.compareStartDate.getTime() && checkDateCommonData.validStartDate.getTime() <= checkDateCommonData.compareEndDate.getTime() && checkDateCommonData.hasTimeOfDayStart)
|
|
&& (checkDateCommonData.validEndDate.getTime() <= checkDateCommonData.compareEndDate.getTime() && checkDateCommonData.validEndDate.getTime() >= checkDateCommonData.compareStartDate.getTime() && checkDateCommonData.hasTimeOfDayEnd);
|
|
};
|
|
|
|
FieldCondition.prototype.checkDateEqualSpan = function (thisValue, compValue) {
|
|
var checkDateCommonData = this.checkDateCommon(thisValue, compValue);
|
|
|
|
return (checkDateCommonData.validStartDate.getTime() == checkDateCommonData.compareStartDate.getTime() && checkDateCommonData.hasTimeOfDayStart)
|
|
&& (checkDateCommonData.validEndDate.getTime() == checkDateCommonData.compareEndDate.getTime() && checkDateCommonData.hasTimeOfDayEnd);
|
|
};
|
|
|
|
FieldCondition.prototype.checkDateEqualTo = function (thisValue, compValue) {
|
|
var defaultDate = '1/1/70';
|
|
var defualtDateObj = new Date(defaultDate);
|
|
|
|
var compArr = compValue.split(',');
|
|
var valueArr = thisValue.split(',');
|
|
|
|
var compareDate;
|
|
|
|
var hasTimeOfDay = false;
|
|
|
|
if (compArr[0] == '') {
|
|
compareDate = new Date(defaultDate + ' ' + compArr[2]);
|
|
}
|
|
else {
|
|
compareDate = new Date(compArr[0] + ' ' + compArr[2]);
|
|
}
|
|
|
|
var validDate = new Date(defaultDate);
|
|
var timeOfDay = '';
|
|
|
|
if (valueArr.length == 1) {
|
|
timeOfDay = this.getAMPMString(valueArr[0]);
|
|
|
|
if (timeOfDay == '') {
|
|
if (valueArr[0] != '') {
|
|
validDate = new Date(valueArr[0]);
|
|
hasTimeOfDay = true;
|
|
}
|
|
}
|
|
else {
|
|
hasTimeOfDay = true;
|
|
validDate = new Date(valueArr[0]);
|
|
}
|
|
}
|
|
else if (valueArr.length == 2) {
|
|
timeOfDay = this.getAMPMString(valueArr[1]);
|
|
|
|
if (timeOfDay != '')
|
|
hasTimeOfDay = true;
|
|
|
|
if (valueArr[0] != '') {
|
|
validDate = new Date((valueArr[0] + ' ' + valueArr[1] + ' ').replace(/\-/g, '/'));
|
|
}
|
|
else {
|
|
validDate = new Date((defaultDate + ' ' + valueArr[0] + ' ').replace(/\-/g, '/'));
|
|
}
|
|
}
|
|
|
|
return validDate.getTime() == compareDate.getTime() && hasTimeOfDay;
|
|
};
|
|
|
|
FieldCondition.prototype.getAMPMString = function (time) {
|
|
var amIndex = time.indexOf('AM');
|
|
var pmIndex = time.indexOf('PM');
|
|
|
|
var timeOfDay = '';
|
|
|
|
// First see if the time is military time... if so we need to convert it to AM/PM so the rest
|
|
// of this function will return the proper value.
|
|
|
|
if (amIndex === -1 && pmIndex === -1) {
|
|
time = militaryTimeToStandard(time);
|
|
amIndex = time.indexOf('AM');
|
|
pmIndex = time.indexOf('PM');
|
|
}
|
|
|
|
if (amIndex != -1) {
|
|
timeOfDay = time.substring(amIndex).replace(" ", "");
|
|
}
|
|
else if (pmIndex != -1) {
|
|
timeOfDay = time.substring(pmIndex).replace(" ", "");
|
|
}
|
|
|
|
return timeOfDay;
|
|
};
|
|
|
|
function militaryTimeToStandard(militaryTime) {
|
|
var colonIndex = militaryTime.indexOf(':');
|
|
var hours = '';
|
|
var min = '';
|
|
|
|
if (colonIndex === -1) {
|
|
hours = militaryTime.substring(0, 2);
|
|
min = militaryTime.substring(2, 4);
|
|
} else {
|
|
var tokens = militaryTime.split(':');
|
|
hours = tokens[0];
|
|
min = tokens[1];
|
|
}
|
|
|
|
if (hours < 12) {
|
|
ampm = 'AM';
|
|
} else {
|
|
hours = hours - 12;
|
|
ampm = 'PM';
|
|
}
|
|
|
|
return parseInt(hours) + ':' + ('00' + min).slice('-2') + ' ' + ampm; ß
|
|
}
|
|
|
|
|
|
////////// FieldConditions Class //////////
|
|
|
|
// Creates instance of FieldConditions class.
|
|
// * elemInput - Reference to DOM element of field with condition. May be a DOM element or string containing ID. May also be array of DOM elements or IDs. Multiple elements must share same parent.
|
|
// * id - The ID of the field with the condition.
|
|
// * fieldType - The field type of the field with the condition.
|
|
// * isInternal - Whether or not this condition is for internal-only fields.
|
|
// * condList - List (array) of zero or more condition clauses for the field.
|
|
// * validators - Validator dictionary.
|
|
function FieldConditions(options, validators) {
|
|
if (options.elemInput == null)
|
|
throw new Error.argNull("options.elemInput");
|
|
else if (options.id == null)
|
|
throw new Error.argNull("id");
|
|
else if (options.fieldType == null)
|
|
throw new Error.argNull("options.fieldType");
|
|
else if (options.condList == null)
|
|
throw new Error.argNull("options.condList");
|
|
else if (validators == null)
|
|
throw new Error.argNull("validators");
|
|
|
|
this.elemInputIsArray = $.isArray(options.elemInput);
|
|
|
|
// Process elemInput argument.
|
|
if (this.elemInputIsArray) {
|
|
for (var i = 0, len = options.elemInput.length; i < len; i++) {
|
|
if (typeof (options.elemInput[i]) == "string")
|
|
options.elemInput[i] = document.getElementById(options.elemInput[i]);
|
|
}
|
|
|
|
if (options.elemInput.length > 0 && options.elemInput[0]) {
|
|
this.elemContainer = options.elemInput[0].closest('.formFieldContainer');
|
|
this.elemInput = options.elemInput;
|
|
}
|
|
}
|
|
else {
|
|
if (typeof (options.elemInput) == "string")
|
|
options.elemInput = document.getElementById(options.elemInput);
|
|
|
|
if (options.elemInput) {
|
|
this.elemContainer = options.elemInput.closest('.formFieldContainer');
|
|
this.elemInput = options.elemInput;
|
|
}
|
|
}
|
|
|
|
this.validators = validators;
|
|
this.elemReq = document.getElementById('r_' + options.id);
|
|
this.$elemContainer = $(this.elemContainer);
|
|
this.$elemReq = $(this.elemReq);
|
|
this.fieldType = options.fieldType;
|
|
this.id = options.id;
|
|
this.isInternal = options.isInternal;
|
|
this.conditions = FieldCondition.createMulti(this, options.condList);
|
|
}
|
|
|
|
// Static. Creates a single conditions object from an options object.
|
|
FieldConditions.createSingle = function (options, validators) {
|
|
if (options == null)
|
|
throw new Error.argNull("options");
|
|
else if (validators == null)
|
|
throw new Error.argNull("validators");
|
|
|
|
return new FieldConditions(
|
|
options,
|
|
validators);
|
|
};
|
|
|
|
// Static. Creates dictionary of conditions objects from array of option objects.
|
|
FieldConditions.createMulti = function (optionsArray, validators) {
|
|
if (optionsArray == null)
|
|
throw new Error.argNull("optionsArray");
|
|
else if (validators == null)
|
|
throw new Error.argNull("validators");
|
|
|
|
var ret = { keys: [] };
|
|
var key = null;
|
|
|
|
for (var i = 0, len = optionsArray.length; i < len; i++) {
|
|
if (optionsArray[i].id != null) {
|
|
key = optionsArray[i].id;
|
|
ret[key] = FieldConditions.createSingle(optionsArray[i], validators);
|
|
ret.keys.push(key);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
// Attachs event handler to field to monitor changes.
|
|
// * condRunner - FieldConditionsRunner instance to attach.
|
|
// Note: Calling more than once will have no effect.
|
|
FieldConditions.prototype.attachRunner = function (condRunner) {
|
|
if (condRunner == null)
|
|
throw new Error.argNull("condRunner");
|
|
|
|
for (var i = 0, len = this.conditions.length; i < len; i++)
|
|
this.conditions[i].attachRunner(condRunner);
|
|
};
|
|
|
|
// Removes event handler that monitors changes.
|
|
// Note: Calling more than once will have no effect.
|
|
FieldConditions.prototype.detachRunner = function () {
|
|
for (var i = 0, len = this.conditions.length; i < len; i++)
|
|
this.conditions[i].detachRunner();
|
|
};
|
|
|
|
////////// FieldConditionsRunner Class ////
|
|
|
|
// Creates new instance of conditions runners for the field conditions objects provided.
|
|
// * allFieldConditions - Array of FieldConditions objects to execute checks for.
|
|
// * doneCallback - Method executed when run() completes. Recieves log information as argument.
|
|
// * autoAttach - Determines if allFieldConditions are automatically attached to this instance by the constructor. If null/unspecified, treated as true.
|
|
// * runInternal - Set to true to execute internal-only fields.
|
|
function FieldConditionsRunner(allFieldConditions, doneCallback, autoAttach, runInternal) {
|
|
if (allFieldConditions == null)
|
|
throw new Error.argNull("allFieldConditions");
|
|
else if (doneCallback == null)
|
|
throw new Error.argNull("doneCallback");
|
|
|
|
this.fieldConditions = allFieldConditions;
|
|
this.doneCallback = doneCallback;
|
|
this.runInternal = runInternal;
|
|
|
|
if (autoAttach == null || autoAttach)
|
|
this.attachConditions();
|
|
}
|
|
|
|
// Static. Internal. Creates static information object for state tracking during execution.
|
|
FieldConditionsRunner.createFieldStateInfo = function () {
|
|
var ret = {};
|
|
|
|
ret[ConditionActions.None] = ConditionRunnerActResult.None;
|
|
ret[ConditionActions.Show] = ConditionRunnerActResult.None;
|
|
ret[ConditionActions.Hide] = ConditionRunnerActResult.None;
|
|
ret[ConditionActions.Require] = ConditionRunnerActResult.None;
|
|
ret[ConditionActions.RedirectTo] = ConditionRunnerActResult.None;
|
|
|
|
return ret;
|
|
};
|
|
|
|
// Attaches to FieldConditions/FieldCondition objects that runner will use.
|
|
FieldConditionsRunner.prototype.attachConditions = function () {
|
|
for (var i = 0, iLen = this.fieldConditions.keys.length; i < iLen; i++)
|
|
this.fieldConditions[this.fieldConditions.keys[i]].attachRunner(this);
|
|
};
|
|
|
|
// Detaches to FieldConditions/FieldCondition objects that runner may have used.
|
|
FieldConditionsRunner.prototype.detachConditions = function () {
|
|
for (var i = 0, iLen = this.fieldConditions.keys.length; i < iLen; i++)
|
|
this.fieldConditions[this.fieldConditions.keys[i]].detachRunner(this);
|
|
};
|
|
|
|
// Internal. Cleans up runner for use again.
|
|
FieldConditionsRunner.prototype.cleanup = function () {
|
|
if (this.fieldConditionResults != null) {
|
|
delete this.fieldConditionResults;
|
|
delete this.fieldConditionLog;
|
|
}
|
|
};
|
|
|
|
// Internal. Called by run() to log result for each condition.
|
|
FieldConditionsRunner.prototype.log = function (id, condIndex, actType, result, isMet, needRestart) {
|
|
if (condRunnerHideLogDupes && result == ConditionRunnerActResult.SkipDuplicate)
|
|
return;
|
|
|
|
this.fieldConditionLog.push({
|
|
id: id,
|
|
condIndex: condIndex,
|
|
actType: actType,
|
|
result: result,
|
|
isMet: isMet,
|
|
needRestart: needRestart
|
|
});
|
|
};
|
|
|
|
// Internal. Sets whether or not the condition engine is executing.
|
|
FieldConditionsRunner.prototype.setRunning = function (value) {
|
|
if (arguments.length == 0)
|
|
this.isRunning = true;
|
|
else
|
|
this.isRunning = value;
|
|
};
|
|
|
|
// Gets whether or not the condition engine is executing.
|
|
FieldConditionsRunner.prototype.getRunning = function () {
|
|
return this.isRunning;
|
|
};
|
|
|
|
// Internal. Tells condition execution task to reset cycle (done whenever something changes).
|
|
FieldConditionsRunner.prototype.setRestart = function (value) {
|
|
if (arguments == null || arguments.length == 0)
|
|
this.needRestart = true;
|
|
else
|
|
this.needRestart = value;
|
|
};
|
|
|
|
// Internal. Gets whether or not the runner needs to restart.
|
|
FieldConditionsRunner.prototype.getRestart = function () {
|
|
return this.needRestart;
|
|
};
|
|
|
|
// Launches execution of conditions.
|
|
// * fromEvent - Should be set to true when triggerd from DOM events.
|
|
// NOTE: fromEvent may be a race condition but will be left for now while debugging (to simplify logs).
|
|
FieldConditionsRunner.prototype.run = function (fromEvent) {
|
|
if (this.getRunning() && !fromEvent)
|
|
this.setRestart();
|
|
else {
|
|
this.setRunning();
|
|
|
|
this.cleanup();
|
|
|
|
this.runTask();
|
|
|
|
this.doneCallback(this.fieldConditionLog);
|
|
|
|
this.setRunning(false);
|
|
}
|
|
};
|
|
|
|
// Internal. Executes conditions. Should not be called while already running, so run() has sync mechanism for this.
|
|
// * runInternal - If true, conditions for internal conditions will be ran.
|
|
FieldConditionsRunner.prototype.runTask = function (runInternal) {
|
|
var needRestart = true;
|
|
|
|
// Prepare objects for execution.
|
|
this.fieldConditionLog = [];
|
|
this.fieldConditionResults = [];
|
|
this.setRedirectUrl = false;
|
|
|
|
// Populate state information.
|
|
var condCondList = this.fieldConditions;
|
|
var condListInfo = null;
|
|
var condList = null;
|
|
|
|
for (var i = 0, iLen = condCondList.keys.length; i < iLen; i++)
|
|
this.fieldConditionResults[condCondList[condCondList.keys[i]].id] = FieldConditionsRunner.createFieldStateInfo();
|
|
|
|
// Number of restart actions (tracked to eventually kill infinite loops that should not happen).
|
|
var numRestarts = 0;
|
|
|
|
// Start/restart actions.
|
|
while (needRestart && (++numRestarts < 65535)) {
|
|
needRestart = false;
|
|
this.setRestart(needRestart);
|
|
|
|
for (var i = 0, iLen = condCondList.keys.length; i < iLen && !needRestart; i++) {
|
|
condListInfo = condCondList[condCondList.keys[i]];
|
|
|
|
// If we are on the front-end, we don't want to have anything to do with back-end (internal only)
|
|
// conditions, they will cause javascript errors.
|
|
if (!this.runInternal && condListInfo.isInternal == true)
|
|
continue;
|
|
|
|
if (condListInfo.isInternal == false && document.URL.indexOf("Admin") > -1 && document.URL.indexOf("Submissions") > -1)
|
|
continue;
|
|
|
|
condList = condListInfo.conditions;
|
|
|
|
for (var j = 0, jLen = condList.length; j < jLen && !needRestart; j++) {
|
|
var cond = condList[j];
|
|
var results = this.fieldConditionResults[condListInfo.id];
|
|
var logState = ConditionRunnerActResult.None;
|
|
|
|
// Determine whether or not condition is met.
|
|
var isMet = cond.check(false);
|
|
|
|
// This is because the effective action for a failed explicit Show is an implicit Hide (and vice versa).
|
|
var effectiveActType = cond.actType;
|
|
|
|
// Determine if action is contradictory or duplicate and skip UI changes if so.
|
|
switch (effectiveActType) {
|
|
case ConditionActions.Show:
|
|
// Show can collide with hide.
|
|
var resultsHide = results[ConditionActions.Hide];
|
|
|
|
if (resultsHide == ConditionRunnerActResult.SuccessExplicit || (resultsHide == ConditionRunnerActResult.SuccessImplicit && !isMet))
|
|
logState = ConditionRunnerActResult.SkipContradiction;
|
|
|
|
break;
|
|
case ConditionActions.Hide:
|
|
// Hide can collide with show.
|
|
var resultsShow = results[ConditionActions.Show];
|
|
|
|
if (resultsShow == ConditionRunnerActResult.SuccessExplicit || (resultsShow == ConditionRunnerActResult.SuccessImplicit && !isMet))
|
|
logState = ConditionRunnerActResult.SkipContradiction;
|
|
|
|
break;
|
|
case ConditionActions.RedirectTo:
|
|
// Redirects work differently since they span all fields. Extra contradiction detection needed.
|
|
if (this.setRedirectUrl)
|
|
logState = ConditionRunnerActResult.SkipContradiction;
|
|
else if (isMet)
|
|
this.setRedirectUrl = true;
|
|
break;
|
|
}
|
|
|
|
if (isMet && results[effectiveActType] == ConditionRunnerActResult.SuccessExplicit)
|
|
logState = ConditionRunnerActResult.SkipDuplicate;
|
|
else if (!isMet && results[effectiveActType] == ConditionRunnerActResult.SuccessExplicit)
|
|
logState = ConditionRunnerActResult.SkipContradiction;
|
|
else if (!isMet && results[effectiveActType] == ConditionRunnerActResult.SuccessImplicit)
|
|
logState = ConditionRunnerActResult.SkipDuplicate;
|
|
|
|
if (logState == ConditionRunnerActResult.None) {
|
|
// Determine log result.
|
|
logState = isMet ? ConditionRunnerActResult.SuccessExplicit : ConditionRunnerActResult.SuccessImplicit;
|
|
|
|
// Update running state info.
|
|
results[effectiveActType] = logState;
|
|
|
|
// Update form UI.
|
|
cond.doAction(isMet);
|
|
|
|
// Restart task.
|
|
this.setRestart();
|
|
needRestart = true;
|
|
}
|
|
|
|
// Log result.
|
|
this.log(condListInfo.id, j, cond.actType, logState, isMet, needRestart);
|
|
|
|
// Some other action could cause this to get set.
|
|
if (this.getRestart())
|
|
needRestart = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (numRestarts >= 65535)
|
|
console[console.warn ? "warn" : "log"]("Infinite Loop (heuristic-detected) in FieldConditionsRunner.runTask()");
|
|
};
|
|
;
|
|
// This file contains javascript functions for the "External Integration" field type.
|
|
// REQUIREMENTS:
|
|
// FieldSetDesigner.js
|
|
|
|
// These values must match the values provided in CivicPlus.Entities.Modules.FormCenter.Enums.ExternalIntegrationCommandType
|
|
var ExternalIntegrationCommandType = {
|
|
XMLCommand: 1,
|
|
EchoCommand: 2
|
|
};
|
|
|
|
// Closure containing the client-side functionality for the External Integration field type.
|
|
// * externalIntegrationClass - The name of the CSS class that is used to identify external integration buttons.
|
|
function ExternalIntegration(externalIntegrationClassname, fieldSetDesigner) {
|
|
this.cssClassname = externalIntegrationClassname;
|
|
this.fieldSetDesigner = fieldSetDesigner;
|
|
|
|
this.hookEvents = function () {
|
|
var my = this;
|
|
if (my.cssClassname == null)
|
|
throw 'No external integration button CSS class name has been specified.'
|
|
|
|
$('.' + this.cssClassname).click(function (event) {
|
|
var fieldID = null;
|
|
fieldID = event.target.id;
|
|
my.sendRequest(fieldID);
|
|
});
|
|
};
|
|
|
|
this.sendRequest = function (fieldID) {
|
|
var params = this.getFormData();
|
|
var formID = $('#Item_FormID').val();
|
|
var intFieldID = fieldID.replace('e_', '');
|
|
|
|
var my = this;
|
|
var sendData = {
|
|
id: formID,
|
|
fieldID: intFieldID,
|
|
parameters: JSON.stringify(params)
|
|
};
|
|
|
|
$.ajax({
|
|
type: 'post',
|
|
url: '/FormCenter/ExecuteExternalIntegrationCommand',
|
|
data: sendData,
|
|
success: function (data) { my.updateFormData(data, my); },
|
|
error: function (xhr, status, error) { alert('An error occurred while sending the request.'); },
|
|
beforeSend: function () {
|
|
ajaxPostBackStart('Loading');
|
|
},
|
|
complete: function () {
|
|
ajaxPostBackEnd();
|
|
}
|
|
});
|
|
};
|
|
|
|
// This function takes the values from the JSON result and sets the appropriate
|
|
// form field values.
|
|
this.updateFormData = function (responseFromController, externalIntegrationObject) {
|
|
|
|
if (responseFromController.error) {
|
|
alert('An error occurred: ' + responseFromController.errorMessage);
|
|
return;
|
|
}
|
|
|
|
for (var i = 0, len = responseFromController.length; i < len; i++) {
|
|
var param = responseFromController[i];
|
|
switch (responseFromController[i].Type) {
|
|
case FieldTypes.ShortAnswer:
|
|
externalIntegrationObject.updateShortAnswerField(param);
|
|
break;
|
|
case FieldTypes.LongAnswer:
|
|
externalIntegrationObject.updateLongAnswerField(param);
|
|
break;
|
|
case FieldTypes.Checkboxes:
|
|
externalIntegrationObject.updateCheckboxField(param);
|
|
break;
|
|
case FieldTypes.Dropdown:
|
|
externalIntegrationObject.updateDropdownField(param);
|
|
break;
|
|
case FieldTypes.Password:
|
|
externalIntegrationObject.updatePasswordField(param);
|
|
break;
|
|
case FieldTypes.RadioButtons:
|
|
externalIntegrationObject.updateRadioField(param);
|
|
break;
|
|
case FieldTypes.DateTime:
|
|
externalIntegrationObject.updateDateField(param);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.getFormData = function () {
|
|
var params = [];
|
|
|
|
this.appendShortAnswerFields(params);
|
|
this.appendCheckboxFields(params);
|
|
this.appendRadioFields(params);
|
|
this.appendDropdowns(params);
|
|
this.appendTextAreaFields(params);
|
|
this.appendPasswordFields(params);
|
|
|
|
return params;
|
|
};
|
|
|
|
this.createFieldValue = function (fieldID, type, value, externalName) {
|
|
return { ID: fieldID, Type: type, Value: value, ExternalName: externalName};
|
|
};
|
|
|
|
this.appendShortAnswerFields = function (params) {
|
|
var my = this;
|
|
$('input[id^="e_"][type="text"]').each(function (i) {
|
|
var element = $(this);
|
|
params.push(my.createFieldValue(element.attr('id'), FieldTypes.ShortAnswer, element.val(), my.externalSubmissionName(element)));
|
|
});
|
|
};
|
|
|
|
this.externalSubmissionName = function($element) {
|
|
return $element.parents('*[data-external-submission-name]').attr('data-external-submission-name');
|
|
};
|
|
|
|
this.updateShortAnswerField = function (param) {
|
|
var id = param.ID;
|
|
$('#' + param.ID).val(param.Value);
|
|
}
|
|
|
|
this.appendCheckboxFields = function (params) {
|
|
var my = this;
|
|
$('input[id^="e_"][type="checkbox"]').each(function (index) {
|
|
var item = $(this);
|
|
var value = item.attr('value');
|
|
var checked = false;
|
|
if (item.is(':checked')) {
|
|
checked = true;
|
|
}
|
|
var fieldValue = my.createFieldValue(item.attr('id'), FieldTypes.Checkboxes, value, my.externalSubmissionName(item));
|
|
fieldValue.Checked = checked;
|
|
params.push(fieldValue);
|
|
});
|
|
};
|
|
|
|
this.updateCheckboxField = function (param) {
|
|
var id = param.ID;
|
|
if (param.Checked == true)
|
|
$('#' + param.ID).attr('checked', true);
|
|
else
|
|
$('#' + param.ID).attr('checked', false);
|
|
};
|
|
|
|
this.appendRadioFields = function (params) {
|
|
var my = this;
|
|
$('input[id^="e_"][type="radio"]').each(function (index) {
|
|
var item = $(this);
|
|
var value = item.attr('value');
|
|
var checked = false;
|
|
if (item.is(':checked')) {
|
|
checked = true;
|
|
}
|
|
var fieldValue = my.createFieldValue(item.attr('id'), FieldTypes.RadioButtons, value, my.externalSubmissionName(item));
|
|
fieldValue.Checked = checked;
|
|
|
|
params.push(fieldValue);
|
|
});
|
|
};
|
|
|
|
this.updateRadioField = function (param) {
|
|
var id = param.ID;
|
|
var value = param.Value;
|
|
var button = $('input[id^="' + id + '"][value="' + value + '"]');
|
|
button.attr('checked', 'checked');
|
|
};
|
|
|
|
this.appendDropdowns = function (params) {
|
|
var my = this;
|
|
$('select[id^="e_"]').each(function (index) {
|
|
var item = $(this);
|
|
params.push(my.createFieldValue(item.attr('id'), FieldTypes.Dropdown, item.val(), my.externalSubmissionName(item)));
|
|
});
|
|
};
|
|
|
|
this.updateDropdownField = function (param) {
|
|
$('#' + param.ID).val(param.Value);
|
|
}
|
|
|
|
this.appendTextAreaFields = function (params) {
|
|
var my = this;
|
|
$('textarea[id^="e_"]').each(function (index) {
|
|
var element = $(this);
|
|
|
|
if (element.closest('li.LongAnswer').length > 0) {
|
|
params.push(my.createFieldValue(element.attr('id'), FieldTypes.LongAnswer, element.text(), my.externalSubmissionName(element)));
|
|
}
|
|
});
|
|
};
|
|
|
|
this.updateLongAnswerField = function (param) {
|
|
$('#' + param.ID).text(param.Value);
|
|
}
|
|
|
|
this.appendPasswordFields = function (params) {
|
|
var my = this;
|
|
$('input[id^="e_"][type="password"').each(function (i) {
|
|
var element = $(this);
|
|
params.push(my.createFieldValue(element.attr('id'), FieldTypes.Password, element.val(), my.externalSubmissionName(element)));
|
|
});
|
|
}
|
|
|
|
this.updatePasswordField = function (param) {
|
|
// We don't want to update password information with values returned from the remote service.
|
|
return;
|
|
}
|
|
|
|
this.updateDateField = function (param) {
|
|
var my = this;
|
|
var isSpan = (param.Value.indexOf(',') >= 0);
|
|
|
|
var dateID = param.ID + '_date';
|
|
var timeID = param.ID + '_time';
|
|
var endDateID = param.ID + '_dateSpan';
|
|
var endTimeID = param.ID + '_timeSpan';
|
|
|
|
var updateDate = function (selector, val) {
|
|
var datePicker = $('#' + selector);
|
|
if (datePicker.length == 0)
|
|
return;
|
|
|
|
datePicker.data('tDatePicker').value(val);
|
|
};
|
|
|
|
var updateTime = function (selector, val) {
|
|
var timePicker = $('#' + selector);
|
|
if (timePicker.length == 0)
|
|
return;
|
|
timePicker.data('tTimePicker').value(val);
|
|
};
|
|
|
|
if (isSpan) {
|
|
var dateArray = param.Value.split(',');
|
|
var startDate = new Date(dateArray[0]);
|
|
var endDate = new Date(dateArray[1]);
|
|
|
|
updateDate(dateID, startDate);
|
|
updateTime(timeID, startDate);
|
|
|
|
updateDate(endDateID, endDate);
|
|
updateTime(endTimeID, endDate);
|
|
} else {
|
|
var startDate = new Date(param.Value);
|
|
updateDate(dateID, startDate);
|
|
updateTime(timeID, startDate);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Calls subroutines used to initialize the ExternalIntegration javascript object.
|
|
ExternalIntegration.prototype.initialize = function () {
|
|
this.hookEvents();
|
|
};
|
|
|
|
var CP_DynamicForm_ExternalSubmissionFE = function($) {
|
|
|
|
var self = this;
|
|
|
|
|
|
self.getExternalSubmissionData = function() {
|
|
var $fieldContainers = $('.formFieldContainer');
|
|
var data = {};
|
|
$fieldContainers.each(function (index) {
|
|
var $container = $(this);
|
|
var externalSubmissionName = self.getExternalSubmissionName($container);
|
|
var singleFieldData = self.getSingleFieldData($container);
|
|
if (singleFieldData != null) {
|
|
data[externalSubmissionName] = self.getSingleFieldData($container);
|
|
}
|
|
});
|
|
return data;
|
|
};
|
|
|
|
self.getExternalSubmissionName = function($container) {
|
|
return $container.attr('data-external-submission-name');
|
|
};
|
|
|
|
self.getSingleFieldData = function($container) {
|
|
var self = this;
|
|
var result = null;
|
|
if ($container.hasClass('ShortAnswer')) {
|
|
result = self.submissionDataShortAnswer($container);
|
|
} else if ($container.hasClass('LongAnswer')) {
|
|
result = self.submissionDataLongAnswer($container);
|
|
} else if ($container.hasClass('Checkboxes')) {
|
|
result = self.submissionDataCheckboxes($container);
|
|
} else if ($container.hasClass('Dropdown')) {
|
|
result = self.submissionDataDropdown($container);
|
|
} else if ($container.hasClass('RadioButtons')) {
|
|
result = self.submissionDataRadioButtons($container);
|
|
} else if ($container.hasClass('ReplyEmail')) {
|
|
result = self.submissionDataReplyEmail($container);
|
|
} else if ($container.hasClass('DateTime')) {
|
|
result = self.submissionDataDateTime($container);
|
|
} else if ($container.hasClass('DateTimeSpan')) {
|
|
result = self.submissionDataDateTimeSpan($container);
|
|
} else if ($container.hasClass('Password')) {
|
|
result = self.submissionDataPassword($container);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
//
|
|
// There needs to be one function for each type of field that will be passed to
|
|
// an external submission service.
|
|
//
|
|
|
|
self.submissionDataShortAnswer = function($container) {
|
|
return $('input[id^=e_]', $container).val();
|
|
};
|
|
|
|
self.submissionDataLongAnswer = function($container) {
|
|
return $('textarea', $container).html();
|
|
};
|
|
|
|
self.submissionDataPassword = function($container) {
|
|
return $('input[id^=e_]', $container).val();
|
|
};
|
|
|
|
self.submissionDataCheckboxes = function($container) {
|
|
var result = [];
|
|
var $checkedItems = $('input[type=checkbox]:checked', $container);
|
|
$checkedItems.each(function (index) {
|
|
result.push($(this).attr('Value'));
|
|
});
|
|
return result.join();
|
|
};
|
|
|
|
self.submissionDataDropdown = function($container) {
|
|
return $('select option:selected').val();
|
|
};
|
|
|
|
self.submissionDataRadioButtons = function($container) {
|
|
return $('input:radio:checked', $container).val();
|
|
};
|
|
|
|
self.submissionDataReplyEmail = function($container) {
|
|
return $('input[id^=e_]', $container).val();
|
|
};
|
|
|
|
self.isDateTimeValueEmpty = function(val) {
|
|
// The telerik controls sometimes have just "0" if the user does not
|
|
// enter a value, so this function checks for both an empty value and for "0"
|
|
if (val == null || val == '' || val == '0')
|
|
return true;
|
|
else
|
|
return false;
|
|
};
|
|
|
|
self.submissionDataDateTime = function($container) {
|
|
var $dateDiv = $('div.date', $container).not('.time')[0];
|
|
var $timeDiv = $('div.time', $container)[0];
|
|
|
|
var date = $('input', $dateDiv).val();
|
|
var time = $('input', $timeDiv).val();
|
|
|
|
return formatDateTime(date, time);
|
|
};
|
|
|
|
self.formatDateTime = function(date, time) {
|
|
var dateEmpty = isDateTimeValueEmpty(date);
|
|
var timeEmpty = isDateTimeValueEmpty(time);
|
|
|
|
if (dateEmpty && timeEmpty)
|
|
return '';
|
|
else if (!dateEmpty && timeEmpty)
|
|
return date;
|
|
else if (dateEmpty && !timeEmpty)
|
|
return time;
|
|
else
|
|
return date + ' ' + time;
|
|
}
|
|
|
|
self.submissionDataDateTimeSpan = function($container) {
|
|
var $startDateDiv = $('div.date', $container).not('.time')[0];
|
|
var $startTimeDiv = $('div.date.time', $container)[0];
|
|
var startDate = $('input', $startDateDiv).val();
|
|
var startTime = $('input', $startTimeDiv).val();
|
|
|
|
var $endDateDiv = $('div.date', $container).not('.time')[1];
|
|
var $endTimeDiv = $('div.date.time', $container)[1];
|
|
var endDate = $('input', $endDateDiv).val();
|
|
var endTime = $('input', $endTimeDiv).val();
|
|
|
|
var startDateTime = formatDateTime(startDate, startTime);
|
|
var endDateTime = formatDateTime(endDate, endTime);
|
|
|
|
if (startDateTime == '' && endDateTime == '')
|
|
return '';
|
|
|
|
return startDateTime + ',' + endDateTime;
|
|
};
|
|
|
|
|
|
return self;
|
|
}(jQuery);
|
|
|
|
|
|
var CP_DynamicForm_PrintSubmission = (function () {
|
|
self.StatusCodes = {
|
|
Loading: 1,
|
|
Success: 2,
|
|
Spam: 3,
|
|
Timeout: 4
|
|
};
|
|
|
|
return self;
|
|
})();
|
|
/// <reference path="../../../../Assets/Scripts/FrontEnd.js" />
|
|
/// <reference path="../../../../Assets/Scripts/Authentication/PopupBasedAuthentication.js" />
|
|
/// <reference path="../../../../Assets/Scripts/Store.js" />
|
|
/// <reference path="../../../../Assets/Scripts/Authentication/Authentication.js" />
|
|
/// <reference path="../../../../Assets/Scripts/Shared.js" />
|
|
|
|
window.FormCenter = window.FormCenter || {};
|
|
|
|
function SaveProgressClass() {
|
|
var url;
|
|
}
|
|
|
|
if (!window.FormCenter.SaveProgress) {
|
|
window.FormCenter.SaveProgress = new SaveProgressClass();
|
|
}
|
|
|
|
SaveProgressClass.prototype.checkLoggedInStatus = function (event) {
|
|
if (event != null) {
|
|
event.preventDefault();
|
|
}
|
|
|
|
submitCheckboxHandler();
|
|
submitRadioHandler();
|
|
submitDateTimeHandler();
|
|
|
|
if ($('[type="file"]').length > 0) {
|
|
alert($('#hdnFileUploadWarning').val());
|
|
}
|
|
|
|
var $form = $(document.aspnetForm);
|
|
|
|
window.FormCenter.SaveProgress.url = null;
|
|
|
|
window.FormCenter.SaveProgress.url = $(this).attr('href');
|
|
|
|
var savedProgressID = $('#hdnSavedProgressID').val();
|
|
|
|
var postUrl = '/FormCenter/Home/SaveProgress?formID=' + $('#hdnFormID').val();
|
|
|
|
if (savedProgressID != null) {
|
|
postUrl = postUrl + '&savedProgressID=' + savedProgressID;
|
|
}
|
|
|
|
$.ajax({
|
|
url: postUrl,
|
|
type: 'POST',
|
|
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
data: $(document.aspnetForm).serializeArray(),
|
|
success: FormCenter.SaveProgress.savePostCallback,
|
|
async: false,
|
|
beforeSend: function () {
|
|
ajaxPostBackStart('Loading');
|
|
},
|
|
complete: function () {
|
|
ajaxPostBackEnd();
|
|
},
|
|
error: function (xhr, textStatus, exception) {
|
|
alert('Error: ' + xhr.statusText + '\nStatus: ' + xhr.status);
|
|
}
|
|
});
|
|
};
|
|
|
|
SaveProgressClass.prototype.savePostCallback = function(response) {
|
|
if (response.Successful) {
|
|
if (response.LoggedIn) {
|
|
if (response.RedirectUrl != null) {
|
|
window.FormCenter.SaveProgress.setStorageToShowMessage();
|
|
|
|
window.location = response.RedirectUrl;
|
|
}
|
|
else {
|
|
alert(response.Message);
|
|
}
|
|
}
|
|
else {
|
|
window.FormCenter.SaveProgress.setStorageToShowMessage();
|
|
window.FormCenter.SaveProgress.url = window.FormCenter.SaveProgress.url + '?savedProgressKey=' + response.Key;
|
|
if (response.IsSamlLoginEnabled) {
|
|
window.location = '/Admin/Saml/LogonRequest?RelayState=' + window.FormCenter.SaveProgress.url.substring(1);
|
|
}
|
|
else {
|
|
popupSignIn(encodeURI(window.FormCenter.SaveProgress.url), '', FormCenter.SaveProgress.checkLoggedInStatusCallBack);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
alert(response.Message);
|
|
if (response.hasOwnProperty('FormUnavailable') && response.FormUnavailable)
|
|
{
|
|
window.location.href = '/FormCenter';
|
|
}
|
|
}
|
|
};
|
|
|
|
SaveProgressClass.prototype.setStorageToShowMessage = function () {
|
|
$.jStorage.set("showSavedMessage" + $('#hdnFormID').val(), true);
|
|
};
|
|
|
|
SaveProgressClass.prototype.checkLoggedInStatusCallBack = function () {
|
|
|
|
};
|
|
|
|
SaveProgressClass.prototype.deleteProgress = function (event) {
|
|
event.preventDefault();
|
|
|
|
var postUrl = '/FormCenter/Home/DeleteSaveProgress?savedProgressID=' + $(this).attr('data-progressID');
|
|
|
|
AJAX(postUrl, 'POST', null, FormCenter.SaveProgress.deleteProgressCallback, true, null, true);
|
|
};
|
|
|
|
SaveProgressClass.prototype.deleteProgressCallback = function(response) {
|
|
if (response.Successful) {
|
|
$('#savedProgressTr' + response.SavedProgressID).remove();
|
|
}
|
|
};
|
|
|
|
SaveProgressClass.prototype.init = function () {
|
|
if ($.jStorage != null) {
|
|
$('#saveFormProgress').unbind().bind({
|
|
click: FormCenter.SaveProgress.checkLoggedInStatus
|
|
});
|
|
|
|
$('.modern-button.deleteSavedProgress').unbind().bind({
|
|
click: FormCenter.SaveProgress.deleteProgress
|
|
});
|
|
|
|
var storageKey = "showSavedMessage" + $('#hdnFormID').val();
|
|
|
|
var showSavedMessage = $.jStorage.get(storageKey, false);
|
|
|
|
if (showSavedMessage && window.location.search.indexOf("savedProgressID") > 0) {
|
|
$.jStorage.deleteKey(storageKey);
|
|
|
|
if (window.location.search.indexOf("savedProgressID=-1") == -1) {
|
|
alert($('#hdnSavedProgressMessage').val());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
$(document).ready(FormCenter.SaveProgress.init);
|
|
window.pageHandleResponsive = true;
|
|
|
|
$.when(window.Pages.rwdReady).done(function () {
|
|
|
|
toggleClassMedia("maxWidth600px", ".cpForm:media(this-max-width: 600px)");
|
|
toggleClassMedia("maxWidth515px", "#FormCenterContent:media(this-max-width: 515px)");
|
|
toggleClassMedia("maxWidth485px", "#FormCenterContent:media(this-max-width: 485px)");
|
|
toggleClassMedia("maxWidth440px", ".cpForm:media(this-max-width: 440px)");
|
|
toggleClassMedia("maxWidth395px", "#FormCenterContent:media(this-max-width: 395px)");
|
|
toggleClassMedia("maxWidth380px", ".cpForm:media(this-max-width: 380px)");
|
|
});
|
|
|