Friday, December 27, 2019

Most common JavaScript methods for Dynamic 365 CRM


In today's article, I will list out the most used JavaScript methods that are used in Dynamic 365 CRM. I am often being asked where to have a quick reference for learning client-side scripting in Dynamic CRM. Keeping that in my mind, I am listing few methods that one should be handy and ready with.

Note : A basic understanding of Dynamic CRM is a must to understand method and article consider only listing method with minimum description for methods.





debugger;   // The one which is favorite to all who got stuck  

// Context Methods
var UserId      = Xrm.Page.context.getUserId();
var UserName    = Xrm.Page.context.getUserName();
var orgName     = Xrm.Page.context.getOrgUniqueName();
var clientUrl   = Xrm.Page.context.getClientUrl()
var currentUserRoles = Xrm.Page.context.getUserRoles();

context.getEventArgs().preventDefault();    // Explicity preventing the save.
//NOTE: context must be passed as a function param


// Xrm.Page.data.entity Methods
var entityId       = Xrm.Page.data.entity.getId();
var entityId       = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
var entityName     = Xrm.Page.data.entity.getEntityName();
var entitySetName  = Xrm.Page.data.entity.getEntitySetName();
var isDirty        = Xrm.Page.data.entity.getIsDirty();
var AttrName       = Xrm.Page.data.entity.getPrimaryAttributeValue();

//Lookup set: one Statement
Xrm.Page.getAttribute("uomid").setValue([{ id: "69DAC10E-96BC-4F84-8BE9-29F84FF4401C", name: "Default Unit", entityType: "uomschedule" }]); // Unit Group

// Refresh and Focus
Xrm.Page.data.refresh();
Xrm.Page.ui.refreshRibbon();


// Page Save Methods
Xrm.Page.data.entity.save(); // ** Just saves current record
Xrm.Page.data.entity.save("saveandclose") // ** Does a save and close
Xrm.Page.data.entity.save("saveandnew") // ** Save and new


// Field Events
Xrm.Page.getControl("new_fieldname").setFocus();    // Setting Focus to a Field
Xrm.Page.getAttribute("new_fieldname").setSubmitMode("always"); // Explicit Save
Xrm.Page.getAttribute('new_fieldname').fireOnChange();  // Explicity calling FireOnChange event
Xrm.Page.getControl('new_fieldname').setDisabled(true);
Xrm.Page.getAttribute("new_OptionSetName").getSelectedOption().value;   // Get Selected Value from an optionSet

Xrm.Page.getAttribute("new_myfield").setRequiredLevel("none");          // Not Required
Xrm.Page.getAttribute("new_myfield").setRequiredLevel("recommended");   // Business Recommended
Xrm.Page.getAttribute("new_myfield").setRequiredLevel("required");      // Business Required



var formType = Xrm.Page.ui.getFormType();
var formType = executionContext.getFormContext().ui.getFormType();
// Create   1
// Update   2
// ReadOnly 3


// Setting Visibility or Enabling or Disabling
Xrm.Page.ui.controls.get("new_fieldname").setVisible(false);    // Hiding a Field
Xrm.Page.ui.tabs.get("tab_unique_name").setVisible(false);      // Hiding a Tab
Xrm.Page.ui.tabs.get("tab_5").sections.get("tab_5_section_4").setVisible(false);    // Hiding a Section


// Field Level Notification
Xrm.Page.getControl("fieldname").setNotification("message");
Xrm.Page.getControl("fieldname").clearNotification();


// Form Level Notification
MSCRM.ERRORNotification = "ERROR";
MSCRM.WarningNotification = "WARNING";
MSCRM.INFONotification = "INFO";

Xrm.Page.ui.setFormNotification("message", type, unique_number);
Xrm.Page.ui.clearFormNotification(number);



// Custom Filter Query for Lookup Control
Xrm.Page.getControl('eks_accountRating').addCustomFilter('');


// Open an Entity Form
Xrm.Utility.openEntityForm('incident', Xrm.Page.data.entity.getId());


// Open a Web-Resource
var windowOptions = { height: 400, width: 400 }
Xrm.Navigation.openWebResource("new_example",windowOptions);


// Business Process Flow Methods
var activeStageName      = Xrm.Page.data.process.getActiveStage().getName();
var selectedStageName    = Xrm.Page.data.process.getSelectedStage().getName();

"Next" "Previous" = executionContext.getEventArgs().getDirection()

// Binds javascript methods on BPF events
executionContext.getFormContext().data.process.addOnStageChange(functionname)
Xrm.Page.data.process.addOnStageChange(Opportunity.Functions.ValidateSelectedStageOnSave, executionContext);
executionContext.getFormContext().data.process.addOnStageSelected(functionname)

// SubGrid events
count = Xrm.Page.getControl("ln_subgrid_quotes").getGrid().getTotalRecordCount();


// Confirm or Prompt Dialog box 
var confirmStrings = { text: "Please confirm to put Opportunity On-Hold", title: "Confirmation Dialog" };
var confirmOptions = { height: 200, width: 450 };
Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then(
    function (success)
    {
        if (success.confirmed)
        {
            base.attr.setValue(executionContext, "ln_onholddate", Date.now());
            Opportunity.Functions.ReadOnly(executionContext, true);
            base.attr.unlock(executionContext, "header_statuscode");
            base.attr.unlock(executionContext, "statuscode");
            console.log("Dialog closed using OK button.");
        }
        else
        {
            base.attr.setValue(executionContext, "statuscode", 1);
            console.log("Dialog closed using Cancel button or X.");
        }
    });


// Make form Read Only

ReadOnly(executionContext, true); // will make all field ReadOnly

function ReadOnly(executionContext, flag)
{
    Xrm.Page.ui.controls.forEach(function (control, index)
    {
        if (Opportunity.Functions.doesControlHaveAttribute(control))
        {
            control.setDisabled(flag);
        }
    });
}
function doesControlHaveAttribute(control)
{
    var controlType = control.getControlType();
    return controlType != "iframe" && controlType != "webresource" && controlType != "subgrid";
}




// Few Utility JavaScript Methods

console.log("Message: " + msg + ". Error: " + ex);

console.error("Message: " + msg + ". Error: " + ex);

alert("Message: " + msg + ". Error: " + ex);


var returnBool = !isNaN(monthVariable);
var month = parseInt(monthVariable);

 
// Formatting Date
this.setDateOptions = function () {
    Date.prototype.formatMMDDYYYY = function () {
        return this.getMonth() + "/" + this.getDate() + "/" + this.getFullYear();
    }
}

// Formatting Date and Time with AM / PM 

function formatAMPM()

{

    var date = new Date();

    var hours = date.getHours();

    var minutes = date.getMinutes();

    var ampm = hours >= 12 ? 'PM' : 'AM';

    hours = hours % 12;

    hours = hours ? hours : 12; // the hour '0' should be '12'

    minutes = minutes < 10 ? '0' + minutes : minutes;

    var strTime = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear() + " " + hours + ':' + minutes + ' ' + ampm;

    return strTime;

}


// Validating Start and End Date

function ValidateMaintenanceEndDate(executionContext)

{

       var formContext = executionContext.getFormContext();

       var startDateField = formContext.getAttribute("new_maintenancestart");

       var endDateField = formContext.getAttribute("new_maintenanceend");

       var endDateFieldControl = formContext.getControl("new_maintenanceend");

       var startDate = startDateField.getValue();

       var endDate = endDateField.getValue();

 

       if (startDate != null && endDate != null)

       {

             startDate = new Date(startDate.toISOString().substr(0, 10));

             endDate = new Date(endDate.toISOString().substr(0, 10));

 

             endDateFieldControl.clearNotification("ErrEndDate");

 

             if (startDate >= endDate)

             {

                    endDateFieldControl.setNotification("cannot be before or equal to Maintenance Start.", "ErrEndDate");

             }

             else

             {

                    endDateFieldControl.clearNotification("ErrEndDate");

             }

       }

}


// Formatting Phone Number

function formatPhoneNumber(phoneNumber)

{

    if (phoneNumber.length != 10) {

        return phoneNumber;

    }

    var piece1 = phoneNumber.substring(0, 3); //123

    var piece2 = phoneNumber.substring(3, 6); //456

    var piece3 = phoneNumber.substring(6); //7890

 

    return kendo.format("({0})-{1}-{2}", piece1, piece2, piece3);

}

 


 

 

// Converting HTML content to Plain Text

function convertHtmlToPlainText(htmltext)

{

    htmltext = htmltext.replace(/<style([\s\S]*?)<\/style>/gi, '');

    htmltext = htmltext.replace(/<script([\s\S]*?)<\/script>/gi, '');

    htmltext = htmltext.replace(/<\/div>/ig, '\n');

    htmltext = htmltext.replace(/<\/li>/ig, '\n');

    htmltext = htmltext.replace(/<li>/ig, '  *  ');

    htmltext = htmltext.replace(/<\/ul>/ig, '\n');

    htmltext = htmltext.replace(/<\/p>/ig, '\n');

    htmltext = htmltext.replace(/<br\s*[\/]?>/gi, "\n");

    htmltext = htmltext.replace(/<[^>]+>/ig, '');

 

    return htmltext;

}



var temp = document.createElement("div");

temp.innerHTML = html;

return temp.textContent || temp.innerText || "";

 

myHTML.replace(/<[^>]+>/g, '');




// Comparing two Guids
function GuidsAreEqual(guid1, guid2) {
    // compares two guids
    var isEqual = false;
    if (guid1 == null || guid2 == null) {
        isEqual = false;
    } else {
        isEqual = (guid1.replace(/[{}]/g, "").toLowerCase() == guid2.replace(/[{}]/g, "").toLowerCase());
    }
    return isEqual;
}


// SET TIME OUT : Executes a function, after waiting a specified number of milliseconds.
// Syntax : setTimeout(function, milliseconds)
setTimeout(function () { Xrm.Page.ui.clearFormNotification("clearallnotification"); }, 10000);


// SET INTERVAL : repeats the execution of the function continuously.
var intervalId = setInterval(
    function () {
        if (loChildWin.closed) {
            clearInterval(intervalId);
        }
    },500);



// Encoding an URI Component
var _FilterT = "/TeamSet?$select=Name,TeamId&$filter=Name eq '" + encodeURIComponent(teamname) + "'";

Normal__URI  = "https://vicity.com/my test.asp?name=stÃ¥le&car=saab";
Encoded_URI = "https%3A%2F%2Fvicity.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab";



// Decoding a URI Component
var search = decodeURIComponent(location.search);
var params = search.substr(search.indexOf("?") + 1);
params = params.split("&");     // split param and value into individual pieces


// Converting String to a Byte Array
function packStringToByte(str) {
    var bytes = [];
    for (var i = 0; i < str.length; i++) {
        var char = str.charCodeAt(i);
        bytes.push(char >>> 8);
        bytes.push(char & 0xFF);
    }
    return bytes;
}


// Opens a Random Url
function OpenRandomUrl(url) {
    if (url != null)
        window.open(url);
    else
        alert("Page not found");
}



// Create Base64 Object
var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function (e) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode(e); while (f < e.length) { n = e.charCodeAt(f++); r = e.charCodeAt(f++); i = e.charCodeAt(f++); s = n >> 2; o = (n & 3) << 4 | r >> 4; u = (r & 15) << 2 | i >> 6; a = i & 63; if (isNaN(r)) { u = a = 64 } else if (isNaN(i)) { a = 64 } t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) } return t }, decode: function (e) { var t = ""; var n, r, i; var s, o, u, a; var f = 0; e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (f < e.length) { s = this._keyStr.indexOf(e.charAt(f++)); o = this._keyStr.indexOf(e.charAt(f++)); u = this._keyStr.indexOf(e.charAt(f++)); a = this._keyStr.indexOf(e.charAt(f++)); n = s << 2 | o >> 4; r = (o & 15) << 4 | u >> 2; i = (u & 3) << 6 | a; t = t + String.fromCharCode(n); if (u != 64) { t = t + String.fromCharCode(r) } if (a != 64) { t = t + String.fromCharCode(i) } } t = Base64._utf8_decode(t); return t }, _utf8_encode: function (e) { e = e.replace(/\r\n/g, "\n"); var t = ""; for (var n = 0; n < e.length; n++) { var r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r) } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128) } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128) } } return t }, _utf8_decode: function (e) { var t = ""; var n = 0; var r = c1 = c2 = 0; while (n < e.length) { r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r); n++ } else if (r > 191 && r < 224) { c2 = e.charCodeAt(n + 1); t += String.fromCharCode((r & 31) << 6 | c2 & 63); n += 2 } else { c2 = e.charCodeAt(n + 1); c3 = e.charCodeAt(n + 2); t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); n += 3 } } return t } }

// Encode the String                                
var EncodedString = Base64.encode(valuFromContext);

url = portNumber + "MyCustomPage/" + EncodedString;



Please let me know what the other common methods you used while scripting in Dynamic CRM.

Thanks,

Vipin Jaiswal

Thursday, December 12, 2019

Exception 'System.AggregateException' thrown when trying to add source



I was facing this issue today related to Nuget and DLL missing in my project and was not able to proceed to look into an urgent issue.

Severity Code Description Project File Line Suppression State Suppression State
Error Exception 'System.AggregateException' thrown when trying to add source 'https://***.pkgs.visualstudio.com/_packaging/invo/nuget/v3/index.json'. Please verify all your online package sources are available.
One or more errors occurred.
Unable to load the service index for source https://invo.pkgs.visualstudio.com/_packaging/invo/nuget/v3/index.json.
Response status code does not indicate success: 401 (Unauthorized).

Solution
Un-tick package sources that are not accessible with the credentials that are being used to access Nuget or logged in for Visual Studio.

Visual Studio\Tools\Options\Nuget Package Manager\Package Sources



You can Tick specific Nuget Feed (related to your Team Project) and sign in with your VSTS team project account from VS upper right corner and restart VS




Explanation

Sometimes, when you are working for multiple client and have TFS or VS logged in under their credentials, you will not be allowed to access Nuget Package Source for different client with one credentials.
Even when you look for any Nuget package online you might get this error, the reason is under configured package source we are explicitly asking visual studio to list Nuget’s from all listed and ticked package source. 

Nuget Package Source Url : https://api.nuget.org/v3/index.json