How to show Javascript alerts with appropriate alert messages

So often in CRM, users need to be alerted of their actions. For example, a typical alert might be a message that warns you when a user attempts to enter a text string into a numeric field.

Using the alert() method, a message is usually displayed in a pop-up window. This type of alert method does not require any in-depth response from users, who will simply acknowledge it by clicking the OK button.

Microsoft CRM Pop-Up Message 1

With Microsoft Dynamics CRM 2013 and 2015, Microsoft Dynamics CRM has continued to improve the user experience by introducing a flattened interface so to speak.

This approach focuses on removing excessive clicks and flattening out pop-up windowsfound in the previous version of Dynamics CRM.

With that in mind, using an alert method that requires a response from users seems to contradict the flattening approach.

At the same time, Dynamics CRM 2013 and 2015 introduced new alert methods:setFormNotification and setNotification.

These two methods display messages on the form instead of on a pop-up window, and require no clicking from users.

The Classic CRM Alert Method Versus the New Improved CRM Alert

In this article, I am going to demonstrate how the new alert methods are different from the classic one, and how they can be used.

The example here is a credit card form where credit card numbers and a CVV codes were to be validated. In the previous version of Dynamics CRM, using the classic alert() method, users are typically notified of errors one by one and users have to acknowledge them by clicking OK.

Microsoft CRM Pop-Up Message 2

Microsoft CRM Pop-Up Message 3

Of course this alert method can be slightly improved by displaying the error messages in one single alert, thus reducing the number of pop-ups and clicks to one. But still users have to make the effort clicking the OK button.

Microsoft CRM Pop-Up Message 4

Eliminating the Mouse Clicks on the Notifications in Dynamics CRM

In Dynamics CRM 2013 or 2015, mouse click(s) can be completely eliminated by using setFormNotification that displays message on the form header area. And depending on the nature of messages, they can be categorized as information, error and warning.

  • Xrm.Page.ui.setFormNotification(‘Please fix the following error(s):’, ‘INFORMATION’,);
  • Xrm.Page.ui.setFormNotification(‘Invalid Credit Card Number.’, ‘ERROR’);
  • Xrm.Page.ui.setFormNotification(‘Invalid CVV Code.’, ‘WARNING’);

Microsoft CRM Pop-Up Message 5

There is an extra line of code to clear the message from the form, simply use the following method:

  • Xrm.Page.ui.clearFormNotification()

When there are many fields on one form, users may find it difficult to locate the fields that require correction (of course, additional methods can be developed to help locate such fields, for example, setFocus or setRequiredLevel).

In such a case, I would tend to use another alert, setNotification, that displays messages next to the fields. This way, fields can be visibly located and corrected.

  • Xrm.Page.getControl(“new_creditcardnumber”).setNotification(‘Invalid Credit Card Number.’);
  • Xrm.Page.getControl(“new_cvvcode”).setNotification(‘Invalid CVV Code.’);

Microsoft CRM Pop-Up Message 6

Deprecation of DynamicEntity and inclusion of early, late bound entity classes

In Microsoft Dynamics CRM 2011, you can choose from several programming scenarios to find the model that best suits your needs. The programming scenario in Microsoft Dynamics CRM 4.0 used the Web Services Description Language (WSDL) with early bound classes for each entity, and the DynamicEntity class for late-bound programming. You were also required to use late-bound programming for plug-in and custom workflow development. All of this has changed with the new programming models.

 

The main development scenario for Microsoft Dynamics CRM 2011 no longer uses the WSDL. Instead, you now reference two assemblies that allow you to connect to any Microsoft Dynamics CRM system for both early and late bound types. This scenario can be described as late binding or loosely typed. To use late bound types, use the Entity class. This class defines a collection of attributes that can be used to get and set the values of attributes. To use this model, the exact logical name must be known (and specified) as a string.

 

Alternatively, you can use early bound classes generated directly from the metadata, which include all customizations. The generated classes provide early binding and IntelliSense to aid you as you write custom code.

 

The DynamicEntity class has been replaced by the base class Entity. This means that all types are discoverable at both build time and runtime, making all strongly-typed entities now loosely-typed entities. You can use both programming scenarios in the same code as shown in the following example:

