Friday, June 27, 2008

Are you sure you want to navigate away from this page?

Within a form's onload script, it's sometimes necessary to override the default value of a field. On a recent project, I ran into a scenario where this became necessary for the previous development team. They implemented a custom encryption solution where client-side code called a web service to decrypt CRM data. The script then set the DataValue (field text value) of various fields to the decrypted value.

The side-effect of that code was that every time a user opened a record and then closed it (not making any changes), they were prompted with an alert box with the question "Are you sure you want to navigate away from this page? Your changes have not been saved.". Needing to click OK after viewing records became very annoying for users so they asked me whether there was anything that could be done to avoid this unnecessary message.

In looking at the SDK and the built-in code that determines whether a form is "dirty", I discovered that it's possible to set the defaultValue of a control to the current DataValue of the control. In other words, after making changes to the properties of a control (those that use the defaultValue and DataValue properties), you can reset the default value for the control to the data value that was set by other code.

My first attempt at this was to place the following at the bottom of the form's onload script:

crmForm.all.new_regionid.defaultValue = crmForm.all.new_regionid.DataValue;

I thought for sure that would solve the problem, but it didn't. Due to the placement of the onload code in the rendered page, this code ran too early and thus did not have the desired effect.

The use of the JScript function "setTimeout" did the trick, as in this example:

window.setTimeout("crmForm.all.new_attorney.defaultValue = crmForm.all.new_attorney.DataValue", 2000)

I placed that line at the bottom of the form's onload script and the unwanted "are you sure" prompt stopped appearing.

The use of setTimeout means that the user must keep the form open for at least the number of seconds you specify for the code to work. Unless someone opened a form accidentally, two seconds should allow the code to work a vast majority of the time.

Monday, June 16, 2008

What you need to know

A coworker and I were discussing over lunch last week all of the skills that a person needs to possess to properly plan for a Dynamics CRM 4.0 installation, to configure and customize the application, and to keep the application up and running 24x7. This topic came up as we talked about different professions and the level of ongoing learning that's required. For example, his fiancee is studying for the Bar Exam so we talked about the need in that profession to stay on top of the ever-changing legal landscape and courtroom rules to perform that job effectively.

Those responsible for implementing Dynamics CRM, too, need to keep on top of an ever-changing technology landscape while remaining skilled with dozens of existing technologies. When we started naming the skills needed to deploy, customize, and maintain a Dynamics CRM deployment we were surprised at how long the list became. But it explained the late nights and weekends that are sometimes necessary to do our job effectively.

Here's the list of Dynamics CRM implementation skills we came up with, in no particular order:

Dynamics CRM planning, installation, configuration
All Dynamics CRM features and functions (UI, SDK, Filtered views, etc.)
General business savvy (sales, marketing, support, industry-specific)
JavaScript/JScript
Client-side script debugging
HTML
HTML DOM
XML
XML DOM
SOAP
Fiddler output analysis
AJAX
Cascading Style Sheets
CSS behaviors (HTC files)
Object-oriented programming (OOP)
.NET framework
ASP.NET (page development and Web Services)
ADO.NET
C#
Relational database concepts
SQL Server administration
SQL language
SQL clustering
T-SQL development / stored procedures
SQL Reporting Services
Windows Server 2003 / 2008
IIS configuration
SMTP
SSL
Windows Services
Active Directory
Server/network security
Microsoft Exchange
Microsoft MOM
Hardware deployment
TCP/IP (at least the basics)
Microsoft Office
Data Migration
Windows Workflow Foundation
Windows Communication Framework
Debugging (client-side, .NET, SQL)
Systems Integration (messaging, BizTalk, etc.)
Load balancing
Web farms
High-availability (HA) system architecture
ActiveX / COM
Visual Studio 2010 (Added this one and the skills below in January 2010)...
.NET Framework 4.0
C# 4.0
SQL Server 2008
XAML
SharePoint 2010
JQuery and other JavaScript libraries
Microsoft Azure

In reading this list again, it's understandable why SaaS is catching on! That's a lot to know -- and to keep up on on a regular basis.

Still, think about the trade-offs of moving to a SaaS environment. If you really want your information technology to fit your business and not the other way around then it's often worth hiring people who can (and enjoy) working with the technologies noted above. For some reason, I'm one of those. Am I insane? Perhaps. But getting all of those pieces working smoothly and tailoring solutions to a business is very rewarding. And if my Dynamics CRM clients are seeing a return on their investment then this is a win for everyone involved.

Now, please excuse me. I haven't had a chance to crack the seal on my Silverlight Unleashed book yet so I have some reading to do...

Monday, June 9, 2008

An easy way to debug client-side code

