/* 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 cdBuildFontIconElem cdBuildMnemonicLabelHTML cdBuildOpenDialogLabelCell ClientDialogModule consoleLog consoleLogBlockClose consoleLogBlockOpen displayTimedMessage FontIconId_Enum g_dcCustomDialogConfirmerElement g_dcForcedDirtyClass g_dcForceScan g_imageVersion getDateForUrlParam getObj hideDialog hideSubdialog htmlEncode htmlMultilineEncode jsrsExecuteWithErrorP MJTDictionary MWDateTime mwShowGenericReorderDialog pageIncludeRoot posLeft posTop setFocus StringificationUtils trim */ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //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 XZCommonUtils = function() { var _arrKeyDownHandlerFunctions = [], _keyDownHandlerNameToIndexMap = new MJTDictionary(), _arrKeyUpHandlerFunctions = [], _keyUpHandlerNameToIndexMap = new MJTDictionary(), TextBoxPositionMeaning_Enum = { tbpmCenter: 1, tbpmBottomCenter: 2 }; //-------------------------------------------------------------------------- //#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, tmpIsEmptyHours = trim(strRawHourValue) === '', tmpIsEmptyMinutes = trim(strRawMinuteValue) === '', tmpIsEmptySeconds = trim(strRawSecondValue) === '', tmpIsFullyEmpty = tmpIsEmptyHours && tmpIsEmptyMinutes && tmpIsEmptySeconds, tmpTotalSeconds = tmpIsFullyEmpty ? null : ((parseInt(strRawHourValue || '0', 10) || 0) * 60 * 60 + (parseInt(strRawMinuteValue || '0', 10) || 0) * 60 + (parseInt(strRawSecondValue || '0', 10) || 0)), rc = { hourElement: objHourElem, minuteElement: objMinuteElem, secondElement: objSecondElem, rawHourValue: strRawHourValue, rawMinuteValue: strRawMinuteValue, rawSecondValue: strRawSecondValue, totalSeconds: tmpTotalSeconds, 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 pbBuildDurationFields(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 + pbBuildDurationFields(params_) + strPostFieldsHtml + '' + '\n'; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function pbAddDurationFieldsRow(objCDBuilder_, params_) { objCDBuilder_.addDialogInteriorRows( pbBuildDurationFieldsRow(params_) ); } //-------------------------------------------------------------------------- // // Parameters: // // isExpanded: True if the section should initially be presented // as expanded. // // expandoTitleHtml: Html to be rendered to the right of the chevron // buttons. // // expandoElementIdBase: Optional base name to use for the elements that // comprise the expando section. // // expandedRowInfo: Optionally defines the row id and html content of // the section to be displayed when expanded. If this // is omitted, no row should be rendered for the // "Expanded" state. Object has two optional // parameters: // // rowId: If given, will be used as the id of // the row rendered when the expando // is expanded. If not given, the id // will be derived from the base, if // given. If there's no base either, // it will have a hard-coded id so // there better be only one such // expando visible at any given time // or they won't work. // // contentHtml: Optional content for the row. // Defaults to an empty string. // // // collapsedRowInfo: Optionally defines the row id and html content of // the section to be displayed when collapsed. If this // is omitted, no row should be rendered for the // "Collapsed" state. Object has two optional // parameters: "rowId" and "contentHtml". // // cdBuilder_: Optional ClientDialogBuilder. If given, the // section header row and whichever of the expanded/ // collapsed rows were given are added directly to // it (via addSectionHeaderRow()/addFlexibleRow()) // rather than being returned as html. // //-------------------------------------------------------------------------- var EXPANDO_SECTION_PREFIX_EXPAND_BUTTON_ID = 'expBtn_', EXPANDO_SECTION_PREFIX_COLLAPSE_BUTTON_ID = 'clpsBtn_', EXPANDO_SECTION_PREFIX_EXPANDED_SECTION_ID = 'expSec_', EXPANDO_SECTION_PREFIX_COLLAPSE_SECTION_ID = 'clpsSec_'; function pbBuildExpandoSection(params_) { var strExpandoElementIdBase = params_.expandoElementIdBase, tmpIsExpanded = params_.isExpanded, strExpandoTitleHtml = params_.expandoTitleHtml || '', objExpandedRowInfo = params_.expandedRowInfo, objCollapsedRowInfo = params_.collapsedRowInfo, objCdBuilder = params_.cdBuilder_, strDefaultedIdBase = strExpandoElementIdBase || '', strGivenExpandedRowId = (objExpandedRowInfo || {}).rowId, strExpandedRowContentHtml = (objExpandedRowInfo || {}).contentHtml || '', strGivenCollapsedRowId = (objCollapsedRowInfo || {}).rowId, strCollapsedRowContentHtml = (objCollapsedRowInfo || {}).contentHtml || '', strExpandedRowIdToUse = strGivenExpandedRowId || (EXPANDO_SECTION_PREFIX_EXPANDED_SECTION_ID + strDefaultedIdBase), strCollapsedRowIdToUse = strGivenCollapsedRowId || (EXPANDO_SECTION_PREFIX_COLLAPSE_SECTION_ID + strDefaultedIdBase), strExpandButtonIdToUse = (EXPANDO_SECTION_PREFIX_EXPAND_BUTTON_ID + strDefaultedIdBase), strCollapseButtonIdToUse = (EXPANDO_SECTION_PREFIX_COLLAPSE_BUTTON_ID + strDefaultedIdBase), // Plain icons rather than real buttons -- the entire header // (wrapped in the clickable span below) is what actually // triggers the toggle, so these are purely visual. Each is // wrapped in its own fixed-width "expandoIconHolder" (see // uiv2.scss) -- fiiRightChevron/fiiDownChevron don't render // at the same width, and hiding/showing an unwrapped icon // directly would shift expandoTitleHtml sideways when // toggled; the holder's ".collapsed" variant is narrower but // makes up the difference with a matching left margin, so // whichever single holder is actually in the layout (the // other has display:none, same as any hidden ClientDialog // row/element) always occupies the same total width. strExpandButtonHtml = '', strCollapseButtonHtml = '', // The actual row ids (which may have been overridden via // expandedRowInfo.rowId/collapsedRowInfo.rowId, rather than // derived from the base) are stashed on the header itself -- // ptToggleExpandoSection() reads them back from here rather // than re-deriving them from the base, since re-deriving // would miss any override. // tabindex/role make this a real tab stop with the expected // a11y semantics for a non-