CRM 2015/CRM2013 – JavaScipt to get the current users name

This blog post will show you a quick way to get the name of the user using JavaScript.

Where you might use this functionality

This functionality is useful because you might need to update a User lookup field to a particular user in situations like

  • The current user changed a key field
  • The current user is primary contact for a project, account, deliverable.
  • Set a text field of the users name for reporting purposes.

Why are you mentioning it

To do retrieve the current user name in CRM 2011 it took a soap call to retrieve the user name field using the Xrm.Page.context.getUserId().  Below is a blog post I wrote

CRM 2011 – Setting a user lookup with the logged in user with Javascript

There is now a much easier way to do this in CRM 2013 and CRM 2015.  I found this way whilst reading this forum post

crm 2013: javascript get attributes from other entity in Contact Form

Start with the CRM SDK

The Hosk CRM developer mantra is to always start with the CRM SDK to see what methods and functionality exists which can help.

Searching the CRM SDK first helps you see what functionality Microsoft have added, most CRM developers will be surprised the number of new methods added.

It’s very easy for developers to copy and paste existing code in projects but just because it works it doesn’t mean its the best code to use.

This is classic case, the CRM 2011 code is long and involves a soap call, the new functionality added in CRM 2013 allows you to access the data with one line.

Microsoft Client code page – Client-side context (client-side reference)

There are three useful functions about the existing user (there’s another about language but I’m not including it).

getUserId
Returns the GUID of the SystemUser.Id value for the current user.
getUserName
Returns the name of the current user.
getUserRoles
Returns an array of strings that represent the GUID values of each of the security roles that the user is associated with or any teams that the user is associated with.

 

Xrm.Page.context.getUserId()

This would get you the SystemUser.Id

Xrm.Page.context.getUserName();

This would return a text string of the user name

Setting User lookups

The common reason for retrieving the user name and the user id is because both values are needed if you want to programatically set a lookup field in CRM.

Example code is shown below


var setUservalue = new Array();
 setUservalue[0] = new Object();
 setUservalue[0].id = Xrm.Page.context.getUserId();
 setUservalue[0].entityType = 'systemuser';
setUservalue[0].name = Xrm.Page.context.getUserName();

Xrm.Page.getAttribute("LookupField").setValue(setUservalue)

Alternatives

In the requirement I was working on I used JavaScript because I needed to set a field dynamically and instantly.  Other CRM customizations may have different requirements and you could set the lookup field using a Plugin or a workflow.

What I have learnt

  • Use the CRM SDK to see what functionality exists, there might be a better way
  • Microsoft added a new getUserName method in CRM 2013
  • You need the guid, name and entity type to set the value of a lookup field
  • If you don’t need to set the lookup instantly you can use workflows or plugins
  • CRM forum posts provide extremely useful information from a number of CRM developers

 

Advertisement

CRM 2015 SP1 – Turbo forms use asynchronous JavaScript web resource loading

I was reading this blog post from the CRM Lady

Turbo Forms in Microsoft Dynamics CRM 2015 (v7.1.0)

The article points to some good resource learn more about the new turbo forms.

The article from the CRM Team has a wealth of interesting information and lots of healthy warnings for you

Microsoft Dynamics CRM Online 2015 Update 1 – New Form Rendering Engine

What are the new turbo form

Microsoft have been doing lots of tinkering how the CRM forms are rendered.  This graphic shows the effect

// // // // // //

When I saw the graph above my first thoughts were

  1. WOW, Awesome
  2. How did they get such a dramatic improvement
  3. Will this break my customizations

How did Microsoft Improve loading times

I will quote the article

There are 2 main changes that have been made: loading process of the form, and handling of cache.

The article indicates they have moved to parallel loading and are caching more data.

 

Hmmmm Parallel Javascript loading

The increased form loading is great but parallel loading can have some downsides.  I first came across Javascript parallel loading in CRM 2011 rollup 12, you can read about here

To speed up form loading in CRM 2011 they switched to parallel loading and the result meant lots of Javascript methods suddenly stopped working.  The reason for this was because one Javascript file was calling a method on another javascript file.  This worked when the Javascript files were loaded in an order but when you load them all at once sometimes one Javascript file tries to call another dependant Javascript file which is still loading.

So suddenly lots of Javascript errors appeared and all developers had to write a Javascript wait file, like CRM MVP Scott Durow talks about in this article

This is a significant change and could cause lots of errors if you have Javascript code in your OnLoad functions which call other Javascript files.

I noticed a new section appeared in the mdsn article Write code for Microsoft Dynamics CRM forms

Manage library dependencies