C#:

Account entity = new Account();
entity[“name”] = “My Account”; //loosely typed, late binding
entity.AccountNumber = “1234”; //strongly typed, early binding

The Microsoft Dynamics CRM SDK documentation includes samples that use both programming scenarios. The early bound samples use a file of strongly-typed classes that are generated with the code generation utility from a new, uncustomized installation of Microsoft Dynamics CRM. To run the samples, you must generate a file of strongly-typed classes from your installation. You can decide whether to create a proxy assembly from the generated code file or to include the file in your project directly.
@Information above is based on official Microsoft communication on the same.

getIsDirty Property

Returns a Boolean value indicating if there are unsaved changes to the attribute value.

Attribute Types: All

Xrm.Page.getAttribute(arg).getIsDirty()
Return Value
Type: Boolean. True if there are unsaved changes, otherwise false.In this way you can search for all unsaved changes on the form.

Auto save picks up the fields which were dirty(Not saved yet).

Enhancements to solution patches in 2016

Introduction

Now moving forward we will look at a common scenario of sending out Patches for your solution. Often it happens that you may need to update a few components of your managed solution and ideally would like to have a way to only have those shipped and then have a way to compile all of these patches in the next release of the solution. This helps with better versioning control and management of the solution assets.

Patches

Taking it forward from our previous article, here is what our solution looked like.

Keep your eye on the Version number of the solution as this is one of the critical thing which will come to notice as we move ahead.

Now suppose due to some requirement changes I have to increase the maximum length for “First Name” field of Contact from 155 to 175.

Since this field was a part of the earlier solution that we had and this is the only change we need to make to that solution, we will go ahead and create a patch for the original solution

Use the “Clone a Patch” button added to the solutions views

Notice the other buttons as well “Clone Solution” and “Apply Solution Upgrade”, this completes the entire solution management architechture.

It is a good practice to increment the version number for a proper version management of the solution. Since this is a patch it only allows you to modify the last 2 digits in the version.

This creates the following new solution.

Add only the Contact “First Name” field to the solution and update the length as shown below.

When you import this patch on the client environment this solution will be applied on top of the base solution and only the “firstname” field will be updated.

You can create multiple patches for a solution. To create another patch you would select the original solution and click “Clone a Patch”.

The original solution can no longer be modified.

In the Target system, you can delete the managed solution of a patch without affecting the base solution installed there.

The patches don’t have a dependency on each other, so in the target system I deleted the first patch that was imported and then imported the second patch and it works just fine. So that’s huge plus, since one of the problems with earlier solution management architecture was the dependencies that would be created between managed solutions. So here there is no dependency of the patches amongst them. But of course they do need the base solution present since they are patch for the base solution.

Uninstalling the base solution on the target also automatically uninstalls all the patches that were installed for the base solution.

When you want to plan your next version of the solution, you usually want to rollup all of the patches that were released for the base solution into the new solution, before you can add new changes in there. This can be done using the “Clone Solution” button.

Now this time, you are only allowed to change the major and minor parts of the version.

Once the operation completes, you will find the patches deleted and the base solution version updated.

This solution is now available for editing as well.

When the Upgrade solution is imported on the target system, it auto detects this to be an upgrade to an existing installed package and notifies you of the same.

On the next step of the import wizard, you get the option to choose if you want this imported as “Holding Solution”. This option will show up and checked by default if the target organization has base solution and patches for base solution installed. You can learn more about the “Holding Solution” concept here

When the solution import completes, you see a new option “Apply Solution Upgrade” since you chose to import this as a holding solution.

If you do not choose to apply the solution upgrade, you will see three solutions in the target system.

Now choose the original Base solution on the target system and click on the “Apply Solution Upgrade” button to keep a single solution for the package instead of the three that appear now

If there were no patches installed in the target system and the “Stage for Upgrade” option is unchecked, you have the option to check it if you want. If you leave it unchecked it simply updates the solution and you do not need to “Apply Solution Upgrade”.

Conclusion

