CRM 2013 – Client API New Functionalities Recap

If you’ve been following, I had a series of Client API posts late last year. Below I have regrouped the new Client API functionality in a table for reference. This can become helpful especially if you are developing with the “old” CRM 2011 mindset to easily see what you can achieve differently and/or more efficiently in CRM 2013. Details on the new functionalities is available on the Microsoft Dynamics CRM YouTube video and in the CRM 2013 SDK.

Area

Method and Syntax

Description

Data

Xrm.Page.data.refresh(save).then(successCallback, errorCallback)

Asynchronously refreshes and optionally saves all the data of the form without reloading the page.

You can pass a callback method to execute on success or error

Data

Xrm.Page.data.save().then(successCallback, errorCallback)

See my blog post on this here

Data

Xrm.Page.data.getIsValid()

Returns a Boolean value indicating if the form can be saved or not

Data

Xrm.Page.data.setFormDirty()

Set the form as dirty

Entity

Xrm.Page.data.entity.getPrimaryAttributeValue()

Gets a string for the value of the primary attribute of the entity.

UI

Xrm.Page.ui.setFormNotification(message, level, uniqueId);

Xrm.Page.ui.clearFormNotification(uniqueId)

Use setFormNotification to display form level notifications and clearFormNotification to remove notifications. Gareth Tucker has a great article on these here.

Controls

Xrm.Page.getControl(fieldName).setNotification(message)

Xrm.Page.getControl(fieldName).clearNotification()

See article linked above for details. Notifications can be set at the field level

Number

Xrm.Page.getAttribute(fieldName).setPrecision(precision)

This method is used to override the field’s precision

Date

Xrm.Page.getControl(arg).setShowTime(bool)

Specify whether a date control should show the time portion of the date.

Date

Xrm.Page.getControl(arg).setIsAllDay(bool)

Specify whether a date control should set a value including the entire day.

Lookup

Xrm.Page.getControl(arg).addCustomFilter(filter, entityLogicaName)

Use add additional filters to the results displayed in the lookup. Each filter will be combined with any previously added filters as an ‘AND’ condition

The entity logical name is optional. If this is set the filter will only apply to that entity type. Otherwise it will apply to all types of entities returned.

Lookup

Xrm.Page.getControl(arg).addPreSearch(handler)

Use this method to apply changes to lookups based on values current just as the user is about to view results for the lookup.

The argument is a function that will be run just before the search to provide results for a lookup occurs. You can use this handler to call one of the other lookup control functions and improve the results to be displayed in the lookup.

Lookup

Xrm.Page.getControl(arg).removePreSearch(handler)

This API call is used to remove event handler functions that have previously been set for the PreSearch event (see above)

Context

Xrm.Page.context.getUserName()

Returns the name of the current user.

Context

Xrm.Page.context.client.getClient()

Xrm.Page.context.client.getClientState()

See my blog post about it here

Utility

Xrm.Utility.alertDialog(message,onCloseCallback)

Xrm.Utility.confirmDialog(message,yesCloseCallback,noCloseCallback)

Displays a dialog box containing an application-defined message.

Displays a confirmation dialog box that contains an optional message as well as OK and Cancel buttons.

See additional notes on this here.

Utility

Xrm.Utility.isActivityType(entityName)

Determine if an entity is an activity entity.

Utility

Xrm.Utility.openEntityForm(name,id,parameters)

Opens an entity form. Parameters are optional and used to pass the form ID, set default field values or pass custom query string parameters

Utility

Xrm.Utility.openWebResource(webResourceName,webResourceData,width, height)

Opens an HTML web resource.

Dynamics CRM – Year Review from my notes…

2013 has been a huge year for us all Microsoft Dynamics CRM professionals. I thought I would take a few minutes to review my blog stats and make a quick review of what has been helpful to people in the communities over the past 12 months.