As a performance optimization, Microsoft Dynamics CRM forms load JavaScript web resources asynchronously and in parallel. This means that the order in which the libraries are configured for a form does not guarantee that a library will be fully downloaded and initialized before another library might attempt to use one of the objects defined in it.

If you have code that depends on another library to be fully downloaded and initialized, the most straightforward approach is to combine both libraries within a single JavaScript web resource with your code below the library code. A more sophisticated approach is to use libraries such as head.js or require.js to control how the separate libraries are loaded.

 

Is Parallel loading good or bad

There is a quote in blade runner

Replicants are like any other machine. They’re either a benefit or a hazard. If they’re a benefit, it’s not my problem.

Upgrading to CRM 2015 SP1 could cause big problems to Javascript customizations.  It’s good practise to split up your Javascript code to separate files to make it reusable and maintainable but now Microsoft are recommending we put everything in one file.  This could turn out to be one big massive Javascript file, which is ok for performance but maintaining and working with this file is difficult.

This change could catch many CRM developers out because the errors are intermittent, sometimes the javascript files will have loaded in the correct order and work.

It will involve developers writing Javascript code which waits until all the Javascript files load which will cancel out any benefits from parallel loading.

It could be seen as an opportunity to restructure Javascript code to have a self contained loading script and then move other Javascript functions to OnChange events.  This would be a double win of increased loading time due to parallel loading and running less code.

You can use Legacy form loading style

There is a system setting which contains a global setting to control which form loading style you use.

It’s a great idea for Microsoft to put this in because the new speedier form loading code might take some while getting use to it.  When CRM 2011 polaris release came it, it caused a raft of blog posts because CRM Javascript customizations suddenly stopped working.

Settings -> Administration -> System Settings -> General. Select “Yes” under “Use legacy form rendering”

In a perfect world it would have been great to have a entity setting rather than a global setting for the form rendering.

I thought I would write about this because it could effect a lot of people and I never spotted this change until today.

 

How to find Javascript files used in Microsoft Dynamics Forms

Sometimes when you work on a CRM project which contains lots of Javascript files, it can be difficult to determine what Javascript files are being used and which ones are still needed.

The route cause of this is Microsoft Dynamics CRM forms can have lot of methods triggered from fields or ribbon buttons but these can be difficult to find to find what Javascript files are being used.

Where is Javascript triggered in CRM

Javascript files can be used on CRM forms and the code can be triggered on forms loading/saving or by the OnChange event of a field and the Ribbon buttons.  Below is where Javascript files can be used in CRM

  • Javascript triggered by OnChange events
  • Javascript triggered by Ribbon buttons
  • Javascript triggered in form OnLoad/OnSave events
  • Javascript files used in html pages

There are many different areas Javascript can be used but it can be difficult to see what Javascript files are used and linked to field OnChanges, ribbon buttons.

One of the reasons this is difficult is because the CRM UI means it’s not easy to see what fields have Javascript functions triggered via the OnChange event and the only way is to either look at the Javascript files and hope the CRM Developer has used a logical naming structure.

or

You can click the fields in the CRM form and check if there is an OnChange event.

Javascript development and deployment

Javascript development and Javascript deployment can be a bit disjointed.  One method is to write the Javascript file in Visual studio then you copy the Javascript file and paste it into the CRM form changes, save and publish.

It should be noted this isn’t a new problem for CRM 2015/2013 , there have been lots of tools created to help the process.

CRM MVP Mitch Milam created the export Javascript file tool, which I hada used in older versions of Microsoft Dynamics CRM, which you can read about here

The Microsoft Developer toolkit brought big improvements which allowed you to deploy/update Javascript file changes from Visual studio.  I go through the process in this video from Hosk CRM Dev Youtube channel

What Javascript files are used

I recently worked on a project which had gone through some optimization and refactoring, my current task is finding out if all the Javascript files are needed for each of the forms.

The reason the project is in this state is we quickly needed to optimize the code and whilst doing this the Javascript was optimized and refactored, this has resulted in some of the Javascript files not being needed

The code was refactored but some of the Javascript files which were no longer used were not removed.

The code was also part of the Async Javascript load issue, which happened in CRM 2011 Rollup 12

CRM 2011 – Things learnt when reviewing Javascript code on form loads

Here is my blog post on CRM form performance

CRM 2011/2013 Investigating CRM Form Performance issues

 

The Problem

Tidy up Javascript files on forms, remove the WaitForScriptsLoaded Javascript file and replace the onload method with the entity Javascript file.

Remove Javascript files which are no longer referenced.

Factors

To make the problem harder, the Javascript was split over 10 different Javascript projects, which made find if Javascript files were used