Though I have only explored this using basic customizations to entities, the whole solution management framework from creating a solution to patching to moving it to the next release and similarly “upgrading solution” on the target system appears that, it would reduce if not end a lot of “solution import” woes of the ISV community.

Connecting to CRM using console application

Find the code to connect to your organization to perform some CRUD operations, please note this code is completely tested and can be used without any doubt

namespace console_to_connect
{

//namespaces to include
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk.Query;

namespace ConnectToCRM
{
class Program
{
static IOrganizationService _service;
static void Main(string[] args)
{
EntityCollection ec = null;
try
{
ConnectToMSCRM(“pavan@xrm.onmicrosoft.com”, “XRM”, “https://xrm.api.crm8.dynamics.com/XRMServices/2011/Organization.svc”);// connect to your organization
}

catch(Exception ex)
{

}
Guid userid = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).UserId;//Getting the current user who was running this operation
if (userid != Guid.Empty)
{
Console.WriteLine(“Connection Established Successfully”);
Console.ReadKey();
}

else return;
}
public static void ConnectToMSCRM(string UserName, string Password, string SoapOrgServiceUri)
{
try
{
ClientCredentials credentials = new ClientCredentials();
credentials.UserName.UserName = UserName;
credentials.UserName.Password = Password;
Uri serviceUri = new Uri(SoapOrgServiceUri);
OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUri, null, credentials, null);
proxy.EnableProxyTypes();
_service = (IOrganizationService)proxy;

QueryExpression query = new QueryExpression
{
EntityName = “user”,
ColumnSet = new ColumnSet(UserName, Password)
};

}
catch (Exception ex)
{
Console.WriteLine(“Error while connecting to CRM ” + ex.Message);
Console.ReadKey();
}
}
}
}
}

FAQ’s on plugin development and registration

1. How do I find the right Message for registering my plug-in?

· An action in CRM can be performed using different SDK operations. So in order to find the correct subset of messages, you need to filter the messages by entity. Then you can register the plug-in on all the messages that look closer to the functionality.

· To make the search easier, I created an excel sheet with all valid list of Messages and Entities for plug-ins which is located at http://code.msdn.microsoft.com/crmplugin. Filter the list by the entity name to find the correct subset of messages.

2. Why do I need to register on SetState and SetStateDynamicEntity separately?

· As I mentioned earlier there are multiple messages that perform the same action in CRM. One such example is SetStateRequest and SetStateDyanmicEntityRequest . If you want to write a plug-in on SetState, then you need to register it on both messages.

3. Why does Opportunity State change not caught when I register on SetState alone?

· This is one more example of multiple SDK operations valid for an action in CRM. If you look at the Opportunity entity, you shall find that there are Lose, Win, Setstate, SetStateDynamicEntity requests that change the State of an opportunity. So you need to register your plug-in on all the mentioned messages.

4. Why did my plug-in not fire on Create Account, when Opportunity is converted to Account?

· In CRM 3.0 we had this problem. So, If you want your plug-in to be fired when an action happens as a result of another action, you need to register the plug-in in the Child pipeline. Plug-in Registration tool allows you to specify this option during the Step registration process.

· If you register the plug-in with InvocationSource=Parent, then it is fired only on the primary action

5. How do I pass configuration data to plug-in? I don’t see support for app.config

· Hard coding connections, customer configuration in plug-in is always a bad idea. So if you need some information, either you had to read from Registry or from a File. Multi Server deployment is major problem in either of these cases. So wouldn’t it be nice if CRM provided some functionality to store the configuration data to the plug-in just like it stores the assemblies in database? Well, you have it in the form of SdkMessageProcessingStep.configuration and SecureConfiguration properties. Both of these properties are strings. They can be set when registering the Step and their values are available in the plug-in constructor at runtime.

· SdkMessageProcessingStep is an OrgOwned entity, so any user in CRM can read the values from this entity via SDK. So data stored in it is not restricted to administrators only.

· On the other hand, SecureConfiguration can only be read by CRM Administrators. So if you want to store username, pass word information, etc., save it in this property.

· For a sample look at SamplePlugins.LogContextToCRM in the downloads section

6. How to read the IPluginExecutionContext.InputParameters Property bag and what is the structure?

· InputParamaters property is a serialized version of the SDK Request operation

· Microsoft CRM SDK has good explanation about this property http://msdn2.microsoft.com/en-us/library/cc151087.aspx

7. I need to get an Image of the entity when the update requested is fired

· Register a PreImage on the Step

· Context.PreImages[“entityalias”] should have the DynamicEntity

8. I would like to be notified when IncidentResolution entity is created. I also needed information about the related incident entity. How do I get this information?

· IncidentResolution entity is created as part of Resolve Incident request. So, you can only catch this event if you register on Child pipeline for Create of IncidentResolution entity. You can parse the incidentid from the InputParameters property bag

· However if you need to read custom attributes or other attributes on the incident, you have to call CRM. Since it is a child pipeline, we restrict you in calling CRM by not providing the Proxy. You can work this around by creating a proxy by yourself.

· PluginHelper. GetCrmProxyUsingEndpointUrlInChildPipeline in the downloads section has sample

9. How to get the EntityId in the Plug-in?

· I have created a PluginHelper.cs available in the download section, which helps you understand how to retrieve the entityId based on the message. You can extend it for other messages too. In short you need to look at the Request and see where the entityId is available and then retrieve it accordingly in the plug-in.

· Look at the RetrieveEntityId plug-in in the downloads section.

10. Can I look at what is in the IPluginExecutionContext without debugging?

· IPluginExecutionContext has lot of properties and most of them are dictionaries. I understand that it is hard for developers to know what its contents are before enumerating or debugging. So I created a plug-in that serializes the IPluginExecutionContext and writes it back to CRM so that you can view the Xml in the Form.

· SamplePlugins.LogContextToCRM Plug-in in the download section creates the serialized Xml into the new_pluginContext custom entity. Once you register the plug-in on any message, you shall get the Context in the custom entity

11. How do I know if my plug-in is running in Outlook Offline mode or on the Server?

· You can use IPluginExecutionContext.IsExecutingInOfflineMode property

· SamplePlugins.AmIExecutingOffline plug-in in the download section demos the scenario

12. How do I know if the Request originated in the Outlook Offline mode and replayed?

· You can use CallerOrigin property

· SamplePlugins.OfflinePlaybackConflictResolution plug-in in the download section demos the scenario. It rejects all the updates on the entity from the Outlook Offline client, if the Server had an updated version of the same entity.

· SamplePlugins.MyPluginCallerOrigin plug-in also demos the scenario

13. What is Depth and CorrelationId in the IPluginExecutionContext?

· Depth is an integer property that we automatically increment when Plug-in makes a call back to CRM using web service. When the Depth reaches certain max value, we treat it as potential infinite loop and reject the call.

· CorrelationId is a Guid that is set on the initial call to CRM and used later for tracking resultant calls.

· When you use CreateCrmService() method in the plug-in, we set these values on the proxy. However, if you create your own proxy, please copy these values so that the tracking is in place. PluginHelper.GetCrmProxyUsingEndpointUrlInChildPipeline in the download section has the sample code.

· We do recommend you to use our proxy so that we take care of all the minute details.

14. I registered my plug-in in Child pipeline and I can no longer create proxy to connect to CRM

· We disabled this feature since it is very easy to get into infinite loops as you are way low in the pipeline.

· But if you do have the scenario and absolutely need it, then you can create your own proxy. I have demonstrated this in the PluginHelper.GetCrmProxyUsingEndpointUrlInChildPipeline method but use with Caution !!!

15. What is the difference between InitiatingUserId and UserId in IPluginExecutionContext?

· You registred the plug-in to impersonate as UserA. If UserB makes a call to CRM which triggers the plug-in, then you get UserA in the UserId property and UserB in the IntiatingUserId property.

Column set query to retrieve data

The following code example shows how to use the ColumnSet class to specify what attributes to return from a query expression.

QueryExpression contactquery = new QueryExpression 
{
   EntityName="contact",
   ColumnSet = new ColumnSet("firstname", "lastname", "contactid") 
};

Xrm JS. API syntaxes

Hi All,

Here is file where you can find complete XRM utility javascript syntaxes, follow and download the image file below

Xrm Js syntaxes

Retrieve record using OData and JQuery in CRM 2011

Hi,

Below is the script to read a record using OData & JQuery

function retrieveRecord(id, odataSetName) {

// Get Server URL

var serverUrl = Xrm.Page.context.getServerUrl();

//The OData end-point

var ODATA_ENDPOINT = “/XRMServices/2011/OrganizationData.svc”;

//Asynchronous AJAX function to Retrieve a CRM record using OData

$.ajax({

type: “GET”,

contentType: “application/json; charset=utf-8”,

datatype: “json”,

url: serverUrl + ODATA_ENDPOINT + “/” + odataSetName + “(guid’” + id + “‘)”,

beforeSend: function (XMLHttpRequest) {

//Specifying this header ensures that the results will be returned as JSON.

XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);

},

success: function (data, textStatus, XmlHttpRequest) {

readRecord(data, textStatus, XmlHttpRequest)

},

error: function (XmlHttpRequest, textStatus, errorThrown) {

alert(“Error – ” + errorThrown)

}

});

}

function readRecord(data, textStatus, XmlHttpRequest) {

alert(“Record read successfully!!”);

var account = data;

alert(“Name – ” + account.d.Name);

alert(“Id – ” + account.d.AccountId);

}

How do I call this method :-

  • Below is the sample function to read Account

var accountId = “”; // Assign account GUID

var odataSetName = “AccountSet”;

retrieveRecord(accountId,odataSetName );

New features in CRM 2016

CRM 2016 introduces a role-based experience for customer service agents. Users can view their current workload and interact with records through a real-time dashboard.

Cases can now be updated directly from the dashboard by selecting the case and the appropriate action.

Case Enhancements

Case management is simplified and better than ever. Users can now save case details directly on a case record and apply routing rules all in one action by clicking the Save & Route button.

Knowledge Management Capabilities

The new knowledge base article designer now features an enhanced WYSIWYG editor and allows for embedding videos and images. Articles can easily be scheduled to publish or expire for a future date. Knowledge can be enabled on any entity and over 80 languages are now supported. Articles can be shared with external users or analyzed internally to better understand how information is being used.

Word Templates

You can now standardize common CRM data-generated documents. Word templates can be initiated from any form or automated through a workflow. Extract data from CRM into a standardized word document with ease and create custom templates or leverage existing word templates from Microsoft!

Excel Templates

New Excel templates let you use a Microsoft Dynamics provided template or create your own reusable templates to quickly analyze data your way. CRM 2016 allows users to work with data from a downloaded template or from Excel Online. With the CRM Mobile Application, you can also export to Excel directly from a tablet or mobile device. Pretty Excel-lent, huh?

Delve

Unique to each user, Delve uses analytics to identify top trending documents in CRM relevant to the user. Delve looks for connections as to what the user is working on, common groups or teams, and identifies documents that may be relevant such as a newly saved presentation or proposal. Users can view trending documents relevant to them from a dashboard or Office 365.

*Note: data permissions still apply, meaning that if the user does not have permission to view the information it will not be presented.

Consolidated View of Documents in CRM

Display any Office document file from OneDrive for Business, SharePoint, or Office 365 groups directly in CRM. Documents will remain private until the user elects to share.

With the CRM Mobile App, these same documents can be viewed or modified directly from a tablet or mobile device.

CRM App for Outlook

Track emails, add Contacts from within an email, or create new records to track emails against all with the CRM App for Outlook. In addition to Internet Explorer and Chrome, CRM 2016 is expanded to include support for Firefox, Safari for Mac, and Outlook for Mac. One especially cool new feature is that you can track an email while composing it.

Updating CRM on the Go

In future blogs we will focus on Mobile enhancements and features specific to system administrators and customizers. However, we just had to leave you with this amazing new feature. Have you ever wanted to update a field from a mobile device leveraging touch capability? Let’s say you are an Account Manager and while having a conversation with a customer you want to update the Estimated Revenue field. By using a slider control, you can quickly update this field by simply moving the slider. Pretty awesome!