I am the first to admit I am not much of a coder. The only time I really put code to screen is for my new hobby of Arduino sketching (another blog coming soon). However, to be an effective functional consultant I still need to know the basics to make sure I am not expecting too much of the coders; there is no point documenting a design where one small element will take six months of development when an alternative approach will take half a day.
It is true that a good developer will push back on a bad design and suggest a better approach but, if a functional consultant knows the basics, they can steer the client down the right path to begin with and avoid disappointment later.
In this blog I will cover the two most common tools in the development kit-bag; jscripts and plugins. Please note this is not a comprehensive guide to developing in Dynamics CRM. For detailed information, consult the excellent SDK. If there are any developers reading this and I trip over a term or make a hash of something, please do add it to the comments. I would prefer to look foolish and learn something than lead the readers astray ;)
jscripts operate within the browser and, in my experience, commonly serve two purposes:
- Make stuff happen on an entity form e.g. pop up a warning on the create form of a record
- Do something when a custom ribbon button is pressed (2011 terminology, in 2013 we have no ribbon but the actions remain)
In terms of the form, there are four events you can fire the jscript off:
- OnSave (saving of the form)
- OnLoad (when the form opens on the screen)
- OnChange (when the value in a field changes)
- TabStateChange (opening and closing of Tabs)
For buttons, we can fire the script when someone presses our custom ribbon button. This can be useful as an interim step for doing something else e.g. firing a workflow/dialog or plugin (plugins are a little trickier because the server is oblivious to the jscript doing things, and plugins work on the server, but I will talk about how we get around that later).
The jscript does not care if the server knows about the change or not. So, for example, an OnChange script can do things on the form well before the form that is open has been saved. Also, jscripts fire immediately; there is no concept of pre or post-action; they just happen after the event occurs. Therefore, it makes sense not to overload a jscript with doing too much because it means the browser will get bogged down. For those of you who go to web sites where a warning pops up telling you a jscript is taking a long time to run, you will know how this feels.
CRM 2013 has done an excellent job of eliminating the need for a lot of common jscripts through the Business Rules function which allow an administrator to define field and form behaviours through configuration. Business Rules trigger off of field changes, or when the form opens, and allow for things like:
- Popping up a message box
- Changing the value of a field
- Making a field compulsory
- Setting the visibility of a field
- Locking or unlocking a field
Therefore, if you are upgrading from CRM 2011 to 2013 or designing a CRM 2013 system, consider Business Rules to reduce development time.
Plugins run on the server and provide a lot of flexibility and power. As they are server-side, they have no concept of CRM forms but simply respond to stuff that happens on the server. This can be through the saving of information on a form, through the web service layer or through the importing of data through the import wizard (strictly speaking, everything goes through the web service layer, but you get the idea).
Plugins do not trigger off of events, because events are something that happen on forms; plugins trigger off of messages happening in the back end of CRM. While jscripts get a few events to fire off, plugins get many, many messages to fire off. Jamie Miley, my roomie for the most recent MVP Summit and passionate freedom fighter did a great blog on the messages for CRM 2011 here and here (they are also available via the SDK). For CRM 2013, you can see all the messages in the SDK here. An example of a message is the ‘Create’ message for the Account entity. This means we can fire a plugin when the server knows about the creation of a new account.
Plugins can fire before or after the message i.e. a pre-plugin can prevent the creation of an account from occurring, and they can run synchronously or asynchronously meaning they do not have to hold up the user but can run in the background communicating and waiting for third party web services, for example.
Just as Business Rules have reduced the amount of jscript being written in CRM 2013, improvements to workflows mean these have also made in-roads in reducing plugins. Before CRM 2013, workflows ran asynchronously (in the background). While I am a big fan of workflows, only being able to run in the background made them a little awkward in some cases and downright impractical in others. With synchronous workflows in CRM 2013, they are a lot more powerful. A good example of this is the auto-numbering solution from last week. With asynchronous workflows there was always the potential for two workflows to fire close together and assign the same auto-number to two different records. As CRM MVP and fearless truth reporter, Jukka Niiranen recently showed, we can, with a strong level of confidence, rely on synchronous workflows to generate unique auto-numbers for records. Previously, robust behaviour like this was only possible with plugins.
Mixing Code and Helper Entities
This is a nice trick my comrade in arms, Olena Grischenko has shown me. It is one way to trigger a plugin from a ribbon button. The ribbon button can run a jscript and so we need a way for this to generate a message on the server. The trick is to create a new entity (a ‘helper’ entity) and have the jscript act on this entity in some way which the server knows about e.g. create a new record for this entity. This generates a message e.g. a create message and our plugin fires.
As a functional consultant, most of my work is concerned with the front end and adapting it to meet the needs of my client. However, sometimes I must resort to code to smooth out the rough edges or to meet a specific client requirement. In knowing the essentials of how code works with CRM, I can ensure I design the CRM system to be practical but also affordable. This makes for happier clients, happier developers but, most importantly, a better CRM system.