To help me the project adhere’s to Javascript best practices and uses Javascript namespaces.

link to Javascript namespaces

Things to consider

When looking at what Javascript files are needed don’t forget to check the Javascript files used for the ribbon buttons, in this particular project most forms had 5 custom ribbon buttons.

Tools used

Fiddler

I used Fiddler to track what calls were being made out of the form

Visual Studio

I used Visual studio to look at the Javascript files included on the FORM.

F12 Debugger

Press F12 on a record and I could see all the Javascript files being used.

Script finder tool

I knew there was a script finder tool but I couldn’t find it when searching the internet.  Thankfully a reader added a comment and of course it’s in the everyone’s favourite CRM tool or collection of Tools the XRMToolbox.

The XRMToolbox has a Script finder tool which will list all the Javascripts and will show the event e.g. OnLoad, OnSave, OnChange as you can see from the screenshot below

image_24 (2)

 

The tool looks great but I would say the project I was working on has a lot of Javascript and when I tried I pressed the find scripts button it never came back.  I think it timed out because there are loads (hundreds) of scripts and functions.

Process of finding unused Javascript files

I did try doing a find in files but this proved to be very slow and seemed difficult, I eventually decided this process wasn’t really working.

So I looked at the problem a different way

How do I find what files are used when the CRM form is being used?

 

I came up with two main methods.

Method 1

Go through the main Javascipt file specified in the form onSave/OnLoad and look what other Javascript files/methods are referred.  Thankfully the Javascript files used were developed with using Javascript Namespaces so I could search for the namespaces in the file to see what other Javascript files were used.

I cold then compare the Javascript files listed in the Javascript files for the form and what Javascript files were referenced in those Javascript files.

Method 2

When the Javascript form is being used in CRM you can press F12 to get the debugger up, I  could see what Javascript files are loaded.

 

Why did this happen

Good CRM Development will mean the CRM developer will create lots of seperate Javascript files which can used in multiple CRM forms.  The reason you split the Javascript file into common Javascript files is because it’s better to use the same Javsacript code in many different forms rather than copy the code in many different Javascript files (e.g. if you have one Javascript file for each form).

You never want to duplicate code because if there is a bug in the code then you would have to fix all the various copies of the code and the chances are you would forget to change some of them.  Later it would be difficult for the CRM developer to know which code was fixed and which code still had the bug in.

When Javascript code is no longer needed CRM developers often forget to remove Javascript files and methods, this can add to the confusion for a CRM developer when there are javascript files and methods which don’t seem to be used.  It can be scary to be the CRM developer to remove unused Javascript files and methods because it’s difficult to be 100 percent sure they are not used anywhere.

 

 

 

 

CRM 2013 – Using Dynamic Javascript

Javascript is a slippery beast, Slave to no one and master to many.   It’s just a quick blog post today, not as quick as this article I found written by me

CRM 2011 – Javascript snippet – How to remove all existing values from an OptionSet

 

I’m more happy in the .net and C# world with it’s static variables.

What I mean by this is C# you have to declare the variable you are going to use e.g.

  • string
  • int
  • bool
  • custom type

 

but with Javascript a var can be anything, it’s like something out of X-men changing and morphing it’s way along.

Here is a good article about static and dynamic languages

Static vs. dynamic typing of programming languages

 

Why doesn’t Hosk like Dynamic Javascript

Good question, surely I should like dynamic things.

Some of the reasons I don’t like it are

  • Hard to read/understand other peoples code
  • Bugs can be compiled and then appear in runtime when the code is run
  • It encourages the cowboy coders to go to town
  • It’s strange and different

 

Get to the point

I’m not saying I don’t like Javascript it’s just sometimes I want to do things and I’m not sure HOW because the syntax can be a bit crazy.  Like all developers once we have a working example in our hands, we are off.  So recently I saw some interesting Javascript in a project I am working and I was intrigued to understand how it worked and use it again.

One cool feature about Javascript is the ability to pass in function names using variables, a bit like reflection(ish), but only once you know how because I tried searching for this on the internet and fell down a big dark hole.

 

Example

On a form I have 4 OptionSets which we are dynamically setting the values to.

If I pass in the OptionSetField name I can dynamically get the control


var control = Xrm .Page .getControl (OptionSetFieldName);

I can then clear this control


control. clearOptions();

I can then add in the new values and build it up.  The beauty of dynamic code is I can use the same code for all the OptionSets because I can pass in the name of the control.

When adding a the new optionSet values in, I can use a dynamic variable to retrieve the field name from array, which contains values retrieved from a fetchXML query.  The childField is the name of the field in CRM.


      var option = {
                    value: retrievedOptionSet[i]. text == "" ? "null" : retrievedOptionSet[0].attributes [childField]. value,
                    text: retrievedOptionSet[0].attributes [childField]. formattedValue
                };
                control. addOption(option);
            }


Summary

It may be common knowledge to all you JavaScript wizards out there, but I hadn’t used or seen JavaScript using dynamic names.  It makes sense and it’s very useful so I thought I would share it with you

 

CRM JavaScript Programming Best Practices in different versions

Microsoft has a very good page on Javascript programming in CRM – http://msdn.microsoft.com/en-us/library/hh771584.aspx

I was reading this today and I noticed it had a Javascript Programming Best Practices section.  Javascript is very useful but I often feel the code produced in Javascript is not alway the best quality because there is no type checking and the process of writing the code and uploading is a bit of a hassle.

 

I have selected a couple of the best Practices but to read the full list go to the article

Microsoft have also created best practices for different versions, links to below to the different pages

CRM 2011 – Javascript best practices

CRM 2013 – Javascript best practices

CRM 2015 – Javascript best practices

 

There are a lot of best practices and it’s a really good article, but below are my top 4 best practices from the article.  I would definitely recommend you read the different articles.

 

Use a Cross-browser JavaScript Library for HTML Web Resource User Interfaces

A cross-browser JavaScript library, such as jQuery, provides many advantages when developing HTML web resources that must support multiple browsers. JavaScript libraries like jQuery provide a unified development experience for all browsers supported by Microsoft Dynamics CRM. These capabilities are most appropriate when you are using HTML web resources to provide user interfaces. JavaScript libraries like jQuery provide consistent ways to interact with the Document Object Model (DOM).

Use Feature Detection When Writing Functions for Multiple Browsers

Even when you use a cross-browser library like jQuery, you need to be very aware of differences between browsers. You can generally detect which browser is being used by querying thenavigator.useragent property. This is called browser detection. Browser detection is not a good strategy for most cases because it can’t take into account what features newer versions of a browser have. Also, some browsers provide the capability to modify the navigation.useragent property so that they appear to be a different browser.

Feature detection is the recommended approach. By detecting what features are available, you can create code paths for the browsers you support without knowing exactly which browser is being used. For more information about feature detection, see How to Detect Features Instead of Browsers.

Define Unique Names for Your JavaScript Functions

When you are the only developer for an HTML page you can easily manage the names of the JavaScript functions you use. In Microsoft Dynamics CRM, other solutions may add JavaScript functions to the page where your function is used.

If two JavaScript functions on a page have the same name, the first function defined is overwritten by the second. For this reason, make sure that you define unique names for your JavaScript functions. For more information, see Creating Script Libraries.

Use Asynchronous Data Access Methods

When you access data by using the Microsoft Dynamics CRM web services that use the REST or SOAP endpoint for web resources, always use an XMLHttpRequest that is configured to execute asynchronously. The reason is that the browser operates on a single thread. If that thread is being used to execute a long-running process synchronously the browser will stop responding.

CRM 2011 – Be careful removing fields from a form

I had written some javascript which retrieved values from a field which I was displaying on the form.

I had added an account field onto a quote product, so I could then use the account id to inject into some fetchXML in a subgrid so I only showed quote products which had only been sold to the the account selected on the quote.

I could have looked this up using a query but I thought I would add it onto the Quote Product form and pass the value using relationships.

It worked fine but as I came to release the code I thought I didn’t really need the account lookup field on the form so I took it off.

Then when testing my code it wasn’t working, so I pressed F12 and was ready to debug, except it wasn’t running my code because it was erroring whilst trying to get the account lookup field, with this error.

SCRIPT5007: Unable to get value of the property ‘getValue’: object is null or undefined

So the morale of the story is, you can only access fields in Javascript which are on the form.  The solution to this problem was to make the fields not visible.

This is logical when I stop to think about it because why would CRM load up all the variables which are not being used on the form, it would be a complete waste of time.

This was an early morning, not fully awake error but it does show you the danger of taking off variables from a form without seeing if any javascript uses those fields for something

CRM 2011 – Javascript to set the current date and time

A quick blog entry and a suprisingly easy and small piece of code

In the code below I have function which gets triggered when a user ticks the confirm Closed checkbox it then sets the current date and time.

if the user untick the checkbox I wipe the date and time value.

The date functionality in javascript holds the current time as well

 function confirmClosedOnChange() {
 var closedConfirmed = Xrm.Page.getAttribute("new_closedconfirmed").getValue()

if (closedConfirmed) {
var currentDateTime = new Date();
Xrm.Page.getAttribute("new_confirmedcloseddate").setValue(currentDateTime);
} else {

Xrm.Page.getAttribute("new_confirmedcloseddate").setValue(null);
}
 }
 

CRM 2011 – Displaying images for a contact

A quick blog post to point you in the direction of a couple of exellent tools to display images in for a contact (or other entities).

The timing of this was a day too late (for me) because I had written a basic way to display images yesterday and then today I find the solution today and it works better than mine because you can have multiple images and it resizes the images in a neat way, working out the aspect ratio from the available space.

Both solutions use the method of uploading picture files as a note for the contact and then display these.

For the html, jquery method then go to this blog and you can download the solution file

http://mscrmblogger.com/2012/03/31/imagebrowser-webresource/

You will need to add the image img_browser.html as a webresource onto your page.  This is very useful because I think (I haven’t tried it) use this to display images on other entities.

The MSCRM blogger team have also created a silverlight version, well actually they created that first, you can get that here

http://crmattachmentimage.codeplex.com/

A great contribution to the CRM community and will save everyone writing the same solution over and over.

CRM 2011 – displaying similar quote products in a subgrid by injecting FetchXML

I had a requirement this week where a customer was adding products to a quote and when they selected a product they then want to see previous quotes which featured the same product and the price and quantity it sold for.  Basically the sales person wanted to see what the product had been sold for before to make sure the price they were quoting wasn’t too radical.

The idea I came up with was to have a grid on the Quote Product form, which displayed quote products of the same type as the quote product selected.

This would mean I would have to dynamically change a view or show items in the grid.

I created a view showing the fields of the Quote Product and then specified a product I was searching for.

I found this excellent blog post

CRM 2011 – Change Subgrid View Java Script

This blog post explains how you can load in new fetchXML into a subgrid, you can inject the FetchXML on the form onload, which enables you to get some variables from the form and inject them into FetchXML which then is used to update the SubGrid.

So on my Quote Product form I checked to see if a product had been selected on the form OnLoad, on this particular form the subgrid doesn’t load until you have selected a product, unit and a quantity, which then reloads the form.

The code itself which I have taken and changed from the blog post referenced above, is quite clever.  The function is called and if the SubGrid has not been loaded, it calls the function again after a small time delay.  This ensures the SubGrid is loaded before you try and inject the fetchXML into the view.

The FetchXML is created, I got the fetchXML by doing an advanced find on my previously created view, there is a button which allows you to retrieve the FetchXM, which is very useful.

function UpdateSubGrid() {
var quoteGrid = document.getElementById("Quote_Products");
var productId = Xrm.Page.getAttribute("productid").getValue();
if (productId != null){
//If this method is called from the form OnLoad, make sure that the grid is loaded before proceeding
 if (quoteGrid == null) {
 //The subgrid hasn't loaded, wait 1 second and then try again
 setTimeout('UpdateSubGrid()', 1000);
 return;
 }

var fetchXml = ""
+ " <entity name='quotedetail'>"
+ " <attribute name='productid' />"
+ " <attribute name='productdescription' />"
+ " <attribute name='priceperunit' />"
+ " <attribute name='quantity' />"
+ " <attribute name='extendedamount' />"
+ " <attribute name='salesrepid' />"
+ " <attribute name='uomid' />"
+ " <attribute name='manualdiscountamount' />"
+ " <attribute name='baseamount' />"
+ " <attribute name='new_quoteid' />"
+ " <attribute name='quotedetailid' />"
+ " <order attribute='productid' descending='false' />"
+ " <filter type='and'>"
+ " <condition attribute='productid' operator='eq' uiname='1 Function Easy Clean Mini Kit' "
+ " uitype='product' value='" + productId[0].id +"' />"
+ " </filter>"
+ " <link-entity name='quote' from='quoteid' to='quoteid' visible='true' link-type='outer' alias='a_ff5a49bd001a45f7a14dd99a28f37f91'>"
+ " <attribute name='customerid' />"
+ " <attribute name='name' />"
+ " <attribute name='quotenumber' />"
+ " <attribute name='quoteid' />"
+ " </link-entity>"
+ " <link-entity name='product' from='productid' to='productid' visible='false' link-type='outer' alias='a_e0b689bded554f07ab0b241a932d482e'>"
+ " <attribute name='productnumber' />"
+ " </link-entity>"
+ " </entity>"
+ "</fetch>";
 // alert(fetchXml);
 //Inject the new fetchXml
 quoteGrid.control.setParameter("fetchXml", fetchXml);
 //Force the subgrid to refresh
 quoteGrid.control.refresh();
}
%d bloggers like this: