/*! * CommonScript.js v1.0.1 - 2024-02-11 */ function setDateTimeFieldValue(fieldId, dateValue) { var $submitField = $("#" + fieldId); var $displayField = $submitField.nextAll(".datetimepicker").children("input"); var dateFormat = $displayField.attr("data-date-format"); $submitField.val(moment.utc(dateValue).format("YYYY-MM-DDTHH:mm:ss.SSSSSSS")); $displayField.val(moment(dateValue).format(dateFormat)); } function setLookupField(fieldName, entityId, entityName, recordLabel) { $("#" + fieldName).val(entityId); $("#" + fieldName + "_name").val(recordLabel); $("#" + fieldName + "_entityname").val(entityName); $("#" + fieldName).addClass("dirty"); } function setTextFieldsToEmpty(fieldsToClear) { for (let x = 0; x < fieldsToClear.length; x++) { $("#" + fieldsToClear[x]).val(""); } } function onChangeOfField(fieldName, functionName) { $("#" + fieldName).on("change", functionName); } function hideElementById(fieldId, selectedValue, listOfIdsToHide) { var fieldValue = $("#" + fieldId).val(); if (fieldValue == selectedValue) { if (listOfIdsToHide != null) { for (let x = 0; x < listOfIdsToHide.length; x++) { $("#" + listOfIdsToHide[x]).hide(); } } } } function hideFields(fieldsToHide) { for (let x = 0; x < fieldsToHide.length; x++) { $("#" + fieldsToHide[x]) .closest("td") .hide(); } } function showFields(fieldsToShow) { for (let x = 0; x < fieldsToShow.length; x++) { $("#" + fieldsToShow[x]) .closest("td") .show(); } } function hideFieldsWhenChecked(checkboxId, fieldsToHide) { if ($("#" + checkboxId).is(":checked")) { for (let x = 0; x < fieldsToHide.length; x++) { $("#" + fieldsToHide[x]) .closest("td") .hide(); } } else { for (let x = 0; x < fieldsToHide.length; x++) { $("#" + fieldsToHide[x]) .closest("td") .show(); } } } function showFieldsWhenChecked(checkboxId, fieldsToShow) { if ($("#" + checkboxId).is(":checked")) { for (let x = 0; x < fieldsToShow.length; x++) { $("#" + fieldsToShow[x]) .closest("td") .show(); } } else { for (let x = 0; x < fieldsToShow.length; x++) { $("#" + fieldsToShow[x]) .closest("td") .hide(); } } } function hideAndShowFieldsWhenValueSelected( fieldId, selectedValue, fieldsToHide, fieldsToShow ) { var fieldValue = $("#" + fieldId).val(); if (fieldValue == selectedValue) { if (fieldsToHide != null) { for (let x = 0; x < fieldsToHide.length; x++) { $("#" + fieldsToHide[x]) .closest("td") .hide(); } } if (fieldsToShow != null) { for (let x = 0; x < fieldsToShow.length; x++) { $("#" + fieldsToShow[x]) .closest("td") .show(); } } } } function hideSectionForSpecifiedValue(fieldId, selectedValue, sectionsToHide) { var fieldValue = $("#" + fieldId).val(); if (fieldValue == selectedValue) { if (sectionsToHide != null) { for (let x = 0; x < sectionsToHide.length; x++) { $("table[data-name='" + sectionsToHide[x] + "']") .parent() .hide(); } } } } function hideSections(sectionsToHide) { if (sectionsToHide != null) { for (let x = 0; x < sectionsToHide.length; x++) { $("table[data-name='" + sectionsToHide[x] + "']") .parent() .hide(); } } } function showSections(sectionsToShow) { if (sectionsToShow != null) { for (let x = 0; x < sectionsToShow.length; x++) { $("table[data-name='" + sectionsToShow[x] + "']") .parent() .show(); } } } function hideAndShowOptionSetValues( fieldId, listOfValuesToHide, listOfValuesToShow ) { var fieldValue = $("#" + fieldId); if (fieldValue != undefined) { if (listOfValuesToHide != null) { for (let x = 0; x < listOfValuesToHide.length; x++) { if ($("#" + fieldId).is("select")) { // is dropdown $( "#" + fieldId + " option[value=" + listOfValuesToShow[x] + "]" ).show(); } else if ($("#" + fieldId).is("span")) { // handle vertical list metadata render let $optionElement = $( "#" + fieldId + " [value=" + listOfValuesToShow[x] + "]" ); // hide option $optionElement.show(); // hide label $optionElement.next("label").show(); $optionElement.next("label").next("br").show(); } } } } } function removeValidatorsForSpecifiedValue(fieldId, selectedValue, fieldNames) { var fieldValue = $("#" + fieldId).val(); if (fieldValue == selectedValue) { for (let x = 0; x < fieldNames.length; x++) { var fieldName = fieldNames[x]; if (typeof Page_Validators == "undefined") return; if ($("#RequiredFieldValidator" + fieldName) != undefined) { $("#RequiredFieldValidator" + fieldName).remove(); } if ($("#" + fieldName) != undefined) { $("#" + fieldName) .closest(".control") .prev() .removeClass("required"); $("#" + fieldName).prop("required", false); for (i = 0; i < Page_Validators.length; i++) { if (Page_Validators[i].id == "RequiredFieldValidator" + fieldName) { Page_Validators.splice(i, 1); } } } } } } function removeValidators(fieldNames) { for (let x = 0; x < fieldNames.length; x++) { var fieldName = fieldNames[x]; if (typeof Page_Validators == "undefined") return; if ($("#RequiredFieldValidator" + fieldName) != undefined) { $("#RequiredFieldValidator" + fieldName).remove(); } if ($("#" + fieldName) != undefined) { $("#" + fieldName) .closest(".control") .prev() .removeClass("required"); $("#" + fieldName).prop("required", false); for (i = 0; i < Page_Validators.length; i++) { if (Page_Validators[i].id == "RequiredFieldValidator" + fieldName) { Page_Validators.splice(i, 1); } } } } } function removeCustomValidators(validatorIds) { for (let x = 0; x < validatorIds.length; x++) { var validatorId = validatorIds[x]; if (typeof Page_Validators == "undefined") return; if ($("#" + validatorId) != undefined) { $("#" + validatorId).remove(); } if ($("#" + validatorId) != undefined) { $("#" + validatorId) .closest(".control") .prev() .removeClass("required"); $("#" + validatorId).prop("required", false); for (i = 0; i < Page_Validators.length; i++) { if (Page_Validators[i].id == validatorId) { Page_Validators.splice(i, 1); } } } } } function addValidatorForSpecifiedValue( fieldId, selectedValue, fieldNamesAndLabels ) { var fieldValue = $("#" + fieldId).val(); if (fieldValue == selectedValue) { for (let x = 0; x < fieldNamesAndLabels.length; x++) { var fieldNameAndLabel = fieldNamesAndLabels[x]; var fieldName = fieldNameAndLabel[0]; var fieldLabel = fieldNameAndLabel[1]; var preCreatedValidator = false; if (typeof Page_Validators == "undefined") return; for (i = 0; i < Page_Validators.length; i++) { if (Page_Validators[i].id == "RequiredFieldValidator" + fieldName) { preCreatedValidator = true; break; } } if (preCreatedValidator == true) { continue; } // Create new validator $("#" + fieldName + "_label") .parent() .addClass("required"); var newValidator = document.createElement("span"); newValidator.style.display = "none"; newValidator.id = "RequiredFieldValidator" + fieldName; newValidator.controltovalidate = "casetypecode"; newValidator.errormessage = "" + fieldLabel + " is a mandatory field."; newValidator.validationGroup = ""; newValidator.initialvalue = ""; newValidator.evaluationfunction = function (fieldName) { var validatorId = fieldName.id; validatorId = validatorId.replace("RequiredFieldValidator", ""); var value = GetValidatorValue(validatorId); if (value == null || value == "") { return false; } else { return true; } }; // Add the new validator to the page validators array: Page_Validators.push(newValidator); // Wire-up the click event handler of the validation summary link $("a[href='#" + fieldName + "_label']").on("click", function () { scrollToAndFocus(fieldName + "_label", fieldName); }); } } } function addValidator(fieldNamesAndLabels) { for (let x = 0; x < fieldNamesAndLabels.length; x++) { var fieldNameAndLabel = fieldNamesAndLabels[x]; var fieldName = fieldNameAndLabel[0]; var fieldLabel = fieldNameAndLabel[1]; var preCreatedValidator = false; if (typeof Page_Validators == "undefined") return; for (i = 0; i < Page_Validators.length; i++) { if (Page_Validators[i].id == "RequiredFieldValidator" + fieldName) { preCreatedValidator = true; break; } } if (preCreatedValidator == true) { continue; } // Create new validator $("#" + fieldName + "_label") .parent() .addClass("required"); var newValidator = document.createElement("span"); newValidator.style.display = "none"; newValidator.id = "RequiredFieldValidator" + fieldName; newValidator.controltovalidate = "casetypecode"; newValidator.errormessage = "" + fieldLabel + " is a mandatory field."; newValidator.validationGroup = ""; newValidator.initialvalue = ""; newValidator.evaluationfunction = function (fieldName) { var validatorId = fieldName.id; validatorId = validatorId.replace("RequiredFieldValidator", ""); var value = GetValidatorValue(validatorId); if (value == null || value == "") { return false; } else { return true; } }; // Add the new validator to the page validators array: Page_Validators.push(newValidator); // Wire-up the click event handler of the validation summary link $("a[href='#" + fieldName + "_label']").on("click", function () { scrollToAndFocus(fieldName + "_label", fieldName); }); } } function GetValidatorValue(id) { var control; control = document.getElementById(id); if (typeof control.value == "string") { return control.value; } return GetValidatorValueRecursive(control); } function GetValidatorValueRecursive(control) { if ( typeof control.value == "string" && (control.type != "radio" || control.checked == true) ) { return control.value; } var i, val; for (i = 0; i < control.childNodes.length; i++) { val = ValidatorGetValueRecursive(control.childNodes[i]); if (val != "") return val; } return ""; } /** * Formats the given number into a '$x.xx' formatted string. * * @param {number} amount The amount to format. */ function transformIntoCurrencyFormat(amount) { if (isNaN(amount)) { amount = 0; F; } return "$" + amount.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); } /** * Converts a Microsoft.Xrm.Sdk.Money data-type string into a number. * * @param {string} value The input to convert. */ function convertMoneyStringToNumber(value) { value = value.replace("$", "").replace(/,/g, ""); if (value.indexOf("(") > -1) { // contains () which signifies a negative number value = value.replace("(", "").replace(")", ""); value *= -1; } var amt = parseFloat(value); return !isNaN(amt) ? amt : 0; } function displayErrorAlert(errorMessage) { var $container = $(".notifications"); if ($container.length == 0) { var $pageheader = $(".page-heading"); if ($pageheader.length == 0) { $container = $("
").prependTo( $("#content-container") ); } else { $container = $("
").appendTo($pageheader); } } $container.find(".notification").slideUp().remove(); var $alert = $( " " ) .on("closed.bs.alert", function () { if ($container.find(".notification").length == 0) { $container.hide(); } }) .prependTo($container); $container.show(); $("html, body").animate( { scrollTop: $alert.offset().top - 20, }, 200 ); } function customValidator(id, control, errorMessage, evaluationFunction) { if (typeof Page_Validators == "undefined") return; var newValidator = document.createElement("span"); newValidator.style.display = "none"; newValidator.id = id; newValidator.controltovalidate = control; newValidator.errormessage = "" + errorMessage + ""; newValidator.validationGroup = ""; newValidator.initialvalue = ""; newValidator.evaluationfunction = function () { var result = evaluationFunction(); return result; }; // Add the new validator to the page validators array: Page_Validators.push(newValidator); // Wire-up the click event handler of the validation summary link $("a[href='#" + control + "_label']").on("click", function () { scrollToAndFocus(control + "_label", control); }); } /** * Restricts the datetimepicker to dates on or before today. * @param {string} fieldName - The base field name (without suffix). */ function limitDateTimePickerToPast(fieldName) { var datePickerId = fieldName + "_datepicker_description"; var target = $("#" + datePickerId); if (target.length === 0) { console.error("Datetimepicker element not found: #" + datePickerId); return; } var today = moment(); // Use moment.js for compatibility with datetimepicker target.closest(".datetimepicker").datetimepicker("destroy").datetimepicker({ format: "MM/DD/YYYY", // Adjust to your date format maxDate: today, // Restrict to today and earlier }); } /** * Restricts the datetimepicker to dates on or after today. * @param {string} fieldName - The base field name (without suffix). */ function limitDateTimePickerToFuture(fieldName) { var datePickerId = fieldName + "_datepicker_description"; var target = $("#" + datePickerId); if (target.length === 0) { console.error("Datetimepicker element not found: #" + datePickerId); return; } var today = moment(); // Use moment.js for compatibility with datetimepicker target.closest(".datetimepicker").datetimepicker("destroy").datetimepicker({ format: "MM/DD/YYYY", // Adjust to your date format minDate: today, // Restrict to today and later }); } /** * Restricts the datetimepicker to a custom date range. * @param {string} fieldName - The base field name (without suffix). * @param {string} startDate - The start date (format: MM/DD/YYYY). * @param {string} endDate - The end date (format: MM/DD/YYYY). */ function limitDateTimePickerToRange(fieldName, startDate, endDate) { var datePickerId = fieldName + "_datepicker_description"; var target = $("#" + datePickerId); if (target.length === 0) { console.error("Datetimepicker element not found: #" + datePickerId); return; } target .closest(".datetimepicker") .datetimepicker("destroy") .datetimepicker({ format: "MM/DD/YYYY", // Adjust to your date format minDate: startDate ? moment(startDate, "MM/DD/YYYY") : false, maxDate: endDate ? moment(endDate, "MM/DD/YYYY") : false, }); } /** * Checks if any visible field on the form has the "dirty" state. * Skips PCF controls by identifying their unique generated IDs or classes. * @returns {Array} - Returns an array of field names or labels that are dirty, excluding PCF controls. */ function getDirtyFields() { var dirtyFields = []; // Check all visible fields for the "dirty" state, skipping PCF controls $(".dirty:visible").each(function () { var fieldId = $(this).attr("id"); var fieldLabel = "Unnamed Field"; // Default fallback // Skip PCF controls by ID or class pattern if (fieldId && fieldId.startsWith("PcfControl")) { return; // Skip this field } if (fieldId) { // Attempt to find a label associated with the field (e.g., with "_label") var labelElement = $(`#${fieldId}_label`); if (labelElement.length > 0) { fieldLabel = labelElement.text().trim(); } else if ($(this).closest(".table-info").find("label").length > 0) { // Look for a label in a common wrapper fieldLabel = $(this).closest(".table-info").find("label").text().trim(); } else if ($(this).attr("aria-label")) { // Fallback to aria-label if available fieldLabel = $(this).attr("aria-label").trim(); } } // If the field is dirty and not a PCF control, add its label to the list if ($(this).data("isdirty") || $(this).hasClass("dirty")) { dirtyFields.push(fieldLabel); } }); return dirtyFields; } /** * Attaches logic to workflow buttons to check for unsaved changes. * Forces the user to save the form if any visible fields have unsaved changes, excluding PCF controls. * @param {string} selector - The selector for the workflow button(s) (e.g., class, id, or attribute-based selector). */ function attachUnsavedChangesCheckToWorkflowButtons(selector) { $(selector).on("click", function (e) { // Get the list of dirty fields var dirtyFields = getDirtyFields(); if (dirtyFields.length > 0) { e.stopImmediatePropagation(); // Fully stop any other event handlers e.preventDefault(); // Prevent the default button action // Construct the message with dirty field names var message = "There are unsaved changes on the form in the following fields:\n"; message += dirtyFields .map(function (field) { return `- ${field}`; }) .join("\n"); alert(message); return false; } // Allow the workflow action to proceed if no dirty fields return true; }); }