The CRM development tools is one of the most popular. The idea back then was to build a CRM Solutions deployment utility to help support a development environment that resembles what MVP Gonzalo Ruiz describes on his blog post. With time, this had become a fairly popular tool available on Codeplex and I’ve received a lot of feature requests. Obviously, with all the time that I have, I was able to integrate… almost none of them J. Hopefully, 2014 will be a better year.

The other very popular article is the one about MSCRM and data archiving. It is something that almost every client will ask for prior to buying a CRM solution and there still isn’t a straight answer. It always depends on why you need to archive, how much money you want to spend on it and who is going to do the job for you. With CRM 2013 coming out and SQL 2012, I may dig into some of the new performance metric and write an update on that topic over the next year.

The CRM 2013 Client API series has been a success as well.

For 2014, I am planning to start by writing a more concise article that highlights the changes in the CRM 2013 APIs including client and server operations. I will also spend some more time evaluating ISV solutions which I cannot wait to get my hands on. In the meantime, enjoy the holidays my CRM people!

Cheers!

CRM 2013 – Client API: Save Event Arguments

There are a few useful additions that have been added to the client API around the Save event. They are 3 methods that have been formally introduced:

getSaveMode: Returns a value indicating how the save event was initiated by the user.
isDefaultPrevented: Returns a value indicating whether the save event has been canceled because the preventDefault method was used in this event hander or a previous event handler.
preventDefault: Cancels the save operation, but all remaining handlers for the event will still be executed.

The key method is the getSaveMode function. Think about the new auto-save feature on updated forms. The getSaveMode function allow the javascript method executing on the Save event to know why/how the record is being saved. That gives you the flexibility as a developer to add some additional logic to handle your scenario… Below is the list of values returned by the getSaveMode function based on the entity type.

Entity Event Mode Value
All Save 1
All Save and Close 2
All Save and New 59
All AutoSave 70
Activities Save as Completed 58
All Deactivate 5
All Reactivate 6
User or Team owned entities Assign 47
Email (E-mail) Send 7
Lead Qualify 16
Lead Disqualify 15

This is fantastic as you can now write script to handle very specific scenario like an activity being resolved, a record being saved and closed, assigned and other cases. Below is a usage example in which we prevent the auto-save from happening as presented in the SDK documentation:

function preventAutoSave(econtext) {
   var eventArgs = econtext.getEventArgs();
   if (eventArgs.getSaveMode() == 70) {
      eventArgs.preventDefault();
   }
}

Cheers

CRM 2013 – Client API: Save & Refresh

I know these operations seem like very basic functionalities that have been around for a while. I wanted to point a specific new feature that comes with CRM 2013: the ability to run a callback method after a refresh or after a save triggered from a JavaScript method.

In the past, using the old Xrm.Page.data.entity.save method caused a refresh of the page which dismissed any code after the save in your script. Take this scenario for example…

  • You have button in your ribbon on an Account form
  • The button calls an external web service to update some of the account field values based on the account’s Primary Contact value which is on editable on the form
  • The web service only takes the account id as a parameter, it loads the records, reads it and takes action

With the old save method, you had to require that the user saves the account so that the value of Primary Contact is saved to the database, then click your button that will call the web service with account ID. Such a requirement certainly causes pain in user experience especially if there are a lot of situations where they need to hit save, wait for refresh and click another button.

With the new Save and Refresh, we now have the possibility to add callback methods:

Xrm.Page.data.refresh(save).then(successCallback, errorCallback);

// Parameters
// save => A Boolean value to indicate if data should be saved after it is refreshed.
// successCallback => A function to call when the operation succeed
// errorCallbak => A function to call when the operation fails. It gets called with 2 parameters (an error code and a localized error message)

Xrm.Page.data.save().then(successCallback, errorCallback);

// Parameters
// successCallback => A function to call when the operation succeed
// errorCallbak => A function to call when the operation fails. It gets called with 2 parameters (an error code and a localized error message)

Having had this problem in the past makes this one a good candidate for most exciting new client API feature for me 🙂

Cheers