On a recent project CRM 4.0), I was asked to revise the default behaviour of the "Convert Activity... To Case" option on the E-mail form. The client did not want the modal dialog box to appear (the one prompting for the Customer and Subject) and wanted instead to set default values in code. The business purpose for the change was to increase productivity and avoid incorrect data-entry by their 20+ users, who use that feature several times each day.

Below is a step-by-step process for making this change.

Note: Since this example requires a change to a core CRM js file, Microsoft considers this an "unsupported" customization.

In order to debug the "To Case" command (outlined below) I loaded my favorite IE browser add-in development tool... IE WebDeveloper. (See my previous blogs about this product.)














Using IE WebDeveloper, I was able to determine that the To Case menu option calls the function convertToCase with a parameter of 4202.

The screenshot below shows the "To Case" menu option (in the HTML DOM) highlighted on the left and the JScript function outlined on the right.




To start debugging the convertToCase(4202) function call, I used the Run Scripts feature of IE WebDeveloper to execute the JScript debugger statement along with the function, as shown below:



After clicking Run, I started debugging with Visual Studio 2008.



Since the script is running in the context of the current CRM web page, I was then able to step into the convertToCase function, which it turns out resides in \inetpub\wwwroot\_static\Activities\Activity.js.

Finally, I revised convertToCase (removed the code that opened the modal window) to my liking and debugged through the code a few more times to make sure my customization worked as planned.

The coolest part of using IE WebDeveloper to help out with this customization is not needing to place the debugger statement inside a script file -- I was able to start debugging immediately within the current page. This same technique can be used to fire onLoad, onChange, or any other window/document/element event. For example, to fire onLoad you can run this in the IE WebDeveloper:

debugger;
crmForm_window_onload0();


Again, this lets you step through the onLoad script of any form without the need to place a debugger statement in the form code.

As another example, assume you want to fire the onClick message for a custom button added via ISV.Config and debug into the JScript that CRM constructs. Run this code in the IE WebDeveloper script window to start a debug session in Visual Studio:

var customButton = document.getElementById("ISV_New_4_GPInvoiceLookup").childNodes.item(0).childNodes.item(0).childNodes.item(1);
var evt = document.createEventObject();
debugger;
customButton.fireEvent("onclick", evt);

Sunday, June 8, 2008

IE WebDeveloper

A while back I discovered a great browser add-in and development tool named IE WebDeveloper. Although there are some similar add-ins available that are free, it's worth the small price to get the extra features in this app.

Here's how I find myself using IE WebDeveloper while working on CRM 4.0 implementations:
  • Get the schema name of any attribute on a form.
  • Execute scripts (jscript/javascript) against the current page. Examples: fire the onLoad event for the page or onChange for any field, test your code on the live CRM form page (current DOM) before publishing it, manipulate the browser DOM interactively to test custom UI functionality, or write and run a script to list all "dirty" fields on a form.
  • View the script tied to any DOM element. I use this as a quick way to view the onChange code for fields.
  • Interactively change the content, attributes, and style for any DOM element. This is useful for placing custom elements on the page, such as an icon next to a field. My team did this recently to provide real-time duplicate checking for data entered into a field. Being able to place images on the form, nudge them around, etc. saved a lot of time and guesswork. (Of course, what I described was an "unsupported" customization.)
  • Get the id (Guid) of an entity listed in a grid.
  • Capture all window, document, and element events. I used this recently on a custom ASP.NET page (integrated into CRM) to write code to handle various mouse events.

Besides being able to easily browse up and down the page DOM, the second most useful feature of IE WebDeveloper is the ability to run scripts interactively against the current page. You can dynamically hide and show tabs, test field validation code, loop through elements to perform actions on them, and just about anything else you might need to do to interact with any screen in CRM. It really takes the guesswork out of how CRM pages are constructed and how to customize them.

As for other browser tools, I also use Instant Source for interactively browsing the page DOM and Fiddler to help with performance and troubleshooting.

Lastly, if you have a weekend (and hard drive) to fill and want to add to your development tool collection, then it's hard to find a larger collection of dev tools than Scott Hanselman's "ultimate tools" page.

A wealth of knowledge... and how to keep up.

If you implement Dynamics CRM full-time like I do, you want to be sure to keep up on the latest SDK releases, sample code, tools, tips, tricks, etc. One app that makes this easier is Copernic Agent Pro.

With Copernic's web page tracking feature, you enter links for the pages you want to track, set up the tracking schedule, and it will send an e-mail to you with the pages that were updated. It even highlights the content that's new or updated.

The app's main feature is to search for web content, filter-out missing pages and those that don't contain the words (or Boolean expression) that you specify, and to highlight the search "hits".

In my next blog I'll list the 40+ blog sites and general MSCRM sites that I have Copernic tracking for me each day. Now, if only it would consolidate all blog updates into one Word doc or PDF and load it to my Amazon Kindle for my daily commute... panacea!