// MISC. FUNCTIONS NEEDED FOR VALIDATION function getJSFormValidationVersion() { //returns the validation version for the form (defaults to 5, can be changed via shopOnLoad()) var v = getDocObject('jsFormValidationVersion'); if (!v) return(1); return(mParseFloat(v.value)); } function setJSFormValidationVersion(newVersion) { var v = getDocObject('jsFormValidationVersion'); if (v) v.value = newVersion; } function isIDForQuestion(questionID) { return (questionID.substring(0,2) == "Q_"); } function isStringNonWhitespace(s) { for (var i = 0; i < s.length ; i++) { var c = s.charAt(i); if ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r')) return true; } return false; } //returns the number of non-whitespace answers for a multi-input value function getMultiInputNumNonBlankAnswers(inputName) { var a = getMultiInputValues(inputName); var c = 0; for (var i = 0; i < a.length; i++) { if (isStringNonWhitespace(a[i])) c++; } return(c); } function isInputBlank(inputName) { if (getInputElement(inputName) == null) return false; var s = getInputElement(inputName).value; return(!isStringNonWhitespace(s)); /* for (var i = 0; i < s.length ; i++) { var c = s.charAt(i); if ((c != ' ') && (c != '\t') && (c != '\n')) return false; } return true; */ } //Returns TRUE if the passed string appears to be a valid e-mail address function isEmailAddressValid (passedEmail) { var a = (!(String(passedEmail)).search(/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.mil)|(\.biz)|(\.gov)|(\.org)|(\.int)|(\.info)|(\.name)|(\.coop)|(\..{2,2}))$)\b/gi)); //general validity var b = (String(passedEmail).indexOf('@') == String(passedEmail).lastIndexOf('@')); //only one @ var c = (String(passedEmail) == fullTrimString(passedEmail)); //no whitespace return(a && b && c); } //Returns TRUE if the given input's value looks like a valid US or MX postal code function isInputAValidUSPostalCode(inputName) { var s = new String(getInputValue(inputName)); return(!s.search(/^\d{5}$/)); } //Returns TRUE if the given input's value looks like a valid Canadian postal code function isInputAValidCAPostalCode(inputName) { var s = new String(getInputValue(inputName)); var s1 = !s.search(/^[A-Z]\d[A-Z]\s\d[A-Z]\d/); var s2 = !s.search(/^[A-Z]\d[A-Z]/); return(s1 || s2); } //Returns TRUE if the given input's value looks like a valid MSPA shopper certificate number (6 lowercase alpha/numeric characters) function isInputAValidMSPACertificateNumber(inputName){ var s = new String(getInputValue(inputName)); return(!s.search(/[a-z0-9]{6}/) && s.length == 6); } //Returns TRUE if the passed string is a valid number according to the prophetSampleEntryNumber field function isStringAValidNumber(value) { //variables var thenumber; //grab the prophetSampleFormatEntryDate value on the page to check against var prophetSampleFormatEntryNumber = document.getElementById("prophetSampleFormatEntryNumber"); if (prophetSampleFormatEntryNumber == null) {alert("Warning: prophetSampleFormatEntryNumber object not found. \n\n Validation cannot continue.");return false;} var s = new String(prophetSampleFormatEntryNumber.value); // var s = "ii.fff"; //Step 1 determine our delimiter var strDelimiter; strDelimiter = s.replace(/i/g,""); strDelimiter = strDelimiter.replace(/f/g,""); //Step 2 grab the value and start checking it... var st = new String(value); if(st=='')return false; var usedDecimal = false; for (i = 0; i < st.length; i++) { var theChar = st.slice(i, i+1); if (!((theChar >= "0" && theChar <= "9") || (theChar ==strDelimiter && !usedDecimal) || (theChar == "-" && i == 0))) return(false); if (theChar == strDelimiter) usedDecimal = true; } return(true); } //Returns TRUE if the given input's value can be interpreted as a integer or a float function isInputAValidNumber(inputName) { if (getInputElement(inputName) == null) return true; var s = new String(getInputElement(inputName).value); return (isStringAValidNumber(s)); } //Returns TRUE if the given value can be interpreted as having a valid date format as specified in the prophetSampleFormatEntryData field. function isStringAValidDate(value) { //variables var themonth; var theday; var theyear; //grab the prophetSampleFormatEntryDate value on the page to check against var prophetSampleFormatEntryDate = document.getElementById("prophetSampleFormatEntryDate"); if (prophetSampleFormatEntryDate == null) {alert("Warning: prophetSampleFormatEntryDate object not found. \n\n Validation cannot continue.");return false;} if (prophetSampleFormatEntryDate.value == null) {alert("Warning: prophetSampleFormatEntryDate object not found. \n\n Validation cannot continue.");return false;} var s = new String(prophetSampleFormatEntryDate.value); // var s = "MM/dd/yyyy"; //Step 1 determine our delimiter var strDelimiter; strDelimiter = s.replace(/dd/,""); strDelimiter = strDelimiter.replace(/MM/,""); strDelimiter = strDelimiter.replace(/yyyy/,""); //compare to see if our delimiter is 2 characters if it is then continue if(strDelimiter.length < 2)return false; //now that we have a delimeter make sure both characters in the delimiter are the same if(strDelimiter.charAt(0)!= strDelimiter.charAt(1))return false; strDelimiter = strDelimiter.charAt(0); //Step 2 grab the value and start checking it... var st = new String(value); if(st=='')return false; var dateElementArray = st.split(strDelimiter); //grab the input to validate if (dateElementArray.length != 3) return(false); for (m = 0; m < 3; m++) { for (p = 0; p < String(dateElementArray[m]).length; p++) { var theChar = String(dateElementArray[m]).slice(p, p+1); //if the character we are parsing is the day then store the corresponding day value if (theChar < "0" || theChar > "9") return(false); } } //Step 3 find the position of the day month and year values, using these positions, grab them from the input we are validating and store them in the corresponding variables var dateFormatElementArray = s.split(strDelimiter); for (i = 0; i < 3; i++) { var theChar = String(dateFormatElementArray[i]).charAt(0); //if the character we are parsing is the day then store the corresponding day value if(theChar != 'M' && theChar != 'd' && theChar != 'y') return false; if(theChar == 'M'){ //month themonth = String(dateElementArray[i]) } if(theChar == 'd'){ //day theday = String(dateElementArray[i]) } if(theChar == 'y'){ //year theyear = String(dateElementArray[i]) } } //Step 4 now check each of the values //the year is not 4 digits if (String(theyear).length != 4) return(false); //make sure all of the dates are numbers. if (isNaN(themonth) || isNaN(theday) || isNaN(theyear)) return(false); //day checking... if (themonth < 1 || themonth > 12 || theday < 1 || theday > 31 || (theyear < 1900 && theyear > 99) || theyear > 2099) { // check month range return false; } if ((themonth==4 || themonth==6 || themonth==9 || themonth==11) && theday==31) { return false; } if (themonth == 2) { // check for february 29th var isleap = (theyear % 4 == 0 && (theyear % 100 != 0 || theyear % 400 == 0)); if (theday>29 || (theday==29 && !isleap)) { return false; } } return(true); } //Returns TRUE if the given input's value can be interpreted as having a valid date format: MM/DD/YY or MM/DD/YYYY //Note: this does *not* check for invalid days within a month (eg. 2/31/1980) function isInputAValidDate(inputName) { if (getInputElement(inputName) == null) return true; var s = new String(getInputElement(inputName).value); return (isStringAValidDate(s)); } //Returns TRUE if the given string's value can be interpreted as having a valid time format according to the prophetSampleFormatEntryTime fields function isStringAValidTime(value) { //variables var boolHasAMPM = false; var boolIs24HourTime = false; var boolIsAMPMSuffix = false; var boolIsAMPMPrefix = false; var strAMString = ''; var strPMString = ''; //grab the prophetSampleFormatEntryTimeAM value on the page to check against var prophetSampleFormatEntryTimeAM = document.getElementById("prophetSampleFormatEntryTimeAM"); if (prophetSampleFormatEntryTimeAM == null) {alert("Warning: prophetSampleFormatEntryTimeAM object not found. \n\n Validation cannot continue.");return false;} //grab the prophetSampleFormatEntryTimePM value on the page to check against var prophetSampleFormatEntryTimePM = document.getElementById("prophetSampleFormatEntryTimePM"); if (prophetSampleFormatEntryTimePM == null) {alert("Warning: prophetSampleFormatEntryTimePM object not found. \n\n Validation cannot continue.");return false;} var s = new String(prophetSampleFormatEntryTimeAM.value); var s2 = new String(prophetSampleFormatEntryTimePM.value); // var s = "hh:mm AM"; // var s2 = "hh:mm PM"; //determine our delimiter (we do this by finding the index of the minutes and grabbing the character before it... var strDelimiter; var strDelimiterIndex = 0; strDelimiterIndex = s.indexOf("m"); if(strDelimiterIndex==0)return false; strDelimiter = s.charAt (strDelimiterIndex-1); //compare to see if our delimiter is 1 character if it is then continue if(strDelimiter.length < 1 || strDelimiter.length > 1)return false; //determine the position of the space in the time, this will let us know where our AM PM is located //------------------------------------------------------------------------ var timeFormatElementArray = s.split(strDelimiter); var timeFormatPMElementArray = s2.split(strDelimiter) if ((timeFormatElementArray.length != 2) || (timeFormatPMElementArray.length != 2)) return(false); var intArrayIndexLoc; //stores the array index of the format array we found the space in and hence the AM or PM if((timeFormatElementArray[0].indexOf(" ") > -1) || (timeFormatElementArray[1].indexOf(" ") > -1 )){ boolHasAMPM = true; boolIs24HourTime = false; } else{ boolHasAMPM = false; boolIs24HourTime = true; //we assume if the time is 24 hour format then there will be NO AM or PM value } if(boolHasAMPM==true){ if(timeFormatElementArray[0].indexOf(" ") > -1)intArrayIndexLoc = 0; if(timeFormatElementArray[1].indexOf(" ") > -1)intArrayIndexLoc = 1; //we have the position so now determine if the hh or mm is before or after the space var timeFormatAMPMArray = timeFormatElementArray[intArrayIndexLoc].split(" "); var timeFormatAMPMArray2 = timeFormatPMElementArray[intArrayIndexLoc].split(" "); if(timeFormatAMPMArray[0] != 'mm' && timeFormatAMPMArray[0] != 'hh'){ boolIsAMPMPrefix=true; strAMString=timeFormatAMPMArray[0]; //grab the pm string... strPMString=timeFormatAMPMArray2[0]; } else{ boolIsAMPMSuffix=true; strAMString=timeFormatAMPMArray[1]; //grab the pm string... strPMString=timeFormatAMPMArray2[1]; } } //Step 1 grab the time string and do some simple checks on it var timeElementAMPMArray; var st = new String(value); if(st=='')return false; var timeElementArray = st.split(strDelimiter); if (timeElementArray.length != 2) return(false); //AM PM check... //make sure they provided an AM or PM if they needed to... if(boolHasAMPM==true){ var boolGoodToGo = false; //stupid javascript doesn't like order of operations when i put these 2 statments together so...store the result in a variable and check it later timeElementAMPMArray = timeElementArray[intArrayIndexLoc].split(" "); if((timeElementArray[intArrayIndexLoc].indexOf(strAMString) < 0) && (timeElementArray[intArrayIndexLoc].indexOf(strPMString) >= 0))boolGoodToGo = true; if( (timeElementArray[intArrayIndexLoc].indexOf(strAMString) >= 0) && (timeElementArray[intArrayIndexLoc].indexOf(strPMString) < 0 ))boolGoodToGo = true; //make sure the provide either an AM or PM string if(timeElementAMPMArray[intArrayIndexLoc] != strAMString){ //check for the am string if (timeElementAMPMArray[intArrayIndexLoc] != strPMString){ //ok we didnt find that so check for the pm string return false; } } if(timeElementAMPMArray[intArrayIndexLoc] != strPMString){ //check for the pm string if (timeElementAMPMArray[intArrayIndexLoc] != strAMString){ //ok we didnt find that so check for the am string return false; } } if(boolGoodToGo==false)return false; } //Minutes Check var minutes; //grab the minutes whereever it may be if(boolHasAMPM==true && boolIsAMPMSuffix==true)minutes = timeElementAMPMArray[0]; if(boolHasAMPM==true && boolIsAMPMPrefix==true)minutes = timeElementArray[1]; if(boolHasAMPM==false)minutes = timeElementArray[1]; if (minutes.length != 2) return(false); if(minutes.indexOf(' ') > 0)return(false); //look for a space if(minutes.indexOf('.') > 0)return(false); //look for a period var minutesNum = minutes; if (isNaN(minutesNum)==true) return(false); if (minutesNum < 0 || minutesNum > 59) return(false); //Hours Check var hour; //grab the hours whereever they may be if(boolHasAMPM==true && boolIsAMPMSuffix==true)hour = timeElementArray[0]; if(boolHasAMPM==true && boolIsAMPMPrefix==true)hour = timeElementAMPMArray[1]; if(boolHasAMPM==false)hour = timeElementArray[0]; if(hour.indexOf(' ') > 0)return(false); //look for a space if(hour.indexOf('.') > 0)return(false); //look for a period if (isNaN(hour)==true) return(false); if(boolIs24HourTime==true){ if (hour < 0 || hour > 23) return(false); } else{ if (hour < 1 || hour > 12) return(false); } return(true); } //Returns TRUE if the given input's value can be interpreted as having a valid time format according to the prophetSampleEntryTime fields. //This function will attempt to cut the user some slack and uppercase/lowercase things to see if they work. It then normalizes the field contents. function isInputAValidTime(inputName) { var e = getInputElement(inputName); if (e == null) return true; var s = e.value; if (isStringAValidTime(s)) return(true); s = e.value.toLowerCase(); if (isStringAValidTime(s)) { e.value = s; return(true); }; s = e.value.toUpperCase(); if (isStringAValidTime(s)) { e.value = s; return(true); }; s = e.value.toLocaleLowerCase(); if (isStringAValidTime(s)) { e.value = s; return(true); }; s = e.value.toLocaleUpperCase(); if (isStringAValidTime(s)) { e.value = s; return(true); }; s = e.value.toLocaleLowerCase().replace(/am/, 'a.m.'); if (isStringAValidTime(s)) { e.value = s; return(true); }; s = e.value.toLocaleLowerCase().replace(/pm/, 'p.m.'); if (isStringAValidTime(s)) { e.value = s; return(true); }; return(false); } //------------------------------------------------------------------------------------- //calculates the number of days between 2 date objects passed in //------------------------------------------------------------------------------------- function calcdaysbetween(date1, date2) { // The number of milliseconds in one day var oneday = 1000 * 60 * 60 * 24; // Convert both dates to milliseconds var date1_ms = date1.getTime(); var date2_ms = date2.getTime(); // Calculate the difference in milliseconds var differencems = Math.abs(date1_ms - date2_ms); // Convert back to days and return return Math.round(differencems/oneday); } //------------------------------------------------------------------------------------- //This function parses out the mm/dd/yyyy values based on the format of the date and populated themonth theday and theyear. //this function is used by convertValidDateToDojoFormat() and convertValidDateToDays() //------------------------------------------------------------------------------------- function getMonthDayYearValues(inputName){ ///------------------------------------------------------------------------------------- var themonth; var theday; var theyear; var datearray=new Array(); //grab the prophetSampleFormatEntryDate value on the page to check against var prophetSampleFormatEntryDate = document.getElementById("prophetSampleFormatEntryDate"); if (prophetSampleFormatEntryDate == null) {alert("Warning: prophetSampleFormatEntryDate object not found. \n\n Validation cannot continue.");return 0;} if (prophetSampleFormatEntryDate.value == null) {alert("Warning: prophetSampleFormatEntryDate object not found. \n\n Validation cannot continue.");return 0;} var s = new String(prophetSampleFormatEntryDate.value); //var s = "MM/dd/yyyy"; //Step 1 determine our delimiter var strDelimiter; strDelimiter = s.replace(/dd/,""); strDelimiter = strDelimiter.replace(/MM/,""); strDelimiter = strDelimiter.replace(/yyyy/,""); //compare to see if our delimiter is 2 characters if it is then continue if(strDelimiter.length < 2)return null; //now that we have a delimeter make sure both characters in the delimiter are the same if(strDelimiter.charAt(0)!= strDelimiter.charAt(1))return null; strDelimiter = strDelimiter.charAt(0); //Step 2 grab the value and start checking it... var st = new String(inputName); if(st=='')return null; var dateElementArray = st.split(strDelimiter); //grab the input to validate if (dateElementArray.length != 3) return(null); for (m = 0; m < 3; m++) { for (p = 0; p < String(dateElementArray[m]).length; p++) { var theChar = String(dateElementArray[m]).slice(p, p+1); //if the character we are parsing is the day then store the corresponding day value if (theChar < "0" || theChar > "9") return(null); } } //Step 3 find the position of the day month and year values, using these positions, grab them from the input we are validating and store them in the corresponding variables var dateFormatElementArray = s.split(strDelimiter); for (i = 0; i < 3; i++) { var theChar = String(dateFormatElementArray[i]).charAt(0); //if the character we are parsing is the day then store the corresponding day value if(theChar != 'M' && theChar != 'd' && theChar != 'y') return null; if(theChar == 'M'){ //month themonth = String(dateElementArray[i]); } if(theChar == 'd'){ //day theday = String(dateElementArray[i]); } if(theChar == 'y'){ //year theyear = String(dateElementArray[i]); } } //set the array values datearray[0] = themonth; datearray[1] = theday; datearray[2] = theyear; return datearray; } //------------------------------------------------------------------------------------- //Returns a date format of yyyy-mm-dd for the provided date //Note: this does *not* check for invalid dates //------------------------------------------------------------------------------------- function convertValidDateToDojoFormat(inputName){ var datearray = new Array(); datearray = getMonthDayYearValues(inputName); if(datearray != null){ // The date is good so now put it back together as yyy-mm-dd var s = ''; //padd a 0 on the begining and return the right most 2 characters... datearray[0] = '0' + datearray[0]; //month datearray[1] = '0' + datearray[1]; //day var iLen = String(datearray[0]).length; //month datearray[0] = String(datearray[0]).substring(iLen, iLen - 2); //month var iLen2 = String(datearray[1]).length; //day datearray[1] = String(datearray[1]).substring(iLen2, iLen2 - 2); //day s = datearray[2] + '-' + datearray[0] + '-' + datearray[1]; return (s); } else{ return ''; } } //------------------------------------------------------------------------------------- //Returns the number of days between the date and 01/01/0100 if the given input's value can be interpreted as having a valid date format //Note: this does *not* check for invalid dates //------------------------------------------------------------------------------------- function convertValidDateToDays(inputName){ //variables var comparedateis = new Date(100,0,1,0,0,0,0); //01/01/0100 Date(year, month, day, hours, minutes, seconds, milliseconds) subtract 1 from the month var datearray = new Array(); datearray = getMonthDayYearValues(inputName); if(datearray != null){ // Store the date of the next New Year's Day var comparedatetwois = new Date(datearray[2] ,datearray[0] -1,datearray[1],0,0,0,0); //new Date(year, month, day, hours, minutes, seconds, milliseconds) subtract 1 from the month return (calcdaysbetween(comparedateis, comparedatetwois)); } else{ return 0; } } // converts the passed time (as a string, must be a valid time) to an all-minutes value function convertValidTimeToMinutes(passedTime) { //variables var boolHasAMPM = false; var boolIs24HourTime = false; var boolIsAMPMSuffix = false; var boolIsAMPMPrefix = false; var strAMString = ''; var strPMString = ''; //grab the prophetSampleFormatEntryTimeAM value on the page to check against var prophetSampleFormatEntryTimeAM = document.getElementById("prophetSampleFormatEntryTimeAM"); if (prophetSampleFormatEntryTimeAM == null) {alert("Warning: prophetSampleFormatEntryTimeAM object not found. \n\n Validation cannot continue.");return false;} //grab the prophetSampleFormatEntryTimePM value on the page to check against var prophetSampleFormatEntryTimePM = document.getElementById("prophetSampleFormatEntryTimePM"); if (prophetSampleFormatEntryTimePM == null) {alert("Warning: prophetSampleFormatEntryTimePM object not found. \n\n Validation cannot continue.");return false;} var s = new String(prophetSampleFormatEntryTimeAM.value); var s2 = new String(prophetSampleFormatEntryTimePM.value); // var s = "hh:mm AM"; // var s2 = "hh:mm PM"; //determine our delimiter (we do this by finding the index of the minutes and grabbing the character before it... var strDelimiter; var strDelimiterIndex = 0; strDelimiterIndex = s.indexOf("m"); if(strDelimiterIndex==0)return false; strDelimiter = s.charAt (strDelimiterIndex-1); //compare to see if our delimiter is 1 character if it is then continue if(strDelimiter.length < 1 || strDelimiter.length > 1)return false; //determine the position of the space in the time, this will let us know where our AM PM is located //------------------------------------------------------------------------ var timeFormatElementArray = s.split(strDelimiter); var timeFormatPMElementArray = s2.split(strDelimiter) if ((timeFormatElementArray.length != 2) || (timeFormatPMElementArray.length != 2)) return(false); var intArrayIndexLoc; //stores the array index of the format array we found the space in and hence the AM or PM if((timeFormatElementArray[0].indexOf(" ") > -1) || (timeFormatElementArray[1].indexOf(" ") > -1 )){ boolHasAMPM = true; boolIs24HourTime = false; } else{ boolHasAMPM = false; boolIs24HourTime = true; //we assume if the time is 24 hour format then there will be NO AM or PM value } if(boolHasAMPM==true){ if(timeFormatElementArray[0].indexOf(" ") > -1)intArrayIndexLoc = 0; if(timeFormatElementArray[1].indexOf(" ") > -1)intArrayIndexLoc = 1; //we have the position so now determine if the hh or mm is before or after the space var timeFormatAMPMArray = timeFormatElementArray[intArrayIndexLoc].split(" "); var timeFormatAMPMArray2 = timeFormatPMElementArray[intArrayIndexLoc].split(" "); if(timeFormatAMPMArray[0] != 'mm' && timeFormatAMPMArray[0] != 'hh'){ boolIsAMPMPrefix=true; strAMString=timeFormatAMPMArray[0]; //grab the pm string... strPMString=timeFormatAMPMArray2[0]; } else{ boolIsAMPMSuffix=true; strAMString=timeFormatAMPMArray[1]; //grab the pm string... strPMString=timeFormatAMPMArray2[1]; } } //Step 1 grab the time string and do some simple checks on it var timeElementAMPMArray; var st = new String(passedTime); if(st=='')return false; var timeElementArray = st.split(strDelimiter); if (timeElementArray.length != 2) return(false); //AM PM check... //make sure they provided an AM or PM if they needed to... var strAMorPMActualString = ''; if(boolHasAMPM==true){ var boolGoodToGo = false; //stupid javascript doesn't like order of operations when i put these 2 statments together so...store the result in a variable and check it later timeElementAMPMArray = timeElementArray[intArrayIndexLoc].split(" "); if((timeElementArray[intArrayIndexLoc].indexOf(strAMString) < 0) && (timeElementArray[intArrayIndexLoc].indexOf(strPMString) >= 0))strAMorPMActualString=strPMString;boolGoodToGo = true; if( (timeElementArray[intArrayIndexLoc].indexOf(strAMString) >= 0) && (timeElementArray[intArrayIndexLoc].indexOf(strPMString) < 0 ))strAMorPMActualString=strAMString;boolGoodToGo = true; if(boolGoodToGo==false)return false; } //Minutes Check var minutes; //grab the minutes whereever it may be if(boolHasAMPM==true && boolIsAMPMSuffix==true)minutes = parseInt(timeElementAMPMArray[0], 10); if(boolHasAMPM==true && boolIsAMPMPrefix==true)minutes = parseInt(timeElementArray[1], 10); if(boolHasAMPM==false)minutes =parseInt(timeElementArray[1], 10); //Hours Check var hour; //grab the hours whereever they may be if(boolHasAMPM==true && boolIsAMPMSuffix==true)hour = timeElementArray[0]; if(boolHasAMPM==true && boolIsAMPMPrefix==true)hour = timeElementAMPMArray[1]; if(boolHasAMPM==false)hour = timeElementArray[0]; //if there is a leading 0 then strip it out so we can parseInt the digit if(hour.charAt(0) == '0')hour = hour.substr(1,1); hour = parseInt(hour, 10); //Step 3 the actual conversion if (hour == 12 && boolIs24HourTime==false) hour = 0; if(strAMorPMActualString== "PM")hour += 12; return (parseInt(hour, 10) * 60) + parseInt(minutes, 10); } //Returns TRUE if the given input's value looks like a valid e-mail address function isInputAValidEmailAddress(inputName) { var s = new String(getInputValue(inputName)); s = fullTrimString(s); setInputValue(inputName, s); return isEmailAddressValid(s); } //Returns "" if the input's entries are all valid emails, otherwise returns the first offending entry function checkMultiInputEmailAddresses(inputName) { var s = getMultiInputValues(inputName); for (var i = 0; i < s.length; i++) { if (s[i] != "" && !isEmailAddressValid(s[i])) return s[i]; } return (""); } //Returns "" if the input's email entries are all valid numbers, otherwise returns the first offending entry function checkMultiInputNumbers(inputName) { // first check for a leading decimal and prepend with a zero if need-be to workaround SPR #PALT7KPLSE var e = getInputElement(inputName); var hasR = (e.value.indexOf('\r') != -1); var hasN = (e.value.indexOf('\n') != -1); var v = getMultiInputValues(inputName); for (var i = 0; i < v.length; i++) { if (v[i].slice(0,1) == "." || v[i].slice(0,1) == ",") v[i] = "0" + v[i]; } var sep = (hasR ? '\r' : '') + (hasN ? '\n' : ''); setInputValue(inputName, v.join(sep)); for (var i = 0; i < v.length; i++) { if (v[i] != "" && !isStringAValidNumber(v[i])) return v[i]; } return (""); } // this function is used to clear an error from a question or header - exactly how varies with form build versions function clearError(questionID, questionType) { var v = getDocObject('jsFormValidationVersion'); // pre-version 5 if (!v) { resetImage(questionID); return (false); } // V5 var e = getDocObject(questionID); if (!e) return (false); if (isIDForQuestion(questionID)) { var t = getDocObject(questionID + "Table"); e.style.backgroundColor = ""; t.style.backgroundColor = ""; t.style.border = ""; } else { //header var L = getDocObject(questionID + "TextCell"); var D = getDocObject(questionID + "AnswerCell"); var P = getDocObject(questionID + "PickerCell"); e.style.backgroundColor = ""; L.style.backgroundColor = ""; L.style.borderLeft = ""; L.style.borderTop = ""; L.style.borderBottom = ""; L.style.padding = ""; D.style.backgroundColor = ""; D.style.borderTop = ""; D.style.borderBottom = ""; D.style.padding = ""; // not all headers have a picker cell if (P) { P.style.backgroundColor = ""; P.style.borderTop = ""; P.style.borderBottom = ""; P.style.borderRight = ""; P.style.padding = ""; } else { D.style.borderRight = ""; } } } // this function is used to add a header/question to the list of headers/questions that have failed validation function raiseError(questionID, questionType) { if (getInputElement(questionID) == null) return false; if (incorrectQIDs != "") { incorrectQIDs += "·" + questionID; } else { incorrectQIDs += questionID; if (questionType == "01" || questionType == "07") firstIncorrectQisRadio = true; } } // this function returns TRUE if the questionID has an answer or doesn't exist, FALSE otherwise - also checks dates/times for valid input function isAnswered(questionID, questionType) { // Assume we don't need an answer for this question.... then try to prove this assumption false var returnValue = true; if (getInputElement(questionID) == null) { return (returnValue); }; if (typeof(theForm) != "undefined") { if (theForm.getQuestionById(questionID).isCurrentlyHiddenByCSS()) { return (returnValue); } } if (questionType == "01" || questionType == "07") returnValue = (getInputRadioIndex(questionID) >= 0); //we'll handle long-text-thread generically for now, we'll probably want an override in the future if (questionType == "03" || questionType == "05" || questionType == "18" || questionType == "19" || questionType == "20" || questionType == "22") returnValue = !isInputBlank(questionID); if (questionType == "17") { if (document.getElementById(questionID + 'div').style.display == 'none') return (returnValue); // file uploads might have their div hidden through CSS returnValue = (getInputValue(questionID).length >= 5); // otherwise we need a file with length in file uploads } if (questionType == "02" || questionType == "16") returnValue = (!isInputBlank(questionID) && isInputAValidNumber(questionID)); // single-answer list -- answer can not start with "[" if (questionType == "04") { returnValue = !(getInputElement(questionID).options[getInputElement(questionID).selectedIndex].text.charAt(0) == "["); }; if (questionType == "06") { returnValue = !(countInputSelectedOptions(questionID) == 0); }; // time if (questionType == "12") returnValue = (!isInputBlank(questionID) && isInputAValidTime(questionID)); // date if (questionType == "13") returnValue = (!isInputBlank(questionID) && isInputAValidDate(questionID)); return (returnValue); } function iA(questionID, questionType) { return (isAnswered(questionID, questionType)); } //returns TRUE if the questionID is equal to/less than/etc. to the passed date value given, when [tolerance] (in days) is applied (negative values mean in the past). //[operation] is a string such as '=', '!=', '<', '>=', etc. [value] is always a string. function answerDateIsXXTo (questionID, operation, value, tolerance) { var s = getInputValue(questionID); if (s == "") return(false); var qDays = convertValidDateToDays(s); var vDays = convertValidDateToDays(value); switch (operation) { case '=' : return(qDays == vDays + tolerance); case '==' : return(qDays == vDays + tolerance); case '!=' : return(qDays != vDays + tolerance); case '<' : return(qDays < vDays + tolerance); case '<=' : return(qDays <= vDays + tolerance); case '>' : return(qDays > vDays + tolerance); case '>=' : return(qDays >= vDays + tolerance); } } //returns TRUE if the questionID is equal to/less than/etc. to the passed date value given, when [tolerance] (in days) is applied (negative values mean in the past). //[operation] is a string such as '=', '!=', '<', '>=', etc. [value] is always a string. function answerDateIsXXToOLD (questionID, operation, value, tolerance) { var s = getInputValue(questionID); if (s == "") return(false); var qDateArray = s.split('/'); var qDate = new Date(qDateArray[2], qDateArray[0] - 1, qDateArray[1]); var vDateArray = value.split('/'); var vDate = new Date(vDateArray[2], vDateArray[0] - 1, vDateArray[1]); //convert tolerance to units of Date object tolerance = tolerance * 86400000; switch (operation) { case '=' : return(qDate.getTime() == vDate.getTime() + tolerance); case '==' : return(qDate.getTime() == vDate.getTime() + tolerance); case '!=' : return(qDate.getTime() != vDate.getTime() + tolerance); case '<' : return(qDate.getTime() < vDate.getTime() + tolerance); case '<=' : return(qDate.getTime() <= vDate.getTime() + tolerance); case '>' : return(qDate.getTime() > vDate.getTime() + tolerance); case '>=' : return(qDate.getTime() >= vDate.getTime() + tolerance); } } // returns TRUE if the questionID is equal to the value given. [value] is always a string. function answerIsEqualTo(questionID, questionType, value) { if (value == "") return (!isAnswered(questionID, questionType)); if (!isAnswered(questionID, questionType)) return (false); if (questionType == "01" || questionType == "07") return(getSelectedRadioValue(questionID) == value); if (questionType == "02" || questionType == "16") return (mParseFloat(getInputValue(questionID)) == mParseFloat(value)); if (questionType == "03" || questionType == "05" || questionType == "12" || questionType == "13" || questionType == "17" || questionType == "18" || questionType == "19" || questionType == "20") return(getInputValue(questionID) == value); if (questionType == "04") return(getSelectedText(questionID) == value); if (questionType == "06") { var e = getInputElement(questionID); //might be a checkbox, which is an array of inputs, not an array of options if (e.type) { if (e.type=="checkbox") { if (e.checked && e.value == value) return (true); //single checkbox } else { for (var i = 0; i < e.length; i++) if ((e.options[i].selected) && (e.options[i].text == value)) return (true); //multiple select } } else { for (var i = 0; i < e.length; i++) if ((e[i].checked) && (e[i].value == value)) return (true); //assume multiple checkboxes } return (false); } } // returns TRUE if the questionID alias is equal to the value given. [value] is always a string. Any questions that use this should always have an alias to avoid IE browser .text vs .value weirdness (see getSelectedValue). function answerIsEqualToAlias(questionID, questionType, value) { if (value == "") return (!isAnswered(questionID, questionType)); if (!isAnswered(questionID, questionType)) return (false); if (questionType == "01" || questionType == "07") return(getSelectedRadioValue(questionID) == value); if (questionType == "02" || questionType == "16") return (mParseFloat(getInputValue(questionID)) == mParseFloat(value)); if (questionType == "03" || questionType == "05" || questionType == "12" || questionType == "13" || questionType == "17" || questionType == "18" || questionType == "19" || questionType == "20") return(getInputValue(questionID) == value); if (questionType == "04") return(getSelectedValue(questionID) == value); if (questionType == "06") { var e = getInputElement(questionID); //might be a checkbox, which is an array of inputs, not an array of options if (e.type) { if (e.type=="checkbox") { if (e.checked && e.value == value) return (true); //single checkbox } else { for (var i = 0; i < e.length; i++) if ((e.options[i].selected) && (e.options[i].value == value)) return (true); //multiple select } } else { for (var i = 0; i < e.length; i++) if ((e[i].checked) && (e[i].value == value)) return (true); //assume multiple checkboxes } return (false); } } function ansEq(questionID, questionType, value) { return (answerIsEqualTo(questionID, questionType, value)); } function ansEqAlias(questionID, questionType, value) { return (answerIsEqualToAlias(questionID, questionType, value)); } // returns TRUE if the questionID is less than the value given. [value] is always a string, and the question type is assumed to be '02' (number) function answerIsLessThan(questionID, value) { var answer = mParseFloat(getInputValue(questionID)); if (isNaN(answer)) return(false); return (answer < (mParseFloat(value))); } // returns TRUE if the questionID is greater than the value given. [value] is always a string, and the question type is assumed to be '02' (number) function answerIsGreaterThan(questionID, value) { var answer = mParseFloat(getInputValue(questionID)); if (isNaN(answer)) return(false); return (answer > (mParseFloat(value))); } // returns TRUE if the questionID is less than or equal to the value given. [value] is always a string, and the question type is assumed to be '02' (number) function answerIsLessThanOrEqualTo(questionID, value) { var answer = mParseFloat(getInputValue(questionID)); if (isNaN(answer)) return(false); return (answer <= (mParseFloat(value))); } // returns TRUE if the questionID is greater than the value given. [value] is always a string, and the question type is assumed to be '02' (number) function answerIsGreaterThanOrEqualTo(questionID, value) { var answer = mParseFloat(getInputValue(questionID)); if (isNaN(answer)) return(false); return (answer >= (mParseFloat(value))); } // resets a question's/header visual error flagging - legacy Pre-V5 forms only function resetImage(questionID) { // Only reset questions -- headers don't have an image if (isIDForQuestion(questionID)) { if (getDocObject(questionID + "Pic") != null) { eval("document." + questionID + "Pic.src=document.forms[0].jsDefinitionsDbURL.value + \"/IBlank?OpenImageResource\""); }; } else { if (getDocObject(questionID) != null) { elem = getInputElement(questionID); elem.className = "QStyle1Input"; } }; } // translates confirmation message from compressed version to full version function getQuestionMessage (messagePosition) { var messageString = new String(getInputValue("jsQuestionMessages")); if (messageString == "") return (""); var messageArray = messageString.split("·"); return (messageArray[messagePosition]); }; // gets number of collapsed messages function getQuestionMessagesLength () { var messageString = new String(getInputValue("jsQuestionMessages")); if (messageString == "") return (-1); var messageArray = messageString.split("·"); return (messageArray.length); }; // removes a validation rule from the appropriate function removeValidationRule (ruleType, rulePosition) { var tmpString = "" if (ruleType == "required") var tmpString = new String(getInputValue("jsReqQuestions")); if (ruleType == "minmax") var tmpString = new String(getInputValue("jsMinMaxQuestions")); if (ruleType == "dependency") var tmpString = new String(getInputValue("jsDependentQuestions")); var tmpQuestionArray = tmpString.split("·"); var origLen = tmpQuestionArray.length; if (origLen > rulePosition) { if (rulePosition == 0) { tmpQuestionArray = tmpQuestionArray.slice(1); } else if (rulePosition == origLen-1) { tmpQuestionArray = tmpQuestionArray.slice(1); } else { var tmpArray1 = tmpQuestionArray.slice(0, rulePosition-1); var tmpArray2 = tmpQuestionArray.slice(rulePosition+1, origLen-1); tmpQuestionArray = tmpArray1.concat(tmpArray2); }; if (ruleType == "required") setInputValue("jsReqQuestions", tmpQuestionArray.join("·")); if (ruleType == "minmax") setInputValue("jsReqQuestions", tmpQuestionArray.join("·")); if (ruleType == "dependency") setInputValue("jsReqQuestions", tmpQuestionArray.join("·")); }; }; // checks a question's Min/Max range while taking flags into account function checkFlaggedMinMaxQuestion (answer, uiAnswer, questionMin, questionMax, minTolerance, maxTolerance, questionFlags, questionMessage, originalArrayPosition) { // alert('checking flaggedmixmax:\n\nanswer: ' + answer + '\nquestionMin:' + questionMin + '\nquestionMax:' + questionMax + '\nminTolerance:' + minTolerance + '\nmaxTolerance:' + maxTolerance // + '\nquestionFlags' + questionFlags + '\nquestionMessage:' + '\noriginalArrayPosition:' + originalArrayPosition); var returnVal = 1; for (var i = 0; i < getQuestionMessagesLength(); i++) { questionMessage = questionMessage.replace("%" + i, getQuestionMessage (i)); }; questionMessage = questionMessage.replace("%ans", uiAnswer); questionMessage = questionMessage.replace("%min", questionMin + minTolerance); questionMessage = questionMessage.replace("%max", questionMax + maxTolerance); if (questionFlags.indexOf("O") > -1) { if (!isNaN(questionMin)) if (answer < (questionMin + minTolerance)) { if (confirm(questionMessage + "\n\nClick \'OK\' to accept. Click \'Cancel\' to change it.")) { getDocObject('S_OverriddenMinMaxFlag').value = '1'; if (questionFlags.indexOf("1") > -1) { removeValidationRule ("minmax", originalArrayPosition); }; } else { returnVal = 0; } }; if (!isNaN(questionMax)) if (answer > (questionMax + maxTolerance)) { if (confirm(questionMessage + "\n\nClick \'OK\' to accept. Click \'Cancel\' to change it.")) { getDocObject('S_OverriddenMinMaxFlag').value = '1'; if (questionFlags.indexOf("1") > -1) { removeValidationRule ("minmax", originalArrayPosition); }; } else { returnVal = 0; }; }; } else { if (!isNaN(questionMin)) if (answer < (questionMin + minTolerance)) returnVal = 0; if (!isNaN(questionMax)) if (answer > (questionMax + maxTolerance)) returnVal = 0; }; return (returnVal); }; function clearFileUpload(divId) { // clears the file upload value for the file upload surrounded with the div id passed // the 'value' property is read-only in the browser for security reasons, so we will re-write the HTML to clear it by grabbing the div surrounding it document.getElementById(divId).innerHTML = document.getElementById(divId).innerHTML; } function clearFileUploadQuestions() { //called by draft-save option to prevent submission of file uploads var tmpString = new String(getInputValue("jsFileUploadQuestions")); if (tmpString == "") return (false); var tmpQuestionArray = tmpString.split("·"); for (var i = 0; i < tmpQuestionArray.length; i++) { if (getInputElement(tmpQuestionArray[i]) != null) { clearFileUpload(tmpQuestionArray[i] + 'div'); } // also uncheck any "delete" checkboxes if (getDocObject("fileMod" + tmpQuestionArray[i])) { getDocObject("fileMod" + tmpQuestionArray[i]).checked = false; } } // clear any logged file upload changes that might have occurred during this edit var e = getInputElement("jsFileUploadChanges"); if (e) e.value = ""; return(false); } function fileUploadModOnChange(obj) { // called by the fileUploadMod checkbox when a file upload is in edit mode var myId = String(obj.id).slice(7); var uploadControl = document.getElementById(myId + "div"); var inlineDisplay = document.getElementById(myId + "inlineFileDiv"); if (obj.checked) { if (uploadControl) uploadControl.style.display = "inline"; if (inlineDisplay) inlineDisplay.style.display = "none"; } else { // clear out the contents of the file upload and hide it if (uploadControl) { clearFileUpload(myId + 'div'); var uploadControl = document.getElementById(myId + "div"); // re-obtain handle uploadControl.style.display = "none"; } if (inlineDisplay) inlineDisplay.style.display = "inline"; } } function getFileUploadFilename(fileUploadId) { // returns the filename-only portion of the file upload control with the id passed var obj = document.getElementById(fileUploadId); if (obj != null) { var fixedFilePath = String(obj.value).replace(/\\/g, "/"); if (fixedFilePath.indexOf("/") < 0) { return (fixedFilePath); } else { return (atRightBack(fixedFilePath, "/")); } } return (''); } function isFileUploadFileExtensionAllowed(fileUploadID, allowedExtensions) { // when passed a file upload ID and a list of extensions (lowercased, separated by *, without a "."), returns TRUE if the extension currently on the file upload is allowed (or is blank, hidden, or some other unanswered value) //get the div (the file upload itself might be hidden) var fDiv = document.getElementById(fileUploadID + 'div'); //hidden completely? extension OK if (fDiv == null) return (true); //not visible? extension OK if (fDiv.style.display == 'none') return (true); var fName = String(getFileUploadFilename(fileUploadID)).toLowerCase(); //empty filename? extension OK if (fName == '') return(true); //cycle through allowed extensions var a = String(allowedExtensions).split("*"); for (var i = 0; i < a.length; i++) { if (fName.slice(-1 * (a[i].length + 1)).toLowerCase() == ("." + a[i]).toLowerCase()) return(true); } return(false); } function fileUploadOnChange(obj) { // called via onChange() of file uploads - checks for duplicate filenames and adds the file upload's new value to jsFileUploadChanges // we'll simply concatenate to keep the client-side JS logic simple, and "replay" the series of events in-order on the backend for processing there if (obj.value != "") { // first check to verify that we've got a unique filename - if not we can't allow the upload or Domino will convert it to ATTxxxx.xxx and we'll never know how it was linked var myFileName = getFileUploadFilename(obj.id); // loop through all currently-attached filenames and check for dupes var currAttachmentArray = String(getInputValue("jsFileAttachmentNames")).split("*"); for (var i = 0; i < currAttachmentArray.length; i++) { if (currAttachmentArray[i] != "") { if (myFileName.toLowerCase() == currAttachmentArray[i].toLowerCase()) { alert (String(jsAlreadyFileNamed).replace(/%value%/, myFileName)); clearFileUpload(obj.id + "div"); return(false); } } } // loop through other visible file uploads and check for dupes var tmpString = new String(getInputValue("jsFileUploadQuestions")); if (tmpString != "") { var tmpQuestionArray = tmpString.split("·"); for (var i = 0; i < tmpQuestionArray.length; i++) { if (tmpQuestionArray[i] != obj.id) { var otherFileName = getFileUploadFilename(tmpQuestionArray[i]); if (otherFileName != '') { if (otherFileName.toLowerCase() == myFileName.toLowerCase()) { alert (String(jsAlreadyFileNamed).replace(/%value%/, myFileName)); clearFileUpload(obj.id + "div"); return(false); } } } } } } // if we get here then there's been a change and it's valid - log the change var e = getInputElement("jsFileUploadChanges"); if (e) e.value += "·" + obj.id + "*" + obj.value; // we'll separate with * -- no filename or path should ever have that in it } // MAIN VALIDATE FUNCTIONS - each function is reponsible for resetting it's QIDs images function checkReqQuestions() { var tmpString = new String(getInputValue("jsReqQuestions")); if (tmpString == "") return (false); var tmpQuestionArray = tmpString.split("·"); for (var i = 0; i < tmpQuestionArray.length; i++) { var tmpSpecificQuestionArray = tmpQuestionArray[i].split(","); var questionID = tmpSpecificQuestionArray[0]; var questionType = tmpSpecificQuestionArray[1]; clearError(questionID); if (typeof(theForm) == "undefined") { if (!isAnswered(questionID, questionType)) raiseError(questionID, questionType); } else { if (!theForm.getQuestionById(questionID).isCurrentlyHiddenByCSS()) { if (!isAnswered(questionID, questionType)) raiseError(questionID, questionType); } } } return(false); } function checkMinMaxQuestions() { var tmpString = new String(getInputValue("jsMinMaxQuestions")); if (tmpString == "") return (false); getDocObject('S_OverriddenMinMaxFlag').value = '0'; //this will be set to '1' if the user/shopper overrides an answer later var tmpQuestionArray = tmpString.split("·"); for (var i = 0; i < tmpQuestionArray.length; i++) { var tmpSpecificQuestionArray = tmpQuestionArray[i].split(","); var questionID = tmpSpecificQuestionArray[0]; if (questionID == "False") continue; //patch for old forms that might have nonsense in the Min/Max validation field due to a backend bug (rebuilding the form should fix this) var questionType = tmpSpecificQuestionArray[1]; clearError(questionID); // our min and max might be numbers, or they might be question references - and they may or may not have tolerance strings appended (e.g. "~5") // get tolerances - default to 0 if not present or bad var minTolerance = 0; var minTolArray = tmpSpecificQuestionArray[2].split("~"); if (minTolArray.length == 2) minTolerance = mParseFloat(minTolArray[1], 10); if (isNaN(minTolerance)) minTolerance = 0; var maxTolerance = 0; var maxTolArray = tmpSpecificQuestionArray[3].split("~"); if (maxTolArray.length == 2) maxTolerance = mParseFloat(maxTolArray[1], 10); if (isNaN(maxTolerance)) maxTolerance = 0; // get minimum - this might be a question reference - get its value if so. var minArray = tmpSpecificQuestionArray[2].split("~"); // regardless of whether or not a tolerance is present the min will always be the first element var questionMin = minArray[0]; if (String(questionMin).substring(0, 2) == "Q_") { // min might be a question reference - get if so if (getInputElement(questionMin) == null) { questionMin = ''; } else if (typeof(theForm) != "undefined") { if (theForm.getQuestionById(questionID).isCurrentlyHiddenByCSS()) { questionMin = ''; } else { questionMin = getInputValue(questionMin); } } else { questionMin = getInputValue(questionMin); } } // get maximum - this might be a question reference - get its value if so. var maxArray = tmpSpecificQuestionArray[3].split("~"); // regardless of whether or not a tolerance is present the min will always be the first element var questionMax = maxArray[0]; if (String(questionMax).substring(0, 2) == "Q_") { // max might be a question reference - get if so if (getInputElement(questionMax) == null) { questionMax = ''; } else if (typeof(theForm) != "undefined") { if (theForm.getQuestionById(questionID).isCurrentlyHiddenByCSS()) { questionMax = ''; } else { questionMax = getInputValue(questionMax); } } else { questionMax = getInputValue(questionMax); } } var questionFlags = ""; var questionMessage = ""; if (tmpSpecificQuestionArray.length > 4) { questionFlags = tmpSpecificQuestionArray[4]; questionMessage = tmpSpecificQuestionArray[5]; } // if the question is hidden, get out if (getInputElement(questionID) == null) continue; if (typeof(theForm) != "undefined") { if (theForm.getQuestionById(questionID).isCurrentlyHiddenByCSS()) continue; } // the question is visible: branch off answertype var isValid = 1; if (questionType == "02" || questionType == "16") { questionMin = mParseFloat(questionMin, 10); questionMax = mParseFloat(questionMax, 10); var answer = mParseFloat(getInputValue(questionID)); if (isInputBlank(questionID)) isValid = 1; else if (isNaN(answer)) isValid = 0; else { isValid = checkFlaggedMinMaxQuestion (answer, getInputValue(questionID), questionMin, questionMax, minTolerance, maxTolerance, questionFlags, questionMessage, i); //if (!isNaN(questionMin)) if (answer < questionMin) isValid = 0; //if (!isNaN(questionMax)) if (answer > questionMax) isValid = 0; } } else if (questionType == "03" || questionType == "05" || questionType == "18") { questionMin = mParseFloat(questionMin, 10); questionMax = mParseFloat(questionMax, 10); var answer = getInputValue(questionID); if (isInputBlank(questionID)) isValid = 1; else { if (!isNaN(questionMin)) if (answer.length < (questionMin + minTolerance)) isValid = 0; if (!isNaN(questionMax)) if (answer.length > (questionMax + maxTolerance)) isValid = 0; } } else if (questionType == "06") { questionMin = mParseFloat(questionMin, 10); questionMax = mParseFloat(questionMax, 10); var answer = countInputSelectedOptions(questionID); if (countInputSelectedOptions(questionID) == 0) isValid = 1; else { if (!isNaN(questionMin)) if (countInputSelectedOptions(questionID) < (questionMin + minTolerance)) isValid = 0; if (!isNaN(questionMax)) if (countInputSelectedOptions(questionID) > (questionMax + maxTolerance)) isValid = 0; } } else if (questionType == "12") { var answer = getInputValue(questionID); if (isInputBlank(questionID)) isValid = 1; else if (!isStringAValidTime(answer)) isValid = 0; else { //brach check for min that is > max (e.g. 10:00PM to 3:00 AM) that spans midnight var isMin = isStringAValidTime(questionMin); var isMax = isStringAValidTime(questionMax); if (isMin && isMax) { questionMin = convertValidTimeToMinutes(questionMin); questionMax = convertValidTimeToMinutes(questionMax); if (questionMin > questionMax) { // time crossing midnight isValid = ((convertValidTimeToMinutes(answer) >= questionMin) || (convertValidTimeToMinutes(answer) <= questionMax)); } else { isValid = ((convertValidTimeToMinutes(answer) >= questionMin) && (convertValidTimeToMinutes(answer) <= questionMax)); } } else { if (isMin) if (convertValidTimeToMinutes(answer) < (convertValidTimeToMinutes(questionMin) + minTolerance)) isValid = 0; if (isMax) if (convertValidTimeToMinutes(answer) > (convertValidTimeToMinutes(questionMax) + maxTolerance)) isValid = 0; } } } else if (questionType == "13") { var answer = getInputValue(questionID); if (isInputBlank(questionID)) isValid = 1; else if (!isStringAValidDate(answer)) isValid = 0; else { if (isStringAValidDate(questionMin)) if (answerDateIsXXTo(questionID, '<', questionMin, minTolerance)) isValid = 0; if (isStringAValidDate(questionMax)) if (answerDateIsXXTo(questionID, '>', questionMax, maxTolerance)) isValid = 0; } }; if (!isValid) raiseError(questionID, questionType); } return(false); } function checkDependencyQuestions() { //check custom JS validation on the form //returns true if no problems, false if there was a trapped error for bad JS //calls raiseError() if any questions failed validation var tmpString = new String(getInputValue("jsDependentQuestions")); if (tmpString == "") return (true); var tmpQuestionArray = tmpString.split("·"); for (var i = 0; i < tmpQuestionArray.length; i++) { // we are splitting based off of alt-251 or # (legacy) if (tmpQuestionArray[i].search(/√/) != -1) { var tmpSpecificQuestionArray = tmpQuestionArray[i].split("√"); } else { var tmpSpecificQuestionArray = tmpQuestionArray[i].split("#"); } var questionID = tmpSpecificQuestionArray[0]; var questionType = tmpSpecificQuestionArray[1]; var condition1 = tmpSpecificQuestionArray[2]; var condition2 = tmpSpecificQuestionArray[3]; var condition3 = tmpSpecificQuestionArray[4]; // only check the question's dependencies if it is actually present on the form (it might be hidden) if (getInputElement(questionID) != null) { clearError(questionID); var cssCheckOk = true; if (typeof(theForm) != "undefined") { cssCheckOk = !theForm.getQuestionById(questionID).isCurrentlyHiddenByCSS(); } if (cssCheckOk) { // if condition1 is true, the condition2 must be true, else condition3 must be true // user-entered JS is subject to typos, so we'll wrap in a try/catch try { if (eval(condition1) == true) { if (eval(condition2) != true) raiseError(questionID, questionType); } else { if (eval(condition3) != true) raiseError(questionID, questionType); } } catch(err) { alert(String(jsDepValidationError).replace(/%tmpmscname%/g, jsg_profileMSCNameForProjectBranding).replace(/%tmpquestionid%/, questionID).replace(/%tmpformid%/, theForm.id).replace(/%tmperrmessage%/, err.message)); return(false); } } //end if } //end if } //end for return(true); } function flagIncorrectQIDs() { var questionIDs; questionIDs = incorrectQIDs.split("·"); var v = getDocObject('jsFormValidationVersion'); for (var i = 0; i < questionIDs.length; i++) { var questionID = questionIDs[i]; // pre-version 5 if (!v) { if (isIDForQuestion(questionID)) { if (getDocObject(questionID + "Pic") != null) { eval("document." + questionID + "Pic.src=document.forms[0].jsDefinitionsDbURL.value + \"/IRedArrow?OpenImageResource\""); }; } else { if (getDocObject(questionID) != null) { elem = getInputElement(questionID); elem.className = "HStyle1InputInvalid"; } }; } else { // V5 valdiation var e = getDocObject(questionID); if (!e) return (false); if (isIDForQuestion(questionID)) { var t = getDocObject(questionID + "Table"); //e.style.backgroundColor = "#ffb7b7"; t.style.backgroundColor = "#ffb7b7"; t.style.border = "solid 2px #ff0000"; } else { //header var L = getDocObject(questionID + "TextCell"); var D = getDocObject(questionID + "AnswerCell"); var P = getDocObject(questionID + "PickerCell"); //e.style.backgroundColor = "#ffb7b7"; L.style.backgroundColor = "#ffb7b7"; L.style.borderLeft = "solid 2px #ff0000"; L.style.borderTop = "solid 2px #ff0000"; L.style.borderBottom = "solid 2px #ff0000"; L.style.padding = "3px"; D.style.backgroundColor = "#ffb7b7"; D.style.borderTop = "solid 2px #ff0000"; D.style.borderBottom = "solid 2px #ff0000"; D.style.padding = "3px"; // not all headers have a picker cell if (P) { P.style.backgroundColor = "#ffb7b7"; P.style.borderTop = "solid 2px #ff0000"; P.style.borderBottom = "solid 2px #ff0000"; P.style.borderRight = "solid 2px #ff0000"; P.style.padding = "3px"; } else { D.style.borderRight = "solid 2px #ff0000"; }; } } } return(false); } function validate() { window.alert (typeof(jsAnswersChecked) != "undefined" ? jsAnswersChecked : "Click OK and please wait while your answers are checked.\n\nThis may take awhile. Please be patient."); if (typeof(mForm) == "function" && getJSFormValidationVersion() >=6) theForm = new mForm(); incorrectQIDs = ""; firstIncorrectQisRadio = false; checkReqQuestions(); checkMinMaxQuestions(); if (!checkDependencyQuestions()) return(false); // if there were any caught JS errors here, bail if (incorrectQIDs != "") { flagIncorrectQIDs(); var badQIDs = incorrectQIDs.split("·"); var firstIncorrectQID = ""; //see if the form has M_MasterQuestionsOrder field, if it does then set firstIncorrectQID to the first one the user sees, otherwise use the first one marked bad if (getDocObject('jsMasterQuestionsOrder')) { var allQIDs = getDocObject('jsMasterQuestionsOrder').value.split("·"); huntForFirstBadQuestion: for (var i = 0; i < allQIDs.length; i++) { for (var k = 0; k < badQIDs.length; k++) { if(allQIDs[i] == badQIDs[k]) { firstIncorrectQID = allQIDs[i]; break huntForFirstBadQuestion; } } } } if (firstIncorrectQID == "") {firstIncorrectQID = badQIDs[0]; } ; // file uploads - ie can't put focus on a hidden upload input, so we'll try that and instead put focus on the delete checkbox if it fails // radio buttons and checkboxes must be handled as a special case as they are arrays of inputs if (getInputElement(firstIncorrectQID).type) { if (getInputElement(firstIncorrectQID).type == 'file') { try { getInputElement(firstIncorrectQID).focus(); } catch(e) { getInputElement("fileMod" + firstIncorrectQID).focus(); } } else { getInputElement(firstIncorrectQID).focus(); } } else { getInputElement(firstIncorrectQID)[0].focus(); } var definitionsDbURL = document.forms[0].jsDefinitionsDbURL.value; var formID = document.forms[0].jsFormID.value; alert(typeof(jsProblemAnswers) != "undefined" ? jsProblemAnswers : "There was a problem with some of your answers.\n\nLook for red boxes around the problem question(s).\n\nA help window is about to appear to\naid you with the questions that have problems."); entryHelpWindowHandle = openEntryHelpWindow(definitionsDbURL, formID, firstIncorrectQID, true); return(false); } else { window.alert(typeof(jsAnswersOK) != "undefined" ? jsAnswersOK : "Your answers look OK!\n\nClick OK to send them!\n\nPlease allow a minute for the process to complete.\n\nYou will then receive a confirmation number."); return(true); } } function validateVisit() { var okToSubmit = true; if (document.forms[0].Status.value == '90') return(okToSubmit); //check for valid-entered date and time (though the visit may have times disabled) /* Commented 2009/06/08 - this should never occur due to our new input validation if (((document.forms[0].ChosenDate.value != '') && !isInputAValidDate('ChosenDate')) && okToSubmit) { alert ("You did not enter a valid date."); okToSubmit = false; } */ /* Commented 2009/06/08 - this should never occur due to our new input validation if (document.forms[0].jsSchedNoTimeFlag.value != '1') { if (!(isInputBlank('ChosenTime') || isInputAValidTime('ChosenTime')) && okToSubmit) { alert (jsValidateTime); okToSubmit = false; } } */ //now check for out-of-range date if (!isInputBlank('ChosenDate') && okToSubmit) { var chosenDateArray = new Array(); chosenDateArray = getMonthDayYearValues(getInputValue("ChosenDate")); var theDate = new Date(chosenDateArray[2], chosenDateArray[0] - 1, chosenDateArray[1], 0, 0, 0, 0); var excludedDays = new String(document.forms[0].jsSchedDOTWExcludes.value); for (i = 0; i < excludedDays.length; i++) { if (excludedDays.substr(i, 1) == String(theDate.getDay() + 1)) okToSubmit = confirm(jsDayOfWeekNotAllowed); }; var theDateInDays = convertValidDateToDays(getInputValue('ChosenDate')); var startDate = convertValidDateToDays(document.forms[0].jsSchedStartDate.value); var endDate = convertValidDateToDays(document.forms[0].jsSchedEndDate.value); if ((startDate > theDateInDays) || (endDate < theDateInDays)) okToSubmit = confirm(jsDateOutsideValidRange); } //check for too-early and too-late time, if applicable if (document.forms[0].jsSchedNoTimeFlag.value != '1' && document.forms[0].jsSchedStartTime.value != '') { if (!isInputBlank('ChosenTime') && okToSubmit) { var startTime = convertValidTimeToMinutes(getInputElement('jsSchedStartTime').value); var endTime = convertValidTimeToMinutes(getInputElement('jsSchedEndTime').value); var theTime = convertValidTimeToMinutes(getInputElement('ChosenTime').value); if (startTime < endTime) { if ((theTime < startTime) || (theTime > endTime)) okToSubmit = confirm(jsTimeOutsideValidRange); } if (startTime > endTime) { if ((theTime < startTime) && (theTime > endTime)) okToSubmit = confirm(jsTimeOutsideValidRange); } } //check for time invalid due to being in the restricted time range if (!isInputBlank('ChosenTime') && okToSubmit && (document.forms[0].jsSchedTimeExclude1.value != "")) { var time1 = convertValidTimeToMinutes(getInputElement('jsSchedTimeExclude1').value); var time2 = convertValidTimeToMinutes(getInputElement('jsSchedTimeExclude2').value); if (time1 < time2) { if ((time1 < theTime) && (time2 > theTime)) okToSubmit = confirm(jsTimeOutsideValidRange); } if (time1 > time2) { if ((time1 < theTime) || (time2 > theTime)) okToSubmit = confirm(jsTimeOutsideValidRange); } } } //check that if 'override dates' is checked that there are new date values given if (document.getElementById('OverrideSchedDatesFlag').checked && okToSubmit) { if (isInputBlank('SchedStartDate') || isInputBlank('SchedEndDate')) { alert (jsMustEnterOverrideDates); okToSubmit = false; } } return(okToSubmit); } function validateVisitAsShopper() { if (document.forms[0].ChosenDateSelect != null) { //Valid dates will be handled by our combobox on the form, though we still need to check for "[Choose one]" if (getSelectedText('ChosenDateSelect').charAt(0) == '[') { alert(typeof(jsChooseDate) != "undefined" ? jsChooseDate : 'You must choose a date.'); return(false); } } //Check for a valid time (may be disabled, though, or not available if rescheduling is not allowed) if (document.forms[0].ChosenTime != null) { if (document.forms[0].jsSchedNoTimeFlag.value != '1') { if (isInputBlank('ChosenTime') || !isInputAValidTime('ChosenTime')) { alert(typeof(jsPickTime) != "undefined" ? jsPickTime : 'You must choose a time.'); return(false); } } //check for too-early and too-late time, if applicable if (document.forms[0].jsSchedNoTimeFlag.value != '1') { if (!isInputBlank('ChosenTime')) { var startTime = convertValidTimeToMinutes(getInputElement('jsSchedStartTime').value); var endTime = convertValidTimeToMinutes(getInputElement('jsSchedEndTime').value); var theTime = convertValidTimeToMinutes(getInputElement('ChosenTime').value); if (startTime <= endTime) { if ((theTime < startTime) || (theTime > endTime)) { alert(typeof(jsPickAnotherTime) != "undefined" ? jsPickAnotherTime : 'You have picked a time that is not allowed.\n\nPick another time.'); return(false); } } if (startTime > endTime) { if ((theTime < startTime) && (theTime > endTime)) { alert(typeof(jsPickAnotherTime) != "undefined" ? jsPickAnotherTime : 'You have picked a time that is not allowed.\n\nPick another time.'); return(false); } } } //check for time invalid due to being in the restricted time range if (!isInputBlank('ChosenTime') && (document.forms[0].jsSchedTimeExclude1.value != "")) { var time1 = convertValidTimeToMinutes(getInputElement('jsSchedTimeExclude1').value); var time2 = convertValidTimeToMinutes(getInputElement('jsSchedTimeExclude2').value); if (time1 < time2) { if ((time1 < theTime) && (time2 > theTime)) { alert(typeof(jsPickAnotherTime) != "undefined" ? jsPickAnotherTime : 'You have picked a time that is not allowed.\n\nPick another time.'); return(false); } } if (time1 > time2) { if ((time1 < theTime) || (time2 > theTime)) { alert(typeof(jsPickAnotherTime) != "undefined" ? jsPickAnotherTime : 'You have picked a time that is not allowed.\n\nPick another time.'); return(false); } } } } } return(true); } // refreshes the visibility for the special actions and other messages of a visit function refreshSpecialActions() { // if we don't have a status field, use the parent form, in case we're calling this from a dialog box or something else spawned by a visit if (document.forms[0].Status) { var visitWindow = window; var visitForm = document.forms[0]; } else { var visitWindow = getParentWindow(); var visitForm = getParentForm(); }; var stat = visitForm.Status.value; var formEnterElementIDs = (String(visitForm.jsFormEnterElementIDs.value)).split('·'); // default to all hidden... getDocObjectFromWindowHandle('notifySA', visitWindow).style.visibility = 'hidden'; getDocObjectFromWindowHandle('acceptSA', visitWindow).style.visibility = 'hidden'; getDocObjectFromWindowHandle('cancelWavesSA', visitWindow).style.visibility = 'hidden'; getDocObjectFromWindowHandle('forceCompletedSA', visitWindow).style.visibility = 'hidden'; //getDocObjectFromWindowHandle('revertAcceptedSA', visitWindow).style.visibility = 'hidden'; this special action will only be available on a fresh doc open // enabled the start/end dates if visible and need-be (though this may be forced off again below) var overrideSchedDatesFlag = getDocObjectFromWindowHandle('OverrideSchedDatesFlag', visitWindow); if (overrideSchedDatesFlag) { if (overrideSchedDatesFlag.checked) { getDocObjectFromWindowHandle('SchedStartDate', visitWindow).disabled = false; getDocObjectFromWindowHandle('SchedEndDate', visitWindow).disabled = false; getDocObjectFromWindowHandle('schedStartDateCalendar', visitWindow).style.visibility = 'visible'; getDocObjectFromWindowHandle('schedEndDateCalendar', visitWindow).style.visibility = 'visible'; } else { getDocObjectFromWindowHandle('SchedStartDate', visitWindow).disabled = true; getDocObjectFromWindowHandle('SchedEndDate', visitWindow).disabled = true; getDocObjectFromWindowHandle('schedStartDateCalendar', visitWindow).style.visibility = 'hidden'; getDocObjectFromWindowHandle('schedEndDateCalendar', visitWindow).style.visibility = 'hidden'; } } // now hide the "enter this form now..." stuff -- alt-250 character here for (i = 0; i < formEnterElementIDs.length; i++) if(formEnterElementIDs[i] != '') { eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + '\', visitWindow).className=\'hiddenVisitFormOption\';'); eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + 'Preview\', visitWindow).className=\'hiddenVisitFormOption\';'); } if (stat == '10') { getDocObjectFromWindowHandle('statusDisp', visitWindow).src = visitForm.jsAssignmentsDbURL.value + "IVisitWorkflow1?OpenImageResource"; getDocObjectFromWindowHandle('statusTextDisp', visitWindow).innerHTML = visitWindow.jsVisitStatusAvailable; getDocObjectFromWindowHandle('notifySA', visitWindow).style.visibility = 'visible'; getDocObjectFromWindowHandle('cancelWavesSA', visitWindow).style.visibility = 'visible'; // now show the "preview this form as shopper..." stuff -- alt-250 character here for (i = 0; i < formEnterElementIDs.length; i++) if(formEnterElementIDs[i] != '') { eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + 'Preview\', visitWindow).className=\'mainMenuLink\';'); } } if (stat == '20') { getDocObjectFromWindowHandle('statusDisp', visitWindow).src = visitForm.jsAssignmentsDbURL.value + "IVisitWorkflow2?OpenImageResource"; getDocObjectFromWindowHandle('statusTextDisp', visitWindow).innerHTML = visitWindow.jsVisitStatusNotified; getDocObjectFromWindowHandle('notifySA', visitWindow).style.visibility = 'visible'; getDocObjectFromWindowHandle('cancelWavesSA', visitWindow).style.visibility = 'visible'; // now show the "preview this form as shopper..." stuff -- alt-250 character here for (i = 0; i < formEnterElementIDs.length; i++) if(formEnterElementIDs[i] != '') { eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + 'Preview\', visitWindow).className=\'mainMenuLink\';'); } } if (stat == '30') { getDocObjectFromWindowHandle('statusDisp', visitWindow).src = visitForm.jsAssignmentsDbURL.value + "IVisitWorkflow3?OpenImageResource"; getDocObjectFromWindowHandle('statusTextDisp', visitWindow).innerHTML = visitWindow.jsVisitStatusScheduled; getDocObjectFromWindowHandle('acceptSA', visitWindow).style.visibility = 'visible'; // now show the "preview this form as shopper..." stuff -- alt-250 character here for (i = 0; i < formEnterElementIDs.length; i++) if(formEnterElementIDs[i] != '') { eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + 'Preview\', visitWindow).className=\'mainMenuLink\';'); } } if (stat == '40') { getDocObjectFromWindowHandle('statusDisp', visitWindow).src = visitForm.jsAssignmentsDbURL.value + "IVisitWorkflow4?OpenImageResource"; getDocObjectFromWindowHandle('statusTextDisp', visitWindow).innerHTML = visitWindow.jsVisitStatusAccepted; getDocObjectFromWindowHandle('forceCompletedSA', visitWindow).style.visibility = 'visible'; // now show the "enter this form now..." stuff -- alt-250 character here for (i = 0; i < formEnterElementIDs.length; i++) if(formEnterElementIDs[i] != '') { eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + '\', visitWindow).className=\'mainMenuLink\';'); eval('getDocObjectFromWindowHandle(\'' + formEnterElementIDs[i] + 'Preview\', visitWindow).className=\'mainMenuLink\';'); } } if (stat == '80') { } if (stat == '90') { getDocObjectFromWindowHandle('statusDisp', visitWindow).src = visitForm.jsAssignmentsDbURL.value + "IVisitWorkflow5?OpenImageResource"; getDocObjectFromWindowHandle('statusTextDisp', visitWindow).innerHTML = visitWindow.jsVisitStatusCompleted; //getDocObjectFromWindowHandle('revertAcceptedSA', visitWindow).style.visibility = 'visible'; this special action will only be available on a fresh doc open // disable ALL sched date overriding if visible if (overrideSchedDatesFlag) { getDocObjectFromWindowHandle('OverrideSchedDatesFlag', visitWindow).disabled = true; getDocObjectFromWindowHandle('SchedStartDate', visitWindow).disabled = true; getDocObjectFromWindowHandle('SchedEndDate', visitWindow).disabled = true; getDocObjectFromWindowHandle('schedStartDateCalendar', visitWindow).style.visibility = 'hidden'; getDocObjectFromWindowHandle('schedEndDateCalendar', visitWindow).style.visibility = 'hidden'; } // disable "change shopper" button if present if (getDocObjectFromWindowHandle('changeShopper', visitWindow)) getDocObjectFromWindowHandle('changeShopper', visitWindow).style.visibility = 'hidden'; // disable "public status" button if present if (getDocObjectFromWindowHandle('PubOverrideFlag', visitWindow)) getDocObjectFromWindowHandle('PubOverrideFlag', visitWindow).disabled = true; } } //verifies that a visit has a date and time entered -- used by various MSC-side workflow functions function validateVisitHasDateAndTime() { if (document.forms[0].jsSchedNoTimeFlag.value != '1') { if (isInputBlank('ChosenTime') || isInputBlank('ChosenDate')) { alert (jsMustFirstEnterDateTime); return false; } } else if (isInputBlank('ChosenDate')) { alert (jsMustFirstEnterDate); return false; } return true; } //used to verify that a visit has a date/time before an MSC user begins to fill out a form (passed by the newUrl argument) function verifyVisitAndOpenForm(newUrl) { if (validateVisit()) { if (!(validateVisitHasDateAndTime())) return false; document.forms[0].$$Return.value = eval(newUrl); //since the MSC is completing the visit, change auto-cancel to NOT allow auto-cancel document.forms[0].OverrideCancelFlag.selectedIndex = 1; document.forms[0].submit(); return false; } } //used to verify that a visit has a date/time before an MSC user begins to fill out a form (passed by the newUrl argument) function verifyVisitAndOpenResumedWork(newUrl) { if (validateVisit()) { if (!(validateVisitHasDateAndTime())) return false; document.forms[0].$$Return.value = eval(newUrl); document.forms[0].updatedResumedWork.value = "1"; //store view used to open the visit so we can take them back there var vCookie = new Cookie('ProphetLastVisitView'); vCookie["lastVisitView"] = jsg_view; //save the cookie! vCookie.store(10950, "/", "", false); //daysToLive, path, domain, secure //since the MSC is completing the visit, change auto-cancel to NOT allow auto-cancel document.forms[0].OverrideCancelFlag.selectedIndex = 1; document.forms[0].submit(); return false; } } //used to verify that a visit has a date/time before an MSC user can force it to completion. function verifyVisitForForcedCompletion() { if (validateVisit()) { if (!(validateVisitHasDateAndTime())) return false; return true; } else { return false; } } //used to confirm that the MSC user wants to revert the visit from completed back to accepted function verifyVisitForRevertToAccepted() { return (confirm(jsVisitReverted)); } function vVAOF(newUrl) { return(verifyVisitAndOpenForm(newUrl)); } function openShopFromVisit(shopUNID) { window.open(document.forms[0].jsShopsDbURL.value + "UNIDs/" + (String(shopUNID)).substr(0, 32) + "?OpenDocument"); return false; } function validateShopper() { //returns false if the shopper's fields don't pass basic minimum validation if(isInputBlank('FirstName')) {alert(jsFirstName); return(false);}; if(isInputBlank('LastName')) {alert(jsLastName); return(false);}; //defaults in case the one on the form hasn't finished deploying via load design yet var jsReqPhoneHome = (window.jsReqPhoneHome == null ? 1 : window.jsReqPhoneHome); var jsReqPhoneOther = (window.jsReqPhoneOther == null ? 0 : window.jsReqPhoneOther); if(getInputElement('PhoneHome') != null) { if (jsReqPhoneHome) { if(isInputBlank('PhoneHome')) {alert(jsHomePhone); return(false);}; } } if(getInputElement('PhoneWork') != null && getInputElement('PhoneWorkFlag') != null) { if(!isInputBlank('PhoneWork') && getSelectedText('PhoneWorkFlag').charAt(0) == '[') {alert(jsCallWork); return(false); }; } if(getInputElement('PhoneFax') != null && getInputElement('PhoneFaxFlag') != null) { if(!isInputBlank('PhoneFax') && getSelectedText('PhoneFaxFlag').charAt(0) == '[') {alert(jsCallFax); return(false); }; } if(getInputElement('PhoneOther') != null) { if (jsReqPhoneOther) { if(isInputBlank('PhoneOther')) {alert(jsCellPhone); return(false);}; } } if(getInputElement('Gender') != null) { if(getSelectedText('Gender').charAt(0) == '[') {alert(jsGender); return(false);}; } if(getInputElement('BirthDate') != null) { if(isInputBlank('BirthDate')) {alert(jsDOB); return(false);}; } if(getInputElement('MSPACertification') != null) { if(getSelectedText('MSPACertification').charAt(0) == '[') {alert(jsMSPACert); return(false);}; if(getInputElement('MSPACertificationNum') != null) { if (getSelectedValue('MSPACertification') != '0') { if (!isInputAValidMSPACertificateNumber('MSPACertificationNum')) { alert(jsMSPACert); return(false); }; }; } } if(getInputElement('Languages') != null) { if(countInputSelectedOptions('Languages') == 0) {alert(jsLanguages); return(false);}; } // check paypal fields - might be hidden since some countries don't have Paypal yet if(getInputElement('PayPalFlag') != null) { if(getSelectedText('PayPalFlag').charAt(0) == '[') {alert(jsPayPal); return(false);}; if(getSelectedText('PayPalFlag') == 'Yes') { if(isInputBlank('PayPalEmailAddress')) {alert(jsPayPalEmail); return(false);}; }; } //check address fields -- note that not all address elements will always be visible - this is handled partially by our function calls but sometimes explicitly here if(isInputBlank('Address1')) {alert(jsMailAddress); return(false);}; if (getInputElement('State') != null) { if(getSelectedText('State').charAt(0) == '[') {alert(jsState); return(false);}; }; if (getInputElement('CityCombo') != null) { if(getSelectedText('CityCombo').charAt(0) == '[') {alert(jsCity); return(false);}; }; if (getInputElement('City') != null) { if(isInputBlank('City')) {alert(jsCity); return(false);}; }; if (getInputElement('ZipCode') != null) { if(isInputBlank('ZipCode')) {alert(jsZip); return(false);}; }; return(true); } //returns the window.document.links[] index of the first 'mailto:' link function getMailtoLinkIndex(windowHandle) { for (var i=0; i < windowHandle.document.links.length; i++) { if (String(windowHandle.document.links[i].href).slice(0,7) == 'mailto:') return(i); } return(-1); } //assigns a shopper and updates client-end UI for a visit function assignShopperToVisit() { var f = document.forms[0]; var shopperDescriptionsArray = f.jsShopperDescriptions.value.split("·"); var shopperEmailsArray = f.jsShopperEmails.value.split("·"); var shopperUNIDsArray = f.jsShopperUNIDs.value.split("·"); var theParentWindow = getParentWindow(); var theParentForm = getParentForm(); var shopperBoxIndex = f.ShopperBox.selectedIndex; getDocObjectFromWindowHandle('shopperInfo', theParentWindow).innerHTML= shopperDescriptionsArray[shopperBoxIndex]; getDocObjectFromWindowHandle('shopperEmail', theParentWindow).innerHTML= shopperEmailsArray[shopperBoxIndex]; //find and update the 'mailto' link var i = getMailtoLinkIndex(theParentWindow); theParentWindow.document.links[i].href = 'mailto:' + shopperEmailsArray[shopperBoxIndex] //update shopper UNID on visit and control (for e-mail generation) f.jsChosenShopperUNID.value = shopperUNIDsArray[shopperBoxIndex]; theParentForm.ShopperUNID.value = shopperUNIDsArray[shopperBoxIndex]; if (theParentForm.ShopperUNID.value != "") { theParentForm.updateAcceptedFlag.value = ""; theParentForm.Status.value = "30"; // getDocObjectFromWindowHandle('statusDisp', theParentWindow).src = theParentForm.jsAssignmentsDbURL.value + "IVisitWorkflow3?OpenImageResource"; refreshSpecialActions(); //refresh the special actions on the visit } } //assigns the current shopper and updates client-end UI for a visit - called by selection of shopper through view dialog function assignOpenedShopperToVisit() { var f = document.forms[0]; var theParentWindow = getParentWindow(); var theParentForm = getParentForm(); getDocObjectFromWindowHandle('shopperInfo', theParentWindow).innerHTML = f.jsShopperDescriptions.value; getDocObjectFromWindowHandle('shopperEmail', theParentWindow).innerHTML = f.jsShopperEmails.value; //find and update the 'mailto' link var i = getMailtoLinkIndex(theParentWindow); theParentWindow.document.links[i].href = 'mailto:' + f.jsShopperEmails.value; theParentForm.ShopperUNID.value = f.jsShopperUNIDs.value; if (theParentForm.ShopperUNID.value != "") { theParentForm.updateAcceptedFlag.value = ""; theParentForm.Status.value = "30"; // getDocObjectFromWindowHandle('statusDisp', theParentWindow).src = theParentForm.jsAssignmentsDbURL.value + "IVisitWorkflow3?OpenImageResource"; refreshSpecialActions(); //refresh the special actions on the visit } } //assigns the current location and updates client-end UI for a visit - called by selection of location through view dialog function assignOpenedLocationToVisit() { var f = document.forms[0]; var theParentWindow = getParentWindow(); var theParentForm = getParentForm(); theParentForm.updatedL_UNIDFlag.value = '1'; theParentForm.L_UNID.value = f.LocationUNID.value; getDocObjectFromWindowHandle('locationInfo', theParentWindow).innerHTML = f.LocationInfoDisp.value; } //called when a shopper submits a shops - sets the isSubmitting variable to true (should be defined on the calling form) and changes all possible "click to submit" texts to "please wait..." function renameShopperSubmitControls() { var pleaseWaitStr = (typeof(jsPleaseWait) != "undefined" ? jsPleaseWait : "Please wait..."); //shop form if (getDocObject('customSave')) getDocObject('customSave').innerHTML = pleaseWaitStr; if (getDocObject('customSaveNeedVia')) getDocObject('customSaveNeedVia').innerHTML = pleaseWaitStr; if (getDocObject('saveMyWorkForNow')) getDocObject('saveMyWorkForNow').innerHTML = pleaseWaitStr; if (getDocObject('saveMyWorkForNow2')) getDocObject('saveMyWorkForNow2').innerHTML = pleaseWaitStr; if (getDocObject('submitAndCreateNew')) getDocObject('submitAndCreateNew').innerHTML = pleaseWaitStr; if (getDocObject('submitAndPublish')) getDocObject('submitAndPublish').innerHTML = pleaseWaitStr; //shopperAcceptVisit form if (getDocObject('acceptDisp')) getDocObject('acceptDisp').innerHTML = pleaseWaitStr; if (getDocObject('cancelDisp')) getDocObject('cancelDisp').innerHTML = pleaseWaitStr; //shopperAppFull form if (getDocObject('submitApplication')) getDocObject('submitApplication').innerHTML = pleaseWaitStr; //shopperEditShopper if (getDocObject('saveChangesTop')) getDocObject('saveChangesTop').innerHTML = pleaseWaitStr; if (getDocObject('saveChangesBottom')) getDocObject('saveChangesBottom').innerHTML = pleaseWaitStr; return (false); } function flagInputError(inputName) { var e = getInputElement(inputName); if (e == null) return false; e.style.backgroundColor = "#ffb7b7"; } function clearInputError(inputName) { var e = getInputElement(inputName); if (e == null) return false; e.style.backgroundColor = ""; } function validateBasedataItem() { //check scoring options if shown var a = getInputElement("ActualMatchValues"); var p = getInputElement("PossibleMatchValues"); var o = getInputElement("ListOptions"); var listOptions = getInputElement("ListOptions"); var listOptionsUsers = getInputElement("ListOptionsUsers"); var listOptionsAliases = getInputElement("ListOptionsAliases"); var listOptionsUsersAliases = getInputElement("ListOptionsUsersAliases"); //num required options is determined on the form, but if listoptions/listoptionsuser is visible then we should always use the options in that var numoptions = 0; var listoptions = getInputElement("ListOptions"); if (listoptions != null) { numoptions = getMultiInputNumNonBlankAnswers("ListOptions") + getMultiInputNumNonBlankAnswers("ListOptionsUsers"); } else { numoptions = mParseFloat(getInputValue("jsNumAnswerOptions")); } var v = ""; clearInputError("ValidDependMatchValue3"); clearInputError("ValidDependBranch1Value3"); clearInputError("ValidDependBranch2Value3"); if (listOptions != null) clearInputError("ListOptions"); if (listOptionsAliases != null) clearInputError("ListOptionsAliases"); if (listOptionsUsers != null) clearInputError("ListOptionsUsers"); if (listOptionsUsersAliases != null) clearInputError("ListOptionsUsersAliases"); clearInputError("ActualMatchValues"); clearInputError("PossibleMatchValues"); //if aliases are shown, # of options must match # of aliases if (listOptions != null && listOptionsAliases != null) { if (getMultiInputNumNonBlankAnswers("ListOptions") != getMultiInputNumNonBlankAnswers("ListOptionsAliases")) { flagInputError("ListOptions"); flagInputError("ListOptionsAliases"); alert(jsWrongNumberAliases); return (false); } } if (listOptionsUsers != null && listOptionsUsersAliases != null) { if (getMultiInputNumNonBlankAnswers("ListOptionsUsers") != getMultiInputNumNonBlankAnswers("ListOptionsUsersAliases")) { flagInputError("ListOptionsUsers"); flagInputError("ListOptionsUsersAliases"); alert(jsWrongNumberAliases); return (false); } } //if shown, ActualMatchValues and PossibleMatchValues must have valid numbers in them... if (a != null) { v = checkMultiInputNumbers("ActualMatchValues"); if (v != "") { flagInputError("ActualMatchValues"); alert (jsValidateNumber.replace(/%value%/, v)); return (false); } } if (p != null) { v = checkMultiInputNumbers("PossibleMatchValues"); if (v != "") { flagInputError("PossibleMatchValues"); alert (jsValidateNumber.replace(/%value%/, v)); return (false); } } //... and also must equal the number of scores required by the number of answer options. if (a != null && numoptions > 0) { if (getMultiInputNumNonBlankAnswers("ActualMatchValues") != numoptions) { flagInputError("ActualMatchValues"); alert (jsWrongNumberScoringOptions); return(false); } } if (p != null && numoptions > 0) { if (getMultiInputNumNonBlankAnswers("PossibleMatchValues") != numoptions) { flagInputError("PossibleMatchValues"); alert (jsWrongNumberScoringOptions); return(false); } } //check numbers in dependency validation if present var d; d = getInputElement("ValidDependMatchValue3"); if (d != null) { v = checkMultiInputNumbers("ValidDependMatchValue3"); if (v != "") { flagInputError("ValidDependMatchValue3"); alert (jsValidateNumber.replace(/%value%/, v)); return (false); } } d = getInputElement("ValidDependBranch1Value3"); if (d != null) { v = checkMultiInputNumbers("ValidDependBranch1Value3"); if (v != "") { flagInputError("ValidDependBranch1Value3"); alert (jsValidateNumber.replace(/%value%/, v)); return (false); } } d = getInputElement("ValidDependBranch2Value3"); if (d != null) { v = checkMultiInputNumbers("ValidDependBranch2Value3"); if (v != "") { flagInputError("ValidDependBranch2Value3"); alert (jsValidateNumber.replace(/%value%/, v)); return (false); } } return true; } function refreshFormVisibilities() { var theForm = new mForm(); theForm.refreshVisibilities(); } function populateLastEditSkippedQuestions() { var theForm = new mForm(); theForm.populateLastEditSkippedQuestions(); } function submitShop() { isSubmitting = true; document.forms[0].isDraft.value = "0"; renameShopperSubmitControls(); if (getJSFormValidationVersion() >= 6) populateLastEditSkippedQuestions(); document.forms[0].submit(); }