CRM 2013 – Client API: Dialogs

CRM 2013 introduces a couple of client side dialog methods under the Xrm.Utility library. The goal is to remove the use of window.open and window.confirm and replaces them with alertDialog and confirmDialog and to support these alert messages in CRM for Tablets. Also, the key difference is that these methods will not block code until a user closes them. However, they contain a callback function parameter to indicate what code should be executed depending on the user’s response.

The Xrm.Utility.alertDialog(message,onCloseCallback) method displays a dialog box that contains a message passed as a parameter. Optionally, you can also execute another method (onCloseCallback) when the OK button is clicked.

var message = "Alert Dialog ! ";
 Xrm.Utility.alertDialog(message, onCloseCallback);
 

The Xrm.Utility.confirmDialog(message, yesCloseCallback, noCloseCallback) method displays a confirmation dialog box that contains an optional message and an OK and a Cancel button. A callback method can be set to run after each of the button is clicked.

var message = "Confirmation Dialog ! ";
 Xrm.Utility.confirmDialog(message, null, null);
 

Again in this case, the methods are only available for “Updated Entities”. You can see my previous post to get the list of entities on which this will not work.

Cheers

CRM 2013 – Client API: Client Methods

The CRM 2013 client API adds a few useful methods. Here I am going to focus on the context.Client methods : context.client.getClient() and context.client.getClientState. These methods are used to find out what kind of client is running and to get the information about it being online or offline. This is useful if you have scripts that you want to run when you are in the web application and nowhere else (not in Outlook client, not on Mobile client). As a consequence of this API change, the previous context.IsOutlookOnline and context.IsOutlookClient are now deprecated.

The getClient method returns the value Web (browser), Outlook (Outlook client) or Mobile (mobile app). The getClientState method returns Online or Offline, the latter applying only to the Outlook and Mobile clients. It’s also worth noting that these methods are only available for what Microsoft calls “Updated Entities”. In short, it’s the entities that have an updated interface (most key entities like Account, Case, Contact, basic activities like Phone Call, Tasks fit into that category). It also works on custom entities.

The entities that are not updated still use the “classic forms” and the Client methods are not supported on these. Here is the list of the entities with classic forms:

Address
Article
Article Comment
Bulk Delete Operation
Connection
Discount
Discount List
Document Location
Email Attachment
Follow
Goal
Goal Metric
Import Source File
Invoice Product
Order Product
Price List
Queue Item
Quote Product
Rollup Field
Rollup Query
Saved View
Service
Service Activity
SharePoint Site
Site
Territory
Unit
Unit Group

CRM 2013 – Real Time Workflows

In the CRM 4.0 and 2011 days, I remember multiple times when I had to write plugins do to operations that a simple workflow could do just because it needed to happen synchronously. Microsoft brought a solution to that concern with the latest CRM 2013 release by introducing real-time workflows.

In order to create an asynchronous workflow, you simply need to create a workflow and uncheck the “Run this workflow in the background (recommended)” checkbox.

If you have missed it or are trying to covert an Asynchronous workflow into a synchronous one, you can do it by deactivating the workflow and using the “Convert to real-time workflow” button.

The workflows’ contents are the same. There is no additional operation that you can do in real-time. The one thing that changes is the way you set up when the workflow gets triggered. Just like when plugins are registered, you have the possibility to choose if you want them to execute before or after a specific event:

Background Process Real Time Process

A few key notes on Real-Time Processes:

  • They can run
    • After record creation
    • Before or after a record update, assignment or status change
    • Before record deletion
  • They can be set to run as the owner of the workflow or as the person making changes to the record in CRM

It certainly gives us more flexibility when it comes to designing feature for real day to day usage. One thing still makes me wonder… Microsoft seems to recommend using background processes. Assuming the reason for that recommendation is performance, I guess it is a way to let application designers know that even though workflows can be run in real-time, this should only be used when really needed as opposed to making it a standard and clogging the CRM Server. To be confirmed…

Cheers