Monday, October 24, 2016

KeyPress Methods in MS CRM 2016

In MS CRM 2016, now we can add KeyPress methods for text or number fields. 
KeyPress Events will help for validation of data or for formatting fields. 

With KeyPress methods you can easily restrict any text attribute to accept only numbers or only alphabets or format phone numbers. 

There are three KeyPress methods 

  • addOnKeyPress - using this method you can add event handler function, which will be called when keyPressed in text or number field. 
  • removeOnKeyPress - removes event handler for text or number field which added using addOnKeyPress. 
  • fireOnKeyPress - you can manually fire an event handler you created for text or number field. 
Here are some examples 

1. Format Phone number
  

contactScript =
{
    onLoadEvents: function () {
        Xrm.Page.getControl('telephone1').addOnKeyPress(contactScript.formattPhoneNumber);
    },
    formattPhoneNumber: function () {
        var phoneNo = Xrm.Page.getControl("telephone1").getValue();
        if (phoneNo.length == 10) {
            var formattedPhone = phoneNo.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
            Xrm.Page.getAttribute('telephone1').setValue(formattedPhone);
        }
    },
};


Call contactScript.onLoadEvents on Form Load, Once number started entering into phone number(telephone1) attribute,  formattPhoneNumber is triggering , once phone number length reaches 10, it will format phone number to 123-456-0010 format. For format phone number you can use any other regular expression. 

2. Restrict only numbers

In above example (format Phone number), user will able to enter alphabets also, but mostly phone number contains only numbers. so to restrict only numbers you can change formattPhoneNumber function as 

formattPhoneNumber: function () {      
        var phoneNo = Xrm.Page.getControl("telephone1").getValue();
        phoneNo = phoneNo.replace(/\D/g, '');
        Xrm.Page.getAttribute('telephone1').setValue(phoneNo);
        if (phoneNo.length == 10) {
            var formattedPhone = phoneNo.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
            Xrm.Page.getAttribute('telephone1').setValue(formattedPhone);
        }
    },

3. Restrict only Alphabets

contactScript =
{
    onLoadEvents: function () {
          Xrm.Page.getControl('jobtitle').addOnKeyPress(contactScript.OnlyAlphabets);
      
    },

    OnlyAlphabets: function () {
        var firstName = Xrm.Page.getControl("jobtitle").getValue();
        firstName = firstName.replace(/[^a-z]/gi, '');
        Xrm.Page.getAttribute('jobtitle').setValue(firstName);
    }
};

4. Suggest Accounts name based on Existing leads 

This is autocomplete example, which will show lead names when user enters at least 3 characters in account name. In this example retrieving data from lead entity synchronously, and retrieving only 10 leads at a time.

Here is complete code

var AccountScript = {
    onLoadEvents: function () {
        Xrm.Page.getControl("name").addOnKeyPress(AccountScript.keyPressFcn);
    },
    keyPressFcn: function (evt) {
        try {
            var userInput = Xrm.Page.getControl("name").getValue();

            /*Search in Lead will be started when user enters atleast 3 characters*/
            if (userInput.length >= 3) {
                resultSet = {
                    results: new Array(),
                };

                var userInputLowerCase = userInput.toLowerCase();

                /*Retrieve Leads whose full name begins with name entered by user.
                Retrieving only 10 Leads and autocomplete will be shown when user enters minimum 3 characters. */

                var req = new XMLHttpRequest();
                req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/leads?$select=fullname&$filter=startswith(fullname,'" + userInputLowerCase + "')&$orderby=fullname asc", false);
                req.setRequestHeader("OData-MaxVersion", "4.0");
                req.setRequestHeader("OData-Version", "4.0");
                req.setRequestHeader("Accept", "application/json");
                req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                req.setRequestHeader("Prefer", "odata.maxpagesize=25");
                req.onreadystatechange = function () {
                    if (this.readyState === 4) {
                        req.onreadystatechange = null;
                        if (this.status === 200) {
                            var leadresults = JSON.parse(this.response);
                            for (var i = 0; i < leadresults.value.length; i++) {
                                var fullname = leadresults.value[i]["fullname"];

                                /*Add found lead in array which will be shown in autocomplete window*/
                                resultSet.results.push({
                                    id: i,
                                    fields: [fullname]
                                });
                            }
                        }
                        else {
                            alert(this.statusText);
                        }
                    }
                };
                req.send();
               
                /*If at least one record found then only show autocomplete window.*/
                if (resultSet.results.length > 0) {
                    evt.getEventSource().showAutoComplete(resultSet);
                } else {
                    evt.getEventSource().hideAutoComplete();
                }
            }
        } catch (e) {
          
            alert(this.statusText);
        }
    }
};


call  AccountScript.onLoadEvents function on Account form load event. 



Friday, October 21, 2016

Quick Create Forms

From CRM 2015, you can use Quick Create form to create records quickly. 

To enable Quick create form for any customize entity, we need to update entity. 

 1. Check "Allow Quick Create" in entity customization. 


2. Save Entity and Publish. 

Now if you try to create new record from lookup it will open quick create form. 





Some times when you enabled Quick create form from entity, and haven't created Quick Create Form, then system will open normal form instead of quick create. 

Also If you have Quick Create form but Allow quick create is not checked, then system will open normal form instead of quick create. 

In another words, to use quick create form, entity must be checked for "Allow Quick Create" and at least one Quick create form created and Entity changes are published

If you created multiple Quick Create forms for any entity, one first created Quick create form is used when you are using quick create functionality either from lookup or sub grid. 
There is no Option to choose another quick create form, also you cannot disable Quick create form. 
In case if you want to use 2nd form only then you have to remove first created quick create form and then system will automatically pick second quick create form. 


Refresh Form Ribbon to show / hide button based on attribute value

I had an requirement, when contact has phone number, then show Make a Call custom button. 
To fulfill this requirement, I created custom button and added action and enable rule to custom button. 

In my button enable rule I am checking for Phone number attribute, if it has value then show button other wise hide button. My JavaScript function is

whenToShowMakeACall: function () {
        var phoneNo = Xrm.Page.getAttribute('telephone1').getValue();
        if (phoneNo != null)
            return true;
        else
            return false;

    },

This is working fine, when contact record has phone number in record and when that record opened button was shown.
But now requirement changed, customer wants to show button, as soon as Phone number entered.
If want to show button as soon as phone number entered, means I need to either save contact record or need to refresh ribbon. 

I cannot save contact record because, there might be some other required attributes are missing. 

Now only option is to refresh ribbon. Till CRM 2016, there is not any supported method to refresh ribbon.  In MS CRM 2016, now we have JavaScript method to refresh ribbon, This method solved my problem. 

I created one JavaScript method and calling on phone number OnChange event to refresh ribbon. 

refreshRibbonNavigation: function () {
        Xrm.Page.ui.refreshRibbon();

    },


No Phone number - No Make a Call button 


When phone number, showing Make a Call button


With Xrm.Page.ui.refreshRibbon();  method, you can show / hide any button based on attribute value.