/* eslint no-unused-vars: "off", eqeqeq: "off", no-useless-assignment: "off", no-empty: "off", no-dupe-else-if: "off", no-use-before-define: "off", no-eval: "off", no-alert: "off", no-global-assign: "off", no-self-assign: "off", no-useless-escape: "off", no-dupe-keys: "off", no-constant-condition: "off", no-unreachable: "off" */ /*global // ConsoleLogging.js ConsoleLogging // SharedFunctions.js htmlEncode // ShopSharedFunctions.js mjtElemData getObj setFocus */ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ var SZFocusUtils = function () { // TODO: Store prior value in the form-elem-data object, and most importantly, INITIALIZE IT! // (Otherwise, when editing existing item, simply tabbing to the field will auto-advance it) var FOCUS_INFO_BUNDLE_PROPERTY_NAME_PREFIX = 'szFocusBundle_', m_nextFieldDataUniquifierId = 1; //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvFocusInfoBundlePropertyName(uniquifierId_) { return FOCUS_INFO_BUNDLE_PROPERTY_NAME_PREFIX + uniquifierId_; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvGetAndAdvanceUniquifierId() { return m_nextFieldDataUniquifierId++; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvNumDecimalPlaces(value_){ var strValue = '' + value_, idxDecimal = strValue.indexOf('.'), tmpStrLen = strValue.length, rcDecimalCount = idxDecimal < 0 ? 0 : tmpStrLen - idxDecimal - 1; return rcDecimalCount; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function ptTestForAutoAdvanceField(params_) { ConsoleLogging.logBlockOpen('SZFocusUtils.ptTestForAutoAdvanceField()'); var strFormId = params_.formId, tmpUniquifierId = params_.uniquifierId, theForm = getObj(strFormId), objFormElemData = mjtElemData(theForm, 'formElemData'), strFocusInfoBundlePropertyName = pvFocusInfoBundlePropertyName( tmpUniquifierId), objFocusInfoBundle = objFormElemData[strFocusInfoBundlePropertyName], strFieldName = objFocusInfoBundle.fieldName, fnActionOnAdvance = objFocusInfoBundle.fnActionOnAdvance, strFollowingFocusFieldName = objFocusInfoBundle.followingFocusFieldName, tmpAdvanceIfGreaterThanIntVal = objFocusInfoBundle.advanceIfGreaterThanIntVal, tmpMaxDecimalPlaces = objFocusInfoBundle.maxDecimalPlaces, strPriorValue = objFocusInfoBundle.priorValue, objField = theForm[strFieldName], strValue = objField.value, tmpFloatVal = parseFloat(strValue), tmpIsValidFloat = !isNaN(tmpFloatVal), tmpIntValue = parseInt(strValue, 10), tmpIsValidInt = !isNaN(tmpIntValue), objFollowingField = strFollowingFocusFieldName ? theForm[strFollowingFocusFieldName] : null, tmpNumDecimalPlaces = pvNumDecimalPlaces(strValue), tmpDoAdvance = (tmpIsValidInt && tmpAdvanceIfGreaterThanIntVal && tmpIntValue && tmpIntValue > tmpAdvanceIfGreaterThanIntVal) || (tmpIsValidFloat && tmpMaxDecimalPlaces && tmpNumDecimalPlaces && tmpNumDecimalPlaces >= tmpMaxDecimalPlaces); ConsoleLogging.logObject({ tmpIsValidInt: tmpIsValidInt, tmpIntValue: tmpIntValue, tmpAdvanceIfGreaterThanIntVal: tmpAdvanceIfGreaterThanIntVal, tmpDoAdvance: tmpDoAdvance, strFollowingFocusFieldName: strFollowingFocusFieldName, is_objFollowingField: !!objFollowingField, tmpIsValidFloat: tmpIsValidFloat, tmpMaxDecimalPlaces: tmpMaxDecimalPlaces, tmpNumDecimalPlaces: tmpNumDecimalPlaces, params_: params_, strFocusInfoBundlePropertyName: strFocusInfoBundlePropertyName, objFocusInfoBundle: objFocusInfoBundle }); objFocusInfoBundle.priorValue = strValue; if (strPriorValue.length !== strValue.length) { if (tmpDoAdvance) { if (fnActionOnAdvance) { fnActionOnAdvance(); } else { setFocus(objFollowingField); } } } ConsoleLogging.logBlockClose(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbBuildOnChangeAttrValue(params_) { var strFormId = params_.formId, objFormElemData = params_.formElemData, strFieldName = params_.fieldName, tmpMaxDecimalPlaces = params_.maxDecimalPlaces, tmpAdvanceIfGreaterThanIntVal = params_.advanceIfGreaterThanIntVal, fnActionOnAdvance = params_.fnActionOnAdvance, strFollowingFocusFieldName = params_.followingFocusFieldName, strInitialValue = params_.initialValue, tmpUniquifierId = pvGetAndAdvanceUniquifierId(), objParams = { formId: strFormId, uniquifierId: tmpUniquifierId }, strEncodedParams = htmlEncode(JSON.stringify(objParams)), rcOnChangeAttrVal = "SZFocusUtils.PROTECTED.testForAutoAdvanceField(" + strEncodedParams + ")", strFocusInfoBundlePropertyName = pvFocusInfoBundlePropertyName(tmpUniquifierId), objFocusInfoBundle = { priorValue: strInitialValue || '', fieldName: strFieldName, maxDecimalPlaces: tmpMaxDecimalPlaces, advanceIfGreaterThanIntVal: tmpAdvanceIfGreaterThanIntVal, fnActionOnAdvance: fnActionOnAdvance, followingFocusFieldName: strFollowingFocusFieldName }; // Save off info to be used in the handler. objFormElemData[strFocusInfoBundlePropertyName] = objFocusInfoBundle; return rcOnChangeAttrVal; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- return { buildOnChangeAttrValue: pbBuildOnChangeAttrValue, PROTECTED: { testForAutoAdvanceField: ptTestForAutoAdvanceField } }; }(); /*global ConsoleLogging getDateForUrlParam ClientDialogModule consoleLog consoleLogBlockOpen consoleLogBlockClose g_dcCustomDialogConfirmerElement g_dcForcedDirtyClass g_dcForceScan htmlEncode htmlMultilineEncode trim cdBuildMnemonicLabelHTML cdBuildOpenDialogLabelCell displayTimedMessage MWDateTime posTop posLeft getObj setFocus hideDialog hideSubdialog jsrsExecuteWithErrorP mwShowGenericReorderDialog MJTDictionary g_imageVersion pageIncludeRoot */ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //function adjustAlphaIndexForScrollOrSize(adjustForAlphaIndexHeight_) { // var tmpWindow = $(window), // tmpWindowScrollTop = tmpWindow.scrollTop(), // tmpDivAlphaIndex = $("#divAlphaIndex"), // tmpAlphaIndexOffset = tmpDivAlphaIndex ? tmpDivAlphaIndex.offset() : 0, // tmpAlphaIndexOffsetTop = tmpAlphaIndexOffset ? tmpAlphaIndexOffset.top : 0, // objAlphaIndexTable = $('#tblAlphaIndex'), // tmpAlphaIndexTableHeight = objAlphaIndexTable ? objAlphaIndexTable.height() : 0, // objAlphaIndexCell = getObj('cellAlphaIndex'), // tmpWindowHeight = tmpWindow.height(), // tmpTblAlphaIndex = tmpDivAlphaIndex.closest("table"), // tmpTblOffset = tmpTblAlphaIndex.offset(); // if (!tmpTblOffset) { // return; // } // var tmpRecipeListContentTop = tmpTblOffset.top, // tmpRecipeListContentHeight = tmpTblAlphaIndex.height(); // if (adjustForAlphaIndexHeight_) { // if (objAlphaIndexCell && tmpRecipeListContentHeight < 1.5 * tmpWindow.height()) { // objAlphaIndexCell.style.display = 'none'; // } else { // objAlphaIndexCell.style.display = ''; // } // } // if (tmpAlphaIndexOffset) { // if (tmpWindowScrollTop + tmpWindowHeight > tmpRecipeListContentTop + tmpRecipeListContentHeight && // tmpAlphaIndexTableHeight > tmpWindowHeight) { // // The bottom has come on-screen and the index is larger than the screen, so stick // // it to the bottom. // getObj('tblAlphaIndex').style.position = 'fixed'; // getObj('tblAlphaIndex').style.top = ''; // getObj('tblAlphaIndex').style.bottom = '10px'; // } else if (tmpWindowScrollTop > tmpAlphaIndexOffsetTop) { // // We've scrolled down so that the area is up off the page, so stick the top of the index to the top of the page. // getObj('tblAlphaIndex').style.position = 'fixed'; // getObj('tblAlphaIndex').style.bottom = ''; // getObj('tblAlphaIndex').style.top = '0px'; // } else if (tmpAlphaIndexOffsetTop > tmpWindowScrollTop) { // // The top of the index section is below the top of the page, so stick it to the top of the parent... // getObj('tblAlphaIndex').style.position = 'relative'; // getObj('tblAlphaIndex').style.top = '0px'; // getObj('tblAlphaIndex').style.bottom = ''; // } // } //} ////------------------------------------------------------------------------------ ////------------------------------------------------------------------------------ //function setupStandardAlphaIndexHandlers() { // //var tmpWindow = $(window); // window.onscroll = // function () { // adjustAlphaIndexForScrollOrSize(0/*adjustForAlphaIndexHeight_*/); // }; // window.onresize = // function () { // adjustAlphaIndexForScrollOrSize(1/*adjustForAlphaIndexHeight_*/); // }; // adjustAlphaIndexForScrollOrSize(1/*adjustForAlphaIndexHeight_*/); //} //------------------------------------------------------------------------------ // // // arrCellIdsWithEditDoneColspans_: This is the list of any cells (in // additional rows) that will need their // colSpan values adjusted. // //------------------------------------------------------------------------------ //function toggleColumnsForEdit(editButtonId_, deleteButtonId_, startingCellIndex_, mandatoryColumnPrefix_, rbIdPrefix_, arrOptionalColumnPrefixes_, arrCellIdsWithEditDoneColspans_) { // var objEditButton = getObj(editButtonId_), // objDeleteButton = getObj(deleteButtonId_), // tmpNowEditing = objEditButton.innerHTML === 'Edit', // i, // j, // objMandatoryCell, // objOptionalCell, // strId, // tmpEditingSpan, // tmpDoneSpan, // arrCellSpanInfo; // if(objDeleteButton) { // objDeleteButton.style.display = tmpNowEditing ? '' : 'none'; // } // objEditButton.innerHTML = tmpNowEditing ? 'Done' : 'Edit'; // if(arrCellIdsWithEditDoneColspans_) { // for(i = 0; i < arrCellIdsWithEditDoneColspans_.length; ++i) { // arrCellSpanInfo = arrCellIdsWithEditDoneColspans_[i]; // strId = arrCellSpanInfo[0]; // tmpEditingSpan = arrCellSpanInfo[1]; // tmpDoneSpan = arrCellSpanInfo[2]; // getObj(strId).colSpan = tmpNowEditing ? tmpEditingSpan : tmpDoneSpan; // } // } // i = startingCellIndex_; // while(true) { // strId = mandatoryColumnPrefix_ + i; // objMandatoryCell = getObj(strId); // if(!objMandatoryCell) { // break; // } // if(rbIdPrefix_ && !tmpNowEditing) { // setCBChecked(rbIdPrefix_ + i/*id_*/, 0/*checked_*/); // } // objMandatoryCell.style.display = tmpNowEditing ? '' : 'none'; // if(arrOptionalColumnPrefixes_) { // for(j = 0; j < arrOptionalColumnPrefixes_.length; ++j) { // objOptionalCell = getObj(arrOptionalColumnPrefixes_[j] + i); // if(objOptionalCell) { // objOptionalCell.style.display = tmpNowEditing ? '' : 'none'; // } // } // } // ++i; // } //} //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //function isMobile() { // if(typeof g_isMobile === 'undefined') { // return false; // } // return !!g_isMobile; //} //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //function setDialogPositionForMediaAndOpen(dialogId_, forceTop_, complexCenterAdjustment_, forceLeft_) { // if (isMobile()) { // if (typeof forceTop_ == 'undefined') { // forceTop_ = true; // } // if (typeof forceLeft_ == 'undefined') { // forceLeft_ = true; // } // } // var tmpPosition, // objDialog = $("#" + dialogId_), // strLeft = (forceLeft_ || isNarrowScreen()) ? "left " : ""; // // if (forceTop_ || isNarrowScreen()) { // tmpPosition = { my: strLeft + "top", at: strLeft + "top", of: window }; // } else { // //tmpPosition = null;//{ my: "center", at: "center", of: window }; // tmpPosition = { my: strLeft + "center", at: strLeft + "center", of: window }; // } // // objDialog.dialog("open"); // if (complexCenterAdjustment_) { // objDialog.dialog("option", { position: { my: "left top", at: "left top", of: window } }); // setTimeout(function () { objDialog.dialog("option", { position: tmpPosition }); }, 10); // } else { // objDialog.dialog("option", { position: tmpPosition }); // } //} //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //function adjustDialogLayouts(objDialog_, arrWideFields_) { // var tmpWindowWidth = $(window).width(), // tmpObserveAlternateWidth = tmpWindowWidth > 550, // tmpDlgWidth = tmpObserveAlternateWidth ? Math.min(tmpWindowWidth - 44, 750) : 350, // tmpFieldWidth = tmpDlgWidth - (tmpObserveAlternateWidth ? 44 : 24), // idx; // // objDialog_.dialog({ width: tmpDlgWidth }); // for (idx = 0; idx < arrWideFields_.length; ++idx) { // arrWideFields_[idx].width(tmpFieldWidth); // } //} //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //function isNarrowScreen() { // return window.matchMedia && window.matchMedia("(max-width: 550px)").matches; //} //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //function isShortScreen() { // return window.matchMedia && window.matchMedia("(max-height: 500px)").matches; //} //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ var CommonUtils = function() { var _arrKeyDownHandlerFunctions = [], _keyDownHandlerNameToIndexMap = new MJTDictionary(), _arrKeyUpHandlerFunctions = [], _keyUpHandlerNameToIndexMap = new MJTDictionary(), TextBoxPositionMeaning_Enum = { tbpmCenter: 0, tbpmBottomCenter: 1 }; //-------------------------------------------------------------------------- //#region Dialog Confirmer class management //-------------------------------------------------------------------------- function pvFlagElementWithClass(params_) { var objTargetElement = params_.targetElement, tmpClearFlag = params_.clearFlag, strClassName = params_.className; if(objTargetElement) { if(tmpClearFlag) { objTargetElement.classList.remove(strClassName); } else { objTargetElement.classList.add(strClassName); } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvFlagElementWithDialogConfirmerClasses(params_) { var objTargetElement = params_.targetElement, arrClassToggleIndicators = params_.arrClassToggleIndicators; arrClassToggleIndicators.forEach(function(toggleIndicator_) { pvFlagElementWithClass({ targetElement: objTargetElement, clearFlag: toggleIndicator_.clearFlag, className: toggleIndicator_.className }); }); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbGetCustomConfirmationClass() { // Class indicates that the associated non-standard element should // be scanned for dirty flag return g_dcCustomDialogConfirmerElement; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbFlagElementForCustomDialogConfirmation(params_) { pvFlagElementWithClass({ targetElement: params_.targetElement, clearFlag: params_.clearFlag, // Class indicates that the associated non-standard element should // be scanned for dirty flag className: pbGetCustomConfirmationClass() }); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbGetForcedDirtyClass() { // Consider dirty even if no record of changes return g_dcForcedDirtyClass; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbFlagElementForcedDirty(params_) { pvFlagElementWithClass({ targetElement: params_.targetElement, clearFlag: params_.clearFlag, className: pbGetForcedDirtyClass() }); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbGetForcedScanClass() { // Scan even if hidden element return g_dcForceScan; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbFlagElementForcedScan(params_) { pvFlagElementWithClass({ targetElement: params_.targetElement, clearFlag: params_.clearFlag, // Scan even if hidden element className: pbGetForcedScanClass() }); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbFlagCustomElementForcedDirtyAndForcedScan(params_) { var objTargetElement = params_.targetElement, tmpClearForcedDirtyClass = params_.clearForcedDirtyClass; pvFlagElementWithDialogConfirmerClasses({ targetElement: objTargetElement, arrClassToggleIndicators: [ { className: pbGetCustomConfirmationClass() }, { className: pbGetForcedScanClass() }, { className: pbGetForcedDirtyClass(), clearFlag: tmpClearForcedDirtyClass } ] }); } //-------------------------------------------------------------------------- //#endregion Dialog Confirmer class management //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbNoOp() { } //-------------------------------------------------------------------------- // TODO: Add to FormValidator? ClientDialogModule? //-------------------------------------------------------------------------- function pbOptionallyValidateRequiredField(params_) { var objField = params_.field, objResultValueHolder = params_.resultValueHolder, tmpSuppressErrorMessage = params_.suppressErrorMessage, strRawMessage = params_.rawMessage, strRawValue = (objField || {}).value, rcIsValid; if(!objField) { if(!tmpSuppressErrorMessage) { ClientDialogModule.showDialogWithConsequence({ formTitle: 'Missing Field', simpleRowContentHtml: '
' + htmlMultilineEncode( 'Missing field for required field validation!\n\n' + strRawMessage) + '
', subdialogDismisalFocusFieldName: objField.name, subdialogDismisalFocusFieldId: objField.id }); } } else if(trim(strRawValue)) { rcIsValid = true; } else if(!tmpSuppressErrorMessage) { ClientDialogModule.showDialogWithConsequence({ formTitle: 'Missing Value', simpleRowContentHtml: '
' + htmlMultilineEncode(strRawMessage) + '
', subdialogDismisalFocusFieldName: objField.name, subdialogDismisalFocusFieldId: objField.id }); } objResultValueHolder.rawValue = strRawValue; objResultValueHolder.isValid; return rcIsValid; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbRefreshListContents() { displayTimedMessage('Reloading...'); window.location.reload(true); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbHideDialogAndRefreshListContents() { hideDialog(); pbRefreshListContents(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbHideDialogAndRefreshPage() { hideDialog(); displayTimedMessage('Refreshing Page...'); window.location.reload(false); // force_ } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbSelRBFocusField(rbId_, fieldId_) { var objRB = getObj(rbId_), objFld = getObj(fieldId_); if(objRB) { objRB.checked = true; } setFocus(objFld); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function pbGetDurationToNow(params_) { var theForm = params_.form, objResultsHolder = params_.durationResultsHolder || {}, strRaw24HourStartTime = params_.raw24HourStartTime, strDateFieldName = params_.dateFieldName, tmpTruncToTheMinute = params_.truncateToTheMinute; objResultsHolder.rcDuration = 0; objResultsHolder.durationTruncatedToTheMinute = tmpTruncToTheMinute; var objDate = strDateFieldName ? theForm[strDateFieldName] : null, rc; if(strDateFieldName && !objDate) { alert('setStopTime() - Couldn\'t get date field (name="' + strDateFieldName + '")'); return rc; } var strDate = objDate ? getDateForUrlParam(objDate.value) : '', objNow = new Date(), objEndTime = new Date( objNow.getFullYear(), objNow.getMonth(), objNow.getDate(), objNow.getHours(), objNow.getMinutes(), tmpTruncToTheMinute ? 0 : objNow.getSeconds(), 0), y = objEndTime.getFullYear(), mm = objEndTime.getMonth(), d = objEndTime.getDate(); if(strDate) { var arrDate = strDate.split('-'); y = parseInt(arrDate[0], 10); mm = parseInt(arrDate[1], 10) - 1; d = parseInt(arrDate[2], 10); } var arrStartTime = strRaw24HourStartTime.split(':'), tmpStartingHour = parseInt(arrStartTime[0], 10), tmpStartingMinute = parseInt(arrStartTime[1], 10), tmpStartingSecond = (arrStartTime.length > 2 && !tmpTruncToTheMinute) ? arrStartTime[2] : 0, tmpStartingMS = 0, objStartTime = new Date( y, mm, d, tmpStartingHour, tmpStartingMinute, tmpStartingSecond, tmpStartingMS); if(objStartTime > objEndTime) { alert('The start time is in the future!'); } else { var tmpStartMS = objStartTime.getTime(), tmpEndMS = objEndTime.getTime(), tmpDeltaMS = tmpEndMS - tmpStartMS, tmpDeltaSeconds = tmpTruncToTheMinute ? 0 : ((tmpDeltaMS - (tmpDeltaMS % 1000)) / (1000)), tmpSeconds = tmpDeltaSeconds % 60, tmpMinutes = ((tmpDeltaSeconds - tmpSeconds) / 60) % 60, tmpHours = (tmpDeltaSeconds - 60 * tmpMinutes - tmpSeconds) / (60 * 60); if(tmpHours * 60 + tmpMinutes > 60 * 18) { alert( "Can't have a duration > 18 hours!\n" + "\n" + "(Stopping now would result in a duration of " + tmpHours + " hours" + (tmpMinutes > 0 ? " and " + tmpMinutes + " minute" + (tmpMinutes > 1 ? "s" : "") : "") + (tmpTruncToTheMinute ? "" : (tmpSeconds > 0 ? " and " + tmpSeconds + " second" + (tmpSeconds > 1 ? "s" : "") : "")) + ".)"); } else { if(tmpHours === 0 && tmpMinutes === 0 && tmpTruncToTheMinute) { tmpMinutes = 1; } objResultsHolder.durationHours = tmpHours; objResultsHolder.durationMinutes = tmpMinutes; objResultsHolder.durationSeconds = tmpSeconds; rc = true; } } return rc; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function pvDecodeDurationFieldName(fieldName_) { var idxLastDot = fieldName_.lastIndexOf('.'), strFieldPrefix = fieldName_.substring(0, idxLastDot), strFieldSuffix = fieldName_.substring(idxLastDot + 1), tmpIsHour = strFieldSuffix === "h", tmpIsMinute = !tmpIsHour && strFieldSuffix === 'm', tmpIsSecond = !(tmpIsMinute || tmpIsHour); return { durationFieldNameBase: strFieldPrefix, isHour: tmpIsHour ? 1 : undefined, isMinute: tmpIsMinute ? 1 : undefined, isSecond: tmpIsSecond ? 1 : undefined }; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function pbDecodeDurationFields(params_) { var theForm = params_.form, strDurationFieldNameBase = params_.durationFieldNameBase, objHourElem = theForm[strDurationFieldNameBase + '.h'], objMinuteElem = theForm[strDurationFieldNameBase + '.m'], objSecondElem = theForm[strDurationFieldNameBase + '.s'], strRawHourValue = objHourElem ? objHourElem.value : '', strRawMinuteValue = objMinuteElem.value, strRawSecondValue = objSecondElem.value, rc = { hourElement: objHourElem, minuteElement: objMinuteElem, secondElement: objSecondElem, rawHourValue: strRawHourValue, rawMinuteValue: strRawMinuteValue, rawSecondValue: strRawSecondValue, combinedValue: '' }; if(strRawHourValue && strRawHourValue !== '00' && strRawHourValue !== '0') { rc.combinedValue = strRawHourValue + ':' + (strRawMinuteValue || '00') + ':' + (strRawSecondValue || '00'); } else if(strRawMinuteValue && strRawMinuteValue !== '00' && strRawMinuteValue !== '0') { rc.combinedValue = strRawMinuteValue + ':' + (strRawSecondValue || '00'); } else if(strRawSecondValue && strRawSecondValue !== '00' && strRawSecondValue !== '0') { rc.combinedValue = strRawSecondValue; } return rc; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function ptDurationChanged(field_, maxDigits_, followingFocusFieldName_) { maxDigits_ = maxDigits_ || 2; var objDecodedFieldName = pvDecodeDurationFieldName(field_.name), strDurationFieldNameBase = objDecodedFieldName.durationFieldNameBase, objDecodedDurationFields = pbDecodeDurationFields({ form: field_.form, durationFieldNameBase: strDurationFieldNameBase }), objHourElem = objDecodedDurationFields.hourElement, objMinuteElem = objDecodedDurationFields.minuteElement, objSecondElem = objDecodedDurationFields.secondElement, tmpIsHour = objDecodedFieldName.isHour, tmpIsMinute = objDecodedFieldName.isMinute, tmpIsSecond = objDecodedFieldName.isSecond, objUpdatedElem = tmpIsHour ? objHourElem : tmpIsMinute ? objMinuteElem : objSecondElem, theForm = objUpdatedElem.form, objFollowingFocusField = followingFocusFieldName_ && theForm ? theForm[followingFocusFieldName_] : null, strValue = objUpdatedElem.value, strPriorValue = objUpdatedElem.getAttribute('data-priorDurVal') || ''; objUpdatedElem.setAttribute('data-priorDurVal', strValue); if(strPriorValue.length !== strValue.length) { if(strValue.length > maxDigits_) { objUpdatedElem.value = strValue.substring(0, 2); } if(strValue.length === maxDigits_) { if(tmpIsHour) { setFocus(objMinuteElem); } else if(tmpIsMinute) { setFocus(objSecondElem); } else if(tmpIsSecond && objFollowingFocusField) { setFocus(objFollowingFocusField); } } else if((tmpIsMinute || tmpIsSecond) && strValue.length === 1) { if('6789'.indexOf(strValue) > -1) { // Can't possibly be a second digit, so move on... if(tmpIsMinute) { setFocus(objSecondElem); } else if(objFollowingFocusField) { setFocus(objFollowingFocusField); } } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function ptDurationKeyup(field_, maxDigits_, followingFocusFieldName_) { ptDurationChanged(field_, maxDigits_, followingFocusFieldName_); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvBuildDurationFields(params_) { var strDurationFieldNameBase = params_.durationFieldNameBase, strComposedFieldValue = params_.composedFieldValue, tmpOmitHours = params_.omitHours, strFollowingFocusFieldName = params_.followingFocusFieldName, strEncodedFollowingFocusFieldNameToUse = strFollowingFocusFieldName ? "'" + strFollowingFocusFieldName + "'" : 'undefined', strHoursFieldName = strDurationFieldNameBase + '.h', strMinutesFieldName = strDurationFieldNameBase + '.m', strSecondsFieldName = strDurationFieldNameBase + '.s', arrSplitFieldValue = strComposedFieldValue.split(':'), tmpSplitFieldCount = arrSplitFieldValue.length, strSeconds = arrSplitFieldValue[tmpSplitFieldCount - 1], strMinutes = tmpSplitFieldCount > 1 ? arrSplitFieldValue[tmpSplitFieldCount - 2] : '', strHours = tmpSplitFieldCount > 2 ? arrSplitFieldValue[tmpSplitFieldCount - 3] : '', strClassAttr = " class='clsDurationSubfield'", strHoursFieldHtml = '' + ' : ', rc; rc = (tmpOmitHours ? '' : strHoursFieldHtml) + '' + ' : ' + ''; return rc; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbBuildDurationFieldsRow(params_) { if(!params_) { params_ = {}; } var strRowId = params_.rowId, tmpHideRow = params_.hideRow, strAdditionalFieldRowClasses = params_.additionalFieldRowClasses, strAdditionalFieldCellClasses = params_.additionalFieldCellClasses, strAdditionalLabelCellClasses = params_.additionalLabelCellClasses, strFieldLabelId = params_.fieldLabelId, tmpSuppressLabelColon = params_.suppressLabelColon, strPreFieldsHtml = params_.preFieldsHtml || '', strPostFieldsHtml = params_.postFieldsHtml || '', strLabelHtml = cdBuildMnemonicLabelHTML(params_), strRowIdAttr = strRowId ? ' id="' + strRowId + '"' : '', strRowStyleAttr = tmpHideRow ? ' style="display:none"' : '', strFieldRowClassAttr = strAdditionalFieldRowClasses ? ' class="' + strAdditionalFieldRowClasses + '" ' : '', strFieldsCellClasses = trim('dialogFieldValue' + (strAdditionalFieldCellClasses ? ' ' + strAdditionalFieldCellClasses : '')), strFieldClassAttr = strFieldsCellClasses ? ' class="' + strFieldsCellClasses + '"' : ''; return '' + cdBuildOpenDialogLabelCell(strFieldLabelId, strAdditionalLabelCellClasses) + (strLabelHtml ? strLabelHtml + (tmpSuppressLabelColon ? '' : ':') : '') + '' + '' + strPreFieldsHtml + pvBuildDurationFields(params_) + strPostFieldsHtml + '' + '\n'; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbAddDurationFieldsRow(objCDBuilder_, params_) { objCDBuilder_.addDialogInteriorRows( pbBuildDurationFieldsRow(params_) ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbIsDialogWithIdShowing(id_) { return getObj(id_) ? true : false; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbIsTouchDevice() { return 'ontouchstart' in window || // works on most browsers navigator.maxTouchPoints; // works on IE10/11 and Surface } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbIsIOS() { return /iPad|iPhone|iPod/.test(navigator.platform); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbSelectFieldContent(obj_) { if(obj_) { try { if(obj_.setSelectionRange) { obj_.setSelectionRange(0, obj_.value.length); } } catch(e) { consoleLog('Error on setSelectionRange: e=' + e); try { if(obj_.select) { obj_.select(); } } catch(e2) { consoleLog('Error on select(): e2=' + e2); } } } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbSelectAndSetFocus(obj_) { pbSelectFieldContent(obj_); setFocus(obj_); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvFormatYMD(y_, m_, d_) { return y_ + '-' + (m_ < 10 ? '0' : '') + m_ + '-' + (d_ < 10 ? '0' : '') + d_; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbFormatDateObjectYMD(date_) { return pvFormatYMD( date_.getFullYear(), date_.getMonth() + 1, date_.getDate()); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbGetTodayAsYMD() { var tmpToday = new Date(); return pbFormatDateObjectYMD(tmpToday); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbGetYesterdayAsYMD() { var tmpToday = new Date(); return pbFormatDateObjectYMD( MWDateTime.getPreviousDay( tmpToday)); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbGetCBOValUsingSelIndex(cboElement_) { var tmpSelIndex = cboElement_.selectedIndex; return tmpSelIndex < 0 ? '' : cboElement_.options[tmpSelIndex].value; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbMultilineIndentEncodeJSONString(jsonString_) { var arrSplitLines = jsonString_.split(/\n/g), i; for(i = 0; i < arrSplitLines.length; ++i) { arrSplitLines[i] = htmlEncode(arrSplitLines[i]).replace(/^\s+/, function(m) { return m.replace(/\s/g, ' '); }); } return arrSplitLines.join('
'); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbHtmlEncodeWithColonBreaks(strRawText_) { var arrPieces = strRawText_.split(':'); for(var i = 0; i < arrPieces.length; ++i) { arrPieces[i] = htmlEncode(arrPieces[i]); } return arrPieces.join(':'); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbScrollItemWithIdIntoView(strId_) { var obj = getObj(strId_); if(obj) { obj.scrollIntoView(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvGetStyle(el_, style_) { var rc = ''; if(el_.currentStyle) { rc = el_.currentStyle[style_]; } else if(window.getComputedStyle) { rc = document.defaultView.getComputedStyle(el_, null).getPropertyValue(style_); } return rc; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbStartsWith(string_, prefix_) { var prefixLen = prefix_.length; return string_.length >= prefixLen && (string_.substring(0, prefixLen) === prefix_); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbEndsWith(string_, suffix_) { var suffixLen = suffix_.length, stringLen = string_.length; return stringLen >= suffixLen && (string_.substring(stringLen - suffixLen) === suffix_); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbClearGlass(glassId_) { var glass = getObj(glassId_ || 'cvsWeightGlass'), szGlass = [glass.clientWidth, glass.clientHeight], context = (glass && glass.getContext) ? glass.getContext('2d') : 0; if(context) { context.clearRect(0, 0, szGlass[0], szGlass[1]); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvSplitTriosWithCommas(string_) { string_ = '' + string_; var rc = ''; while(string_.length) { if(rc) { rc = ',' + rc; } if(string_.length > 3) { rc = string_.substring(string_.length - 3) + rc; string_ = string_.substring(0, string_.length - 3); } else { rc = string_ + rc; string_ = ''; } } return rc; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbAddCommasToDecimalNum(value_) { var arrDec = ('' + value_).split('.'), tmpPartCount = arrDec.length, strDecimalPiece = tmpPartCount === 2 ? ('.' + arrDec[1]) : ''; if(tmpPartCount > 2) { // Multiple decimals, so just return it as-is return '' + value_; } return pvSplitTriosWithCommas(arrDec[0]) + strDecimalPiece; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbPadDollars(params_) { var tmpDollarValue = params_.dollarValue, tmpOmitDecimals = params_.omitDecimals, tmpForceDecimalsWhenNone = params_.forceDecimalsWhenNone, tmpIncludeCommas = params_.includeCommas; if(typeof tmpDollarValue !== 'string') { tmpDollarValue = '' + tmpDollarValue; } tmpDollarValue = trim(tmpDollarValue).replace(new RegExp(',', 'g'), ''); var tmpLen = tmpDollarValue.length, tmpDecPos = tmpDollarValue.indexOf('.'); if(tmpDecPos < 0) { if(!tmpForceDecimalsWhenNone) { // Not forcing decimals when there aren't any... if(tmpIncludeCommas) { return pvSplitTriosWithCommas(tmpDollarValue); } return tmpDollarValue; } // No decimal point. Add one at the end. tmpDecPos = tmpLen; tmpDollarValue += '.'; ++tmpLen; } // By this point there is definitely a decimal point. // Make sure it is followed by at least 2 digits. while(tmpDecPos + 3 > tmpLen) { tmpDollarValue += '0'; ++tmpLen; } if(tmpOmitDecimals) { // Strip from the decimal on... tmpDollarValue = tmpDollarValue.substring(0, tmpDecPos); if(tmpIncludeCommas) { tmpDollarValue = pvSplitTriosWithCommas(tmpDollarValue); } } else { // Now remove any trailing zeros... var tmpNewLen = tmpLen; while((tmpDecPos + 3 < tmpNewLen) && tmpDollarValue[tmpNewLen - 1] === '0') { --tmpNewLen; } if(tmpNewLen !== tmpLen) { tmpDollarValue = tmpDollarValue.substring(0, tmpNewLen); } if(tmpIncludeCommas) { tmpDollarValue = pvSplitTriosWithCommas(tmpDollarValue.substring(0, tmpDecPos)) + tmpDollarValue.substring(tmpDecPos); } } return tmpDollarValue; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbPadDollarsX(dollarValue_, forceDecimalsWhenNone_, includeCommas_) { return pbPadDollars({ dollarValue: dollarValue_, forceDecimalsWhenNone: forceDecimalsWhenNone_, includeCommas: includeCommas_ }); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbIsNegDollarValue(value_) { return pbStartsWith('' + value_, '-'); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbNegateDollarValue(value_) { var rc = '' + value_; if(pbIsNegDollarValue(rc)) { rc = rc.substring(1); } else if(rc) { rc = '-' + rc; } return rc; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvSetCBChecked(id_, checked_) { var objCheck = getObj(id_), tmpAlreadyChecked = '1' === objCheck.getAttribute('data-checked'), objImg = getObj(id_ + '.img'), strSrc = pageIncludeRoot + 'graphics/' + (objCheck.getAttribute('data-' + (checked_ ? 'filledSrc' : 'emptySrc'))), objRow, strOldClass, strCurrClass; if((!tmpAlreadyChecked) === (!checked_)) { // No change. Don't do anything... return; } objRow = objCheck.parentNode; while(objRow && objRow.tagName !== 'TR') { objRow = objRow.parentNode; } if(objRow) { strOldClass = objRow.getAttribute('data-oldClassValue'); if(checked_) { strCurrClass = objRow.className; objRow.setAttribute('data-oldClassValue', strCurrClass); objRow.className = "highlight" + (strCurrClass ? ' ' + strCurrClass : ''); } else { objRow.className = strOldClass ? strOldClass : ''; } } objCheck.setAttribute('data-checked', checked_ ? '1' : '0'); objImg.src = strSrc + '?v=' + g_imageVersion; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbToggleCB(id_, fnToggle_) { var objCheck = getObj(id_), //objImg = getObj(id_ + '.img'), tmpWasChecked = '1' === objCheck.getAttribute('data-checked'); pvSetCBChecked(id_, !tmpWasChecked/*checked_*/); if(fnToggle_) { fnToggle_(); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function pbBuildArrayOfCBValues(startingIndex_, idPrefix_) { var i = startingIndex_, objCheck, strDataValue, rc = []; while(true) { objCheck = getObj(idPrefix_ + i); if(!objCheck) { break; } if('1' === objCheck.getAttribute('data-checked')) { strDataValue = objCheck.getAttribute('data-value'); rc[rc.length] = strDataValue; } ++i; } return rc; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbBuildWordBoundaryFilterFunction(searchText_, fnGetValue_) { var strEscapedSearchText = RegExp.quote(searchText_), regExp = new RegExp('(\\b|^)' + strEscapedSearchText + '.*', 'i'); return function(value_) { if(value_) { var strCurrent = fnGetValue_(value_); return regExp.test(strCurrent); } return false; }; } //-------------------------------------------------------------------------- // // Returns 1 if parses ok, 0 if not. // // If objRc_ is an object, will set: // // objRc_.parsedValue=parsed value as float // objRc_.rawValue=original string value. // //-------------------------------------------------------------------------- function pbParseMixedFraction(strValue_, objRc_) { if(objRc_) { objRc_.rawValue = strValue_; } strValue_ = trim(strValue_); //consoleLogBlockOpen('parseMixedFraction() - strValue_=' + strValue_); var patDecimal = new RegExp('^\\d+\\.?\\d*$'), rc = 0; if(patDecimal.test(strValue_)) { // consoleLog('It\'s a straight-up decimal!'); objRc_.parsedValue = parseFloat(strValue_); rc = 1; } else { //consoleLog('Not a straight-up decimal.'); var patFraction = new RegExp('^\\d+\\s*/\\s*\\d+$'), tmpIsFraction = patFraction.test(strValue_), patMixedFraction = new RegExp('^\\d+\\s+\\d+\\s*/\\s*\\d+$'), tmpIsMixedFraction = (!tmpIsFraction) && patMixedFraction.test(strValue_), tmpSlashPos = strValue_.indexOf('/'), tmpSpacePos = strValue_.indexOf(' '), strPreSlash, tmpInteger = 0, tmpNumerator, tmpDenominator; if(tmpIsFraction || tmpIsMixedFraction) { tmpDenominator = parseInt(trim(strValue_.substring(tmpSlashPos + 1)), 10); strPreSlash = trim(strValue_.substring(0, tmpSlashPos)); if(tmpIsMixedFraction) { tmpNumerator = parseInt(trim(strPreSlash.substring(tmpSpacePos + 1)), 10); tmpInteger = parseInt(trim(strPreSlash.substring(0, tmpSpacePos)), 10); } else { tmpNumerator = parseInt(strPreSlash, 10); } objRc_.parsedValue = tmpInteger + tmpNumerator / tmpDenominator; rc = 1; //consoleLog('Fractional value=' + objRc_.parsedValue); } else { //consoleLog('No good!'); } } //consoleLogBlockClose('parseMixedFraction()'); return rc; } //------------------------------------------------------------------------------ // // // "options_" is an object with the following optional properties: // // leftBound: // rightBound: When specified, text will be held within these bounds. // topBound: // bottomBound: // // boxPositionMeaning: Defaults to TextBoxPositionMeaning_Enum.tbpmCenter // // // Returns: { // rclBox: {pt: [x,y], sz: [cx,cy]} // rectangle for the entire // // box. // // arrTextLines_: [] // Array of strings, one for each piece // // of rendered text. // // // // If this is not a string, it should be // // an object of the form: // // // // { // // string: "", // // alignment: "left|right" // // } // // // } // //-------------------------------------------------------------------------- function pbDrawBoxedText(context_, arrTextLines_, ptPosition_, options_) { var strDefaultFont = options_.defaultFont || '14pt Calibri bold', strCurrFont = strDefaultFont; context_.font = strCurrFont; var tmpTextCount = arrTextLines_.length, objText, strText, tmpAlignRight, tmpTextWidth, tmpDeltaX, tmpTextHeight = context_.measureText('m').width, tmpDY = tmpTextHeight / 5, // Space between lines. tmpMaxTextWidth = 0, i, tmpCurrTextWidth, tmpBoxWidth, tmpBoxLeft, tmpBoxTop, tmpTextLeft, tmpTextTop, tmpCurrTextY, tmpBoxHeight = (tmpTextCount + 1) * tmpTextHeight + (tmpTextCount - 1) * tmpDY, tmpBoxPositionMeaning = TextBoxPositionMeaning_Enum.tbpmCenter, arrTextBoxes = [], rclBox = {}, rc = { rclBox: rclBox, arrTextBoxes: arrTextBoxes }; for(i = 0; i < tmpTextCount; ++i) { objText = arrTextLines_[i]; if(typeof objText === 'string') { strText = objText; } else { strText = objText.string; } strCurrFont = objText.font || strDefaultFont; if(context_.font !== strCurrFont) { context_.font = strCurrFont; } tmpCurrTextWidth = context_.measureText(strText).width; tmpMaxTextWidth = Math.max(tmpCurrTextWidth, tmpMaxTextWidth); } tmpBoxWidth = tmpMaxTextWidth + tmpTextHeight; if(options_ && Object.prototype.hasOwnProperty.call(options_, 'boxPositionMeaning')) { tmpBoxPositionMeaning = options_.boxPositionMeaning; } switch(tmpBoxPositionMeaning) { case -1: // Dummy to allow a switch break; case TextBoxPositionMeaning_Enum.tbpmBottomCenter: tmpBoxLeft = ptPosition_[0] - tmpMaxTextWidth / 2; tmpBoxTop = ptPosition_[1] - tmpBoxHeight; break; default: //TextBoxPositionMeaning_Enum.tbpmCenter: tmpBoxLeft = ptPosition_[0] - tmpMaxTextWidth / 2; tmpBoxTop = ptPosition_[1] - tmpBoxHeight / 2; break; } // Make sure the box is within bounds (if bounds have been specified) if(options_ && Object.prototype.hasOwnProperty.call(options_, 'rightBound')) { tmpBoxLeft = Math.min(tmpBoxLeft, options_.rightBound - tmpBoxWidth); } if(options_ && Object.prototype.hasOwnProperty.call(options_, 'leftBound')) { tmpBoxLeft = Math.max(tmpBoxLeft, options_.leftBound); } if(options_ && Object.prototype.hasOwnProperty.call(options_, 'bottomBound')) { tmpBoxTop = Math.min(tmpBoxTop, options_.topBound - tmpBoxHeight); } if(options_ && Object.prototype.hasOwnProperty.call(options_, 'topBound')) { tmpBoxTop = Math.max(tmpBoxTop, options_.topBound); } // Now calculate the text position given the box position...(margins are textHeight/2) tmpTextLeft = tmpBoxLeft + tmpTextHeight / 2; tmpTextTop = tmpBoxTop + tmpTextHeight / 2 + tmpTextHeight; tmpCurrTextY = tmpTextTop; rclBox.pt = [tmpBoxLeft, tmpBoxTop]; rclBox.sz = [tmpBoxWidth, tmpBoxHeight]; context_.beginPath(); context_.fillStyle = '#ffffff'; context_.fillRect(tmpBoxLeft, tmpBoxTop, tmpBoxWidth, tmpBoxHeight); context_.stroke(); context_.strokeStyle = '#000'; context_.strokeRect(tmpBoxLeft, tmpBoxTop, tmpBoxWidth, tmpBoxHeight); context_.stroke(); context_.fillStyle = '#000000'; for(i = 0; i < tmpTextCount; ++i) { objText = arrTextLines_[i]; if(typeof objText === 'string') { strText = objText; tmpAlignRight = 0; strCurrFont = strDefaultFont; } else { strText = objText.string; tmpAlignRight = 'right' === objText.alignment; strCurrFont = objText.font || strDefaultFont; } if(context_.font !== strCurrFont) { context_.font = strCurrFont; } tmpTextWidth = context_.measureText(strText).width; if(tmpAlignRight) { tmpDeltaX = tmpMaxTextWidth - tmpTextWidth; } else { tmpDeltaX = 0; } if(objText.color) { context_.fillStyle = objText.color; } else { context_.fillStyle = '#000000'; } context_.beginPath(); context_.fillText(strText, tmpTextLeft + tmpDeltaX, tmpCurrTextY); context_.stroke(); var rclText = { pt: [tmpTextLeft + tmpDeltaX, tmpCurrTextY - (tmpTextHeight)], // remove text offset sz: [tmpTextWidth, tmpTextHeight + tmpDY] // Add padding }; arrTextBoxes.push(rclText); tmpCurrTextY += tmpTextHeight + tmpDY; } return rc; } //function removeHandler(arrHandlers_, nameToIndexMap_, name_) { // var idxHandler = nameToIndexMap_.item(name_); // if(idxHandler) { // nameToIndexMap_.removeItemWithKey(name_); // arrHandlers_[idxHandler] = 0; // } //} //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbAddHandler(arrHandlers_, nameToIndexMap_, name_, fnHandler_) { //ConsoleLogging.logBlockOpen('CommonUtils::pbAddHandler()'); //ConsoleLogging.logObject({ // what: 'Adding a handler', // name_: ConsoleLogging.undefinedStringIfUndefined(name_) //}); var idxExisting = nameToIndexMap_.item(name_); if(idxExisting) { arrHandlers_[idxExisting].fnHandler = fnHandler_; } else { arrHandlers_.push({ name: name_, fnHandler: fnHandler_ }); nameToIndexMap_.add(name_, arrHandlers_.length - 1); } //ConsoleLogging.logBlockClose(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbAddKeyDownHandler(name_, fnHandler_) { //ConsoleLogging.logBlockOpen('CommonUtils::pbAddKeyDownHandler()'); pbAddHandler(_arrKeyDownHandlerFunctions, _keyDownHandlerNameToIndexMap, name_, fnHandler_); //ConsoleLogging.logBlockClose(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbAddKeyUpHandler(name_, fnHandler_) { //ConsoleLogging.logBlockOpen('CommonUtils::pbAddKeyUpHandler()'); pbAddHandler(_arrKeyUpHandlerFunctions, _keyUpHandlerNameToIndexMap, name_, fnHandler_); //ConsoleLogging.logBlockClose(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvIterateHandlers(arrHandlers_, event, isEscape_, isTabKey_, keyCode_, isShiftDown_, isAltDown_, isCtrlDown_, objTarget_) { //ConsoleLogging.logBlockOpen('CommonUtils::pvIterateHandlers()'); var rc = 0, i, objFn; for(i = 0; (i < arrHandlers_.length) && !rc; ++i) { objFn = arrHandlers_[i]; if(objFn) { //ConsoleLogging.logObject({ // what: 'Executing handler', // i: i, // objFn__name: ConsoleLogging.undefinedStringIfUndefined(objFn.name) //}); rc = objFn.fnHandler(event, isEscape_, isTabKey_, keyCode_, isShiftDown_, isAltDown_, isCtrlDown_, objTarget_); } } //ConsoleLogging.logBlockClose(); return rc; } //------------------------------------------------------------------------------ // TODO: Why is this here? When would/did we ever use it? //------------------------------------------------------------------------------ function pbIsShiftOnEvent(event_) { consoleLogBlockOpen('isShiftOnEvent()'); if(window.event) { consoleLog('Using window.event.shiftKey=' + window.event.shiftKey); consoleLogBlockClose(); return window.event.shiftKey; } else if(event_) { consoleLog('Using event_.shiftKey=' + event_.shiftKey); consoleLogBlockClose(); return event_.shiftKey; } consoleLog('neither'); consoleLogBlockClose(); return 0; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvBaseDoKeyDown(event) { //ConsoleLogging.logBlockOpen('CommonUtils::pvBaseDoKeyDown()'); var objTarget, isShiftDown, isAltDown, isCtrlDown, keyCode, isEscape, isTabKey; try { if(window.event) { objTarget = window.event.target; isShiftDown = window.event.shiftKey; isAltDown = window.event.altKey; isCtrlDown = window.event.ctrlKey; keyCode = window.event.keyCode; } else if(event) { objTarget = event.target; isShiftDown = event.shiftKey; isAltDown = event.altKey; isCtrlDown = event.ctrlKey; keyCode = event.which; } if(!isAltDown && !isCtrlDown) { isTabKey = keyCode === 9; isEscape = keyCode === 27; } // eslint-disable-next-line no-unused-vars } catch(e) { // ignore error ConsoleLogging.logBlockClose('error'); return; } if(pvIterateHandlers(_arrKeyDownHandlerFunctions, event, isEscape, isTabKey, keyCode, isShiftDown, isAltDown, isCtrlDown, objTarget)) { //ConsoleLogging.logBlockClose('iterate-true'); return false; } //ConsoleLogging.logBlockClose(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvBaseDoKeyUp(event) { var objTarget, isShiftDown, isAltDown, isCtrlDown, isEscape, keyCode, isTabKey; try { if(window.event) { objTarget = window.event.target; isShiftDown = window.event.shiftKey; isAltDown = window.event.altKey; isCtrlDown = window.event.ctrlKey; keyCode = window.event.keyCode; } else if(event) { objTarget = event.target; isShiftDown = event.shiftKey; isAltDown = event.altKey; isCtrlDown = event.ctrlKey; keyCode = event.which; } if(!isAltDown && !isCtrlDown) { isTabKey = keyCode === 9; isEscape = keyCode === 27; } // eslint-disable-next-line no-unused-vars } catch(e) { // ignore error return; } if(pvIterateHandlers(_arrKeyUpHandlerFunctions, event, isEscape, isTabKey, keyCode, isShiftDown, isAltDown, isCtrlDown, objTarget)) { return false; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbBaseInitKeyboard() { //ConsoleLogging.logBlockOpen('CommonUtils::pbBaseInitKeyboard()'); document.onkeydown = pvBaseDoKeyDown; document.onkeyup = pvBaseDoKeyUp; //ConsoleLogging.logBlockClose(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbShowReorderObjectsDialog(objectId_, rawObjectName_, reorderCommandName_, fnOnReorder_, strDialogTitle_, objRSParams_, fnExtractHtmlNameFromRow_) { var arrReorderRows = document.querySelectorAll('.clsReorderRow'), objRow, idx, arrIdNames = [], strName; for(idx = 0; idx < arrReorderRows.length; ++idx) { objRow = arrReorderRows[idx]; if(fnExtractHtmlNameFromRow_) { strName = fnExtractHtmlNameFromRow_(objRow); } else { strName = unescape(objRow.getAttribute('data-name')); } arrIdNames.push( { id: objRow.getAttribute('data-id'), name: strName }); } objRSParams_ = objRSParams_ || {}; mwShowGenericReorderDialog( arrIdNames, function(arrOrderedIds_) { objRSParams_.ids = arrOrderedIds_.join(','); jsrsExecuteWithErrorP( reorderCommandName_, // commandString_ function() { hideSubdialog(); fnOnReorder_(); }, // fnCallback_ 'Re-Ordering ' + rawObjectName_, // doingWhat_ objRSParams_ || {}); // payloadDocument_ }, // fnReOrder_, strDialogTitle_, { highlightedId: objectId_, isHtmlEncoded: fnExtractHtmlNameFromRow_ ? 1 : 0 }); // params_ } //-------------------------------------------------------------------------- // // Adds two vectors // //-------------------------------------------------------------------------- function pvAddV(v1_, v2_) { return [v1_[0] + v2_[0], v1_[1] + v2_[1]]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvHitTestRect(pt_, rect_) { var rc = 0, ptBottomRight = CommonUtils.addV(rect_.pt, rect_.sz); if (pt_[0] >= rect_.pt[0]) { if (pt_[1] >= rect_.pt[1]) { if (pt_[0] <= ptBottomRight[0]) { if (pt_[1] <= ptBottomRight[1]) { rc = 1; } } } } return rc; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pvUpdatePos(x, y, posRelativeElement) { var rc; y = y - posTop(posRelativeElement/*ob_*/, 1/*accountForScrollTop_*/); x = x - posLeft(posRelativeElement/*ob_*/, 1/*accountForScrollLeft_*/); while (posRelativeElement) { var strBorderLeftWidth = pvGetStyle(posRelativeElement, 'border-left-width'), strBorderTopWidth = pvGetStyle(posRelativeElement, 'border-top-width'), deltaBorderX = strBorderLeftWidth && pbEndsWith(strBorderLeftWidth, 'px') ? parseInt(strBorderLeftWidth.substring(0, strBorderLeftWidth.length - 2), 10) : 0, deltaBorderY = strBorderTopWidth && pbEndsWith(strBorderTopWidth, 'px') ? parseInt(strBorderTopWidth.substring(0, strBorderTopWidth.length - 2), 10) : 0; x -= deltaBorderX; y -= deltaBorderY; posRelativeElement = posRelativeElement.offsetParent; } rc = [x, y]; return rc; // **** Account for the canvas border } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbUpdateEventPos(e_, posRelativeElement) { var x, y; // Get the mouse position relative to the canvas element. if (e_.touches) { // iPad var targetItem = e_.touches.item(0); x = targetItem.pageX;// - e_.target.offsetLeft - e_.target.offsetParent.offsetLeft; y = targetItem.pageY;// - e_.target.offsetTop - e_.target.offsetParent.offsetTop; } else { x = e_.pageX; y = e_.pageY; } return pvUpdatePos(x, y, posRelativeElement); } //-------------------------------------------------------------------------- // // date1_ and date2_ are javascript Date objects // //-------------------------------------------------------------------------- function pvDateDiffInDays(date1_, date2_) { //consoleLog('dateDiffInDays() - date1_=' + date1_ + ', date2_=' + date2_); var MS_PER_DAY = 1000 * 60 * 60 * 24, // Discard the time and time-zone information. utc1 = Date.UTC(date1_.getFullYear(), date1_.getMonth(), date1_.getDate()), utc2 = Date.UTC(date2_.getFullYear(), date2_.getMonth(), date2_.getDate()); return Math.floor((utc2 - utc1) / MS_PER_DAY); } //-------------------------------------------------------------------------- // CommonUtils //-------------------------------------------------------------------------- return { optionallyValidateRequiredField: pbOptionallyValidateRequiredField, refreshListContents: pbRefreshListContents, hideDialogAndRefreshListContents: pbHideDialogAndRefreshListContents, hideDialogAndRefreshPage: pbHideDialogAndRefreshPage, selRBFocusField: pbSelRBFocusField, getDurationToNow: pbGetDurationToNow, decodeDurationFields: pbDecodeDurationFields, buildDurationFieldsRow: pbBuildDurationFieldsRow, addDurationFieldsRow: pbAddDurationFieldsRow, isDialogWithIdShowing: pbIsDialogWithIdShowing, isTouchDevice: pbIsTouchDevice, isIOS: pbIsIOS, selectFieldContent: pbSelectFieldContent, selectAndSetFocus: pbSelectAndSetFocus, formatDateObjectYMD: pbFormatDateObjectYMD, getTodayAsYMD: pbGetTodayAsYMD, getYesterdayAsYMD: pbGetYesterdayAsYMD, getCBOValUsingSelIndex: pbGetCBOValUsingSelIndex, multilineIndentEncodeJSONString: pbMultilineIndentEncodeJSONString, htmlEncodeWithColonBreaks: pbHtmlEncodeWithColonBreaks, scrollItemWithIdIntoView: pbScrollItemWithIdIntoView, startsWith: pbStartsWith, endsWith: pbEndsWith, clearGlass: pbClearGlass, addCommasToDecimalNum: pbAddCommasToDecimalNum, padDollars: pbPadDollars, padDollarsX: pbPadDollarsX, noOp: pbNoOp, isNegDollarValue: pbIsNegDollarValue, negateDollarValue: pbNegateDollarValue, toggleCB: pbToggleCB, buildArrayOfCBValues: pbBuildArrayOfCBValues, buildWordBoundaryFilterFunction: pbBuildWordBoundaryFilterFunction, parseMixedFraction: pbParseMixedFraction, drawBoxedText: pbDrawBoxedText, TextBoxPositionMeaning_Enum: TextBoxPositionMeaning_Enum, addKeyDownHandler: pbAddKeyDownHandler, addKeyUpHandler: pbAddKeyUpHandler, isShiftOnEvent: pbIsShiftOnEvent, baseInitKeyboard: pbBaseInitKeyboard, showReorderObjectsDialog: pbShowReorderObjectsDialog, addV: pvAddV, hitTestRect: pvHitTestRect, //updatePos: pbUpdatePos, updateEventPos: pbUpdateEventPos, dateDiffInDays: pvDateDiffInDays, //-------------------------------------------------------------------------- //#region Dialog Confirmer class management //-------------------------------------------------------------------------- getCustomConfirmationClass: pbGetCustomConfirmationClass, flagElementForCustomDialogConfirmation: pbFlagElementForCustomDialogConfirmation, getForcedDirtyClass: pbGetForcedDirtyClass, flagElementForcedDirty: pbFlagElementForcedDirty, getForcedScanClass: pbGetForcedScanClass, flagElementForcedScan: pbFlagElementForcedScan, flagCustomElementForcedDirtyAndForcedScan: pbFlagCustomElementForcedDirtyAndForcedScan, //-------------------------------------------------------------------------- //#endregion Dialog Confirmer class management //-------------------------------------------------------------------------- PROTECTED: { durationChanged: ptDurationChanged, durationKeyup: ptDurationKeyup } }; }();