Tag Archives: javascript

Capturing a signature in a CRM form using html5

Scenario:

“I have a touchscreen.  I want to capture a signature in a Dynamics CRM form.  If the signature hasn’t been saved, then I want to allow a user to provide their signature.  The next time the record is loaded, after the signature has been saved, I want to load an imagine of the signature to prevent ‘resigning’.”

This is a relatively simple thing with Dynamics CRM thanks to web resources and Xrm.Page.  The general concept is to embed an html web resource in the form that captures the signature using the html5 canvas (preferably using an existing control vs. low level canvas programming).  Before saving, you want to copy the data from the canvas control into a Multiple Lines of Text type hidden field on the form so the data is stored when the record is saved.  Finally, when the web resource is loaded, you want to check if the field has data in it.  If so, you can assume a signature was previously recorded and just show the data as an image. 

Here’s the entire source code for a basic implementation:

1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>Signature</title> 5 <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script> 6 <script src="scripts/jSignature.min.js"></script><!-- download from http://willowsystems.github.io/jSignature/#/about/ --> 7 </head> 8 <body> 9 <img id="sigImage" alt="This is an image of the persons signature." style="display:none"/> 10 <div id="sigPanel" style="display:none"> 11 <div id="signature"></div> 12 <button id="clear">Clear</button> 13 </div> 14 <script type="text/javascript"> 15 $(function () { 16 var sigImage = $("#sigImage"); 17 var sigPanel = $("#sigPanel"); 18 var sig = $("#signature"); 19 20 var Xrm = window.parent.Xrm; 21 var sigBase64Attribute = Xrm.Page.getAttribute("msftpoc_esigbase64"); //replace this with your hidden "multiple lines of text" field with a max length of 1,048,576 22 var sigBase64Value = sigBase64Attribute.getValue(); 23 24 sig.bind("change", function (e) { 25 sigBase64Attribute.setValue(sig.jSignature("getData")); 26 }); 27 28 29 if (sigBase64Value != null) { 30 sigImage.css("display", "inline"); 31 sigImage.attr("src", sigBase64Value); 32 } else { 33 sigPanel.css("display", "inline"); 34 sig.jSignature(); 35 $("#clear").click(function() { 36 sig.jSignature("clear"); 37 }); 38 } 39 }); 40 </script> 41 </body> 42 </html> 43

All you have to do is add this web resource to your form (make sure you read instructions in the comments) and update the code to reference your field name.  A few things to note:

  • There are many controls out there, but I chose http://willowsystems.github.io/jSignature/#/about/.  It met all my requirements.  Feel free to use another.
  • The hidden field on the form for my entity is called msftpoc_esigbase64 and uses the Multiple Lines of Text type of Dynamics CRM.  Make sure to change the code to match your field name.
  • For simplicity, I chose to use the default data format of the jSignature control which is a base64 encoded string (hence my field name).  Since base64 encoded strings can be big, I set the max length field to 1,048,576 which is the largest Dynamics CRM allows.  The jSignature control supports other formats.  You could clearly improve on performance of this sample by using one of the smaller string formats.
  • My code doesn’t handle save/autosave side effects.  I simply copy the signature date to the hidden field using the change event of the jSignature control.   A more robust implementation would perhaps wire up to Xrm.Page.data.entity.addOnSave() and intelligently determine whether to copy the data into the field based on save state.  You might also want to consider switching to the image after as successful OnSave with signature if that makes the most sense for your requirements.  I’ll leave that up to you as an exercise for improvement.

Here are a couple screenshots for a quick visualization.

Before Save (signature capable canvas with clear button):

image

After Save (fixed image of signature):

image

@devkeydet

Debugging CRM web resources without ever deploying them

UPDATE: The steps explained below don’t work with CRM 2013.  However, Scott has a blog post which shows you how to get it working again:

http://develop1.net/public/post/Fiddler2-The-tool-that-gives-you-Superpowers-Part-2.aspx

One of my last posts was sharing how I use Visual Studio to debug CRM web resources:

http://blogs.msdn.com/b/devkeydet/archive/2013/06/19/eureka-f5-debugging-of-crm-javascript-web-resources.aspx

This approach was one of those discoveries that makes us developer types get a little excited because it allows us to do something we do repeatedly in a much more efficient fashion.  I just came across another one of those EUREKA moments thanks to Scott Durow (@scottdurow) and some his promising new http://www.sparklexrm.com project. 

BTW, Scott’s the man behind Ribbon Workbench for Dynamics CRM.  It’s the best Ribbon editor out there in my opinion.  I digress…

I was reading through http://www.sparklexrm.com/s/Tutorials/SetUpNewProject.html and discovered a little gift from Scott at the end of the walkthrough.  Steps 9-14 explain how to use www.fiddler2.com to let you debug changes to web resources without ever having to deploy them to Dynamics CRM.  How?  Steps 9-14 explain it.

Combine this with my post on F5 debugging from Visual Studio and you nearly have web resource developer productivity nirvana.  I just tried combining the two approaches.  It works beautifully!  I was able to make changes to JavaScript, hit F5, debug right in Visual Studio, and repeat over and over again.  I did this all without ever having to deploy the JavaScript file to the server.  Because of it, I was able to iterate on my changes in a fraction of the time CRM developer typically spend.  Try it yourself!

@devkeydet

EUREKA: F5 debugging of CRM JavaScript web resources

Scenario:

“Internet Explorer F12 JavaScript debugger is great, but I use Visual Studio.  I want to be able to set breakpoints in my JavaScript web resources which I author in Visual Studio, then hit F5 on the keyboard or Debug->Start Debugging from the menu or the Play Button on my toolbar just like I do with all other types of development in Visual Studio.  Visual Studio should then launch the right CRM url, attach its JavaScript debugger, and my breakpoints should be hit.”

This is the #1 piece of feedback I hear from the customers/partners/ISVs with whom I work.  I’ve always told people it’s not possible.  I just realized how wrong I am.  Given that I’ve used every version Visual Studio since it was first released, I am a little embarrassed to say I just had this “A HA!” moment.  Better late than neverSmile

As I mentioned in this post, I have stopped using the Developer Toolkit for Microsoft Dynamics CRM for web resource authoring in favor of the CRM 2011 Web Resource Linker/Publisher.  Note, I still use the developer toolkit for plugin / workflow activity authoring.  As I state in the post about the web resource linker tool, since it allows you to keep all of your web resources in a standard web project in VS, you get all the benefits of web project capabilities including other addons that work with web projects.  It’s this premise which brought me to my “A HA!” moment.  Below is a video walkthrough of getting this scenario working:

 

You can install the jQuery Code Snippets from:

http://visualstudiogallery.msdn.microsoft.com/577b9c03-71fb-417b-bcbb-94b6d3d326b8

@devkeydet

TOOL HIGHLIGHT: CRM 2011 Web Resource Linker/Publisher

I’ve blogged previously about why I like the approach CRM Solution Manager uses for authoring web resources in Visual Studio.  While I think CRM Solution Manager is a fantastic tool, there are ways to get some of the benefits of it’s approach to web resource authoring with a couple other free Visual Studio addins.  The first tool is CRM 2011 Web Resource Linker/Publisher.  This tool provides the ability to map a file in a Visual Studio project to a web resource in CRM.  Because of this, I can organize my scripts in a folder structure which aligns with the relative path naming convention that’s recommended in the CRM SDK.  See http://msdn.microsoft.com/en-us/library/gg309536.aspx for more details.  In the picture below, I just started with an empty web app and added the dkdt_ structure below:

image

Then, I simply link/publish the files:

image

Here’s an example of what initial linking looks like:

image

Notice that you can also create a new web resource right from the linker dialog.  Once you’ve linked the files, you can do things like multi-select in Solution Explorer and deploy/publish just the files you care about:

image

But wait, there’s more.  Since this is just a standard web app project, I can take advantage of all the goodness that Visual Studio 2012 has to offer.  For example, I can use NuGet to add the CRM 2011 Client Side VSDoc to get JavaScript Intellisense for Xrm.Page and simply drag and drop the file from Solution Explorer to the open JavaScript file that needs Intellisense and Visual Studio takes care of adding the reference:

image

I can also take advantage of addins which are designed to work with web projects such as Web Essentials 2012.  One example is the JavaScript Minification feature:

image

…which will give me a production optimized version of my JavaScript file.  Because these are just files, I can just relink if I want to test the minified version.  To hit home the “because they are just files” point, I’ll give you another example.  I’ve grown fond of TypeScript.  There’s even an Xrm.Page TypeScript definition file.  Because TypeScript ultimately produces JavaScript files, those files can simply be linked/published.  I think you are starting to see the “it just works” pattern here.

So, for me, I’ve stopped using the Developer Toolkit for Microsoft Dynamics CRM to Create and Deploy Web Resources because many of these things I talk about don’t work with the supplied template.  Furthermore, the Developer Toolkit forces you to deploy all of your web resources every time and it doesn’t publish.  You have to do that manually.  I’ve found the approach I lay out in this post to be the most productive way of using Visual Studio to develop web resources.  However, I still use the Developer Toolkit to Create and Deploy Plug-ins and Create and Deploy Workflow Libraries.

HTH

@devkeydet

Improving perceived performance in a CRM form

In general web development, there are useful patterns to improving the perceived performance in a web page.  A great example is this blog post:

http://blog.michaelckennedy.net/2012/11/13/improve-perceived-performance-of-asp-net-mvc-websites-with-async-partialviews/

Once you understand the core concepts of the post (even tough it’s about ASP.NET MVC), you should be able apply similar patterns with CRM Web Resources.  You can achieve the same thing by breaking up your UI pieces into separate web resources and laying them out on the form appropriately.  Or you can have separate div tags in your web resource for each thing that needs to be loaded discretely.  Often times, in CRM, people want to have the similar spinning loading indicator while the initialization of the web resource is happening.  I’ve put together a little sample of how I do it.  I’ve packaged it up as a managed solution you can download and review:

http://sdrv.ms/14dZNvi

Here’s a quick video of it in action:

All I did was add the dkdt_/simulateslowload.htm web resource to the form.

Basically, what happens is when the web resource loads it has the real content hidden.  I simulate an asynchronous web service call using setTimeout with a delay of 3 seconds.  The idea is that the real content gets fully generated after the web service call is complete.  Therefore, a delay.  While we’re waiting, I show a loading animation via an overlaid IFrame.  Once the 3 seconds are over, I hide the animation and show the content.

@devkeydet

CRM Online & Windows Azure: Improving the SSO experience

This is supposed to be one of a series of CRM Online & Windows Azure posts for which I have been building some samples.  While I really wanted to make this the second or third post, someone needed the explanation sooner, so this will be somewhat of a tease to the overall series.

Scenario:

I’ve already configured SSO across Windows Azure & CRM Online.  When I try to integrate an Azure hosted page into the CRM UI, I get the following errors:

This content cannot be displayed in a frame

To help protect the security of information you enter into this website, the publisher of this content does not allow it to be displayed in a frame.

This video walks you through why you get the error and how to work around it with a better user experience.

Here’s the code for the two helper pages…

ssoinitiator.htm (CRM Web Resource)

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

    <head>

        <title></title>

        <meta http-equiv="refresh" content="5">

        <script type="text/javascript">
   1:  

   2:             function getQuerystring(key, default_) {

   3:                 if (default_ == null) default_ = "";

   4:                 key = key.replace(/[[]/, "\[").replace(/[]]/, "\]");

   5:                 var regex = new RegExp("[\?&]" + key + "=([^&#]*)");

   6:                 var qs = regex.exec(window.location.href);

   7:                 if (qs == null)

   8:                     return default_;

   9:                 else

  10:                     return qs[1];

  11:             }

  12:  

  13:             function redirectToIntendedPage() {

  14:                 window.location = decodeURIComponent(getQuerystring("data"));

  15:             }

  16:  

  17:             function bodyOnload() {

  18:                 if (document.cookie.indexOf("AZURE_SSO_COMPLETE=") != -1) {

  19:                     redirectToIntendedPage();

  20:                 } else {

  21:                     var message = document.getElementById("message");

  22:                     message.style.visibility = "visible";

  23:  

  24:                     if (document.cookie.indexOf("AZURE_SSO_INITIATED=") == -1) {

  25:                         document.cookie = "AZURE_SSO_INITIATED=true";

  26:                         window.open("https://crmazrfedtest.cloudapp.net/SSOHelper.htm");//replace with your azure hosted version

  27:                     } else {

  28:                         document.cookie = "AZURE_SSO_COMPLETE=true";

  29:                         redirectToIntendedPage();

  30:                     }

  31:                 }

  32:             }

  33:         

</script>

    </head>

    <body onload="bodyOnload() ">

        <div id="message" style="visibility:hidden">

            <h1>Initiating Single Sign On...</h1>

            <p>This page will refresh shortly.</p>

        </div>

    </body>

</html>

SSOHelper.htm (Azure hosted)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

    <head>

        <title>SSO Helper</title>

        <script type="text/javascript">
   1:  

   2:             function bodyOnload() {

   3:                 window.close();

   4:             }

   5:         

</script>

        <meta http-equiv="expires" content="-1" />

        <meta http-equiv="pragma" content="no-cache" />

    </head>

    <body onload="bodyOnload()">

        <div>

            <h1>Single Sign On Complete</h1>

            <p>Please close this window.</p>

        </div>

    </body>

</html>

@devkeydet

Enable IE10 spell check in a CRM 2011 form

UPDATE: Yes, I am shamelessly promoting IE10 in this post, but this will work in any browser CRM that supports the spellcheck attribute.

Now that Polaris/UR12 is out, CRM works with browsers like IE10 and others that support the spellcheck attribute of the <input/> and <textarea/> tags.  According to Spellchecking in IE10, “Spellchecking is active by default on <textarea> and contenteditable elements, and off by default for text boxes.”

As you might expect, the Multiple Lines of Text fields on the form are rendered using <textarea/> tags.  Therefore, the spelling error suggestions will be shown.  However, Single Line of Text fields are rendered using <input/> tags.  Therefore the spelling won’t be checked.  I tested this out with IE10 installed on Windows Server 2008 R2. 

clip_image002

Notice the first attempt has no red error indicator underlining the misspelled text and the second one does.  Fingers crossed that there will be an option in a future release of Dynamics CRM to control configuring spellcheck for form controls.  In the interim, you can apply an OBVIOUSLY UNSUPPORTED, but relatively harmless workaround if you really want your textboxes to be enabled for IE10 spell checking.  Here’s how:

-Reference jQuery in the form

-Reference a JavaScript file in the form that contains the following function and call it on form load:

function enableSpellcheck(){

$(“:text”).attr(“spellcheck”,true);

}

After applying this, you will see that the text in your textboxes are being checked for spelling errors:

clip_image002[5]

Why is this unsupported?  Because the CRM 2011 SDK clearly states here that “HTML DOM manipulation is not supported” when the CRM product owns the HTML.  Yes, it’s supported for your web resources because you own that html.  The CRM product owns it’s HTML and can never guarantee your code won’t break if you do some wacky DOM manipulation of it’s HTML.

Because of this, I tend to stay away from sharing unsupported hacks.  However, this one seems to follow my unsupported hacks rule of thumb.  I always ask myself, “what are the potential side effects?”  Most of the time, the potential side effects (say after a service update / update rollup) are too risky.  In this case, the risk is low but technically unsupported nonetheless.  It’s your call.

I tested this out with IE10 installed on Windows Server 2008 R2.  You can download IE10 for Windows 7 SP1 / Windows Server 2008 R2 SP1 which you can download in preview form http://ie.microsoft.com/testdrive/info/downloads/Default.html.

 

@devkeydet

Make sure your CRM 2011 customizations will work with the upcoming cross browser release

UPDATE: The Dynamics CRM in the Field blog just published a useful post on Script Errors after Installing UR12.

The next update to CRM 2011 introduces an expanded range of supported browsers.  You can learn more about the upcoming release here:

http://crm.dynamics.com/en-us/Polaris

http://crmpublish.blob.core.windows.net/docs/Release_Preview_Guide_December_2012_FINAL.pdf

Ahead of the release, the latest version of the CRM SDK has guidance on ensuring the JavaScript code you write works in the supported browsers:

http://msdn.microsoft.com/en-us/library/hh771584.aspx#BKMK_WriteJavaScriptForMutlipleBrowsers

The SDK also links to a blog post by the CRM team covering a tool to help existing customers identify where they might have cross browser compatibility issues in their existing web resources:

http://blogs.msdn.com/b/crm/archive/2012/06/21/microsoft-dynamics-crm-2011-custom-code-validation-tool-released.aspx

This tool is not guaranteed to find every cross browser compatibility issue.  As the blog post says, it is also possible for the tool to identify false positives.  Therefore, I would recommend that anyone planning on deploying this update test it in a non production environment first before applying it in production.

The good news is that if you have already followed the guidance in the CRM 2011 SDK regarding what’s supported in terms of customizations using web resources, then your customizations should continue to work after applying the update once it is released.  The CRM team has already done the work to validate that going through supported APIs works with the update.  The bad news is that sometimes people implement unsupported customizations, without understanding that what they’ve done is not supported.  Often times, they find a way to do something on a blog.  However, the blogger doesn’t make it clear that while the approach “works” it isn’t supported.  The resources above will help you identify and fix those kinds of issues in your code.  Please read these resources carefully, understand the potential impact to your customizations, and test appropriately.

I want to reiterate that the supplied resources will not guarantee you haven’t missed something.  They are not a replacement for testing.  They simply make it easier to identify and fix issues before you test.  Hence reducing the issues you find during testing.

@devkeydet

Unit testing CRM 2011 JavaScript web resources

UPDATE: Fixed the video resolution issue.  Higher resolution (720p) version is available.

After writing my post on unit testing plugins, I’ve been asked a few times about how to do the same for Dynamics CRM 2011 JavaScript web resources.  While I knew it could be done, truth be told, I had never done any significant JavaScript unit test using Visual Studio other than unit testing Script# code using MSTest (the default unit testing framework in Visual Studio).  Sure, I had played around with QUnit.  However, QUnit is one of those JavaScript testing frameworks which requires tests to run within a browser.  What I wanted was an approach which met the following criteria:

  • Integrate with MSTest so:
    • I have one test dashboard for both my plugin & JavaScript unit tests
    • I get as much of the TFS integration goodness I can get
      • Gated check-ins
      • Running tests on a build server
      • Etc.
  • Write and debug my code without having to constantly deploy to a CRM server to test and iterate on my code
  • Mock things like Xrm.Page, web service calls, interaction with the HTML DOM, etc.
  • Integrate with the Developer Toolkit
  • Run tests OUTSIDE of the context of a browser

So I scoured the internet, tried a bunch of things I came across, and finally landed on approach which combines lessons learned from the following resources:

While the catalyst for this video was to demonstrate JavaScript unit testing in the context of Dynamics CRM 2011, the approach can be applied to any scenario where you are using JavaScript and some additional API (SharePoint, standard web app, etc.).

Just like with my post on unit testing plugins, it is not my goal here to convince you that you should embrace unit testing.  It’s for those of you who have already bought into the value of unit testing, want to apply it to JavaScript web resource development, and do it in a way that meets my stated criteria above.  In the video, I assume you understand concepts like mocks, fakes, etc. 

You can grab the finished example I show in the walkthrough here:

http://sdrv.ms/StxcgU

Hope this helps those of you who have been as eager as I have to unit test JavaScript web resources.

@devkeydet

Updated Developer Tips and Tricks Deck

I spend a lot of time talking to .NET developers who are looking at building business applications using Dynamics CRM.  They journey to understanding how to be a productive Dynamics CRM developer can sometimes be daunting.  There’s a bit to learn on top of your existing .NET / web dev skills.  If you go through any CRM developer training, including the Dynamics CRM 2011 Developer Training Kit, you usually won’t get to the level of productivity building solutions that a seasoned CRM developer has.  My Developer Tips and Tricks deck is aimed at helping people get there faster.  I just spent a good part of the day updating the deck.  It’s a living document where I modify as I learn new things.

@devkeydet