Showing posts with label MS CRM 2016. Show all posts
Showing posts with label MS CRM 2016. Show all posts

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.








Wednesday, October 19, 2016

Upsert Request using Alternative key

In MS CRM 2016, now we can insert or update request in a single request called Upsert. 
If record with particular key already exists in system, then it will be updated, if not then new record will be created. 

 More details are available  on MSDN site

https://msdn.microsoft.com/en-us/library/dn932135.aspx

Now in CRM 2016 we can create alternative keys, which are either single attribute or combination of attributes, you can use this alternative key for insert / update record. 


1. Single Attribute in alternative Key upsert

I created custom entity called Car, with attributes car no (whole number), name (string), make year (whole number) and Manufacture (string). And defined alternative key on car no. 


My Alternative Key name is - new_carNoId

When using Upsert request, we need to specify attribute name in request NOT key name. 
Here is sample code

Entity car = new Entity(new_car.EntityLogicalName, "new_carno", 2);
car["new_name"] = "Carolla";
car["new_make"] =2015;
car["new_manufacture"] = "Toyota";

UpsertRequest req = new UpsertRequest()
 {
   Target = car
 };


 UpsertResponse resp = (UpsertResponse) serviceProxy.Execute(req);


When creating entity object for insert / update, we need to specify alternate key attribute name and value, and then set other required attributes of record. 

Note: When you create alternative key, that key must be active to use Upsert, if alternative key status pending / failed, execute method will throw error. 

2. Multiple Attribute in alternative Key upsert
If you have alternative key with multiple attributes, then you need to initialize entity object differently. 

I created alternative key in my car entity with Car No (whole Number) and Manufacture (string) attributes. 

When initializing entity object at that time we need to specify KeyAttributeCollection 
and add all your key attribute in this collection. 

 KeyAttributeCollection keyColl = new KeyAttributeCollection();
     keyColl.Add("new_carno", objcar.carNo);
     keyColl.Add("new_manufacture", objcar.Manufacture);

     Entity car = new Entity(new_car.EntityLogicalName, keyColl);
     car["new_name"] = objcar.CarName;
     car["new_make"] = objcar.MakeYear;

     UpsertRequest req = new UpsertRequest()
       {
         Target = car
       };
     UpsertResponse resp = (UpsertResponse) serviceProxy.Execute(req);

When Upsert request is executed, at that time CRM will look for combination of Car No and Manufacture, if any record exists in system, then it will be updated, otherwise it record will be created. 

If you have lots of records and wants to insert / update then you can use UpsertResponse in 
ExecuteMultipleRequest  request also. 

List<CarDetails> cars = new List<CarDetails>();
cars.Add(new CarDetails(1, "X15", "BMW", 2016));
cars.Add(new CarDetails(2, "XX3", "BMW", 2014));
cars.Add(new CarDetails(3, "XX4", "BMW", 2014));
cars.Add(new CarDetails(4, "XL3", "BMW", 2014));
cars.Add(new CarDetails(1, "1Carolla CS", "Toyota", 2014));
cars.Add(new CarDetails(2, "1Carolla LE", "Toyota", 2015));
cars.Add(new CarDetails(3, "Carolla SE", "Toyota", 2015));


ExecuteMultipleRequest multipleReq = new ExecuteMultipleRequest()
 {
  Settings = new ExecuteMultipleSettings()
   {
     ContinueOnError = true,
     ReturnResponses = true
    },
   Requests = new OrganizationRequestCollection()
  };

foreach (var objcar in cars)
 {
  KeyAttributeCollection keyColl = new KeyAttributeCollection();
  keyColl.Add("new_carno", objcar.carNo);
  keyColl.Add("new_manufacture", objcar.Manufacture);

  Entity car = new Entity(new_car.EntityLogicalName, keyColl);
  car["new_name"] = objcar.CarName;
  car["new_make"] = objcar.MakeYear;

 UpsertRequest req = new UpsertRequest()
 {
   Target = car
  };

  multipleReq.Requests.Add(req);
 }


 ExecuteMultipleResponse mulresponse = (ExecuteMultipleResponse)_serviceProxy.Execute(multipleReq);


Note:  With ExecuteMultipleRequest you can execute 999 requests at a time. If you have more records than 999 in ExecuteMultipleRequest Collection, then CRM will throw error.