A Better Dynamics CRM E-mail Editor With Markdown

Last month I wrote a post called A Better Dynamics CRM E-mail Editor With TinyMCE in which I showed how to create a better Dynamics CRM e-mail editing interface using TinyMCE. Since then I have done some work with Markdown, and I decided it would be an interesting exercise to make a Markdown-enabled e-mail editor. For typical CRM users, the TinyMCE editor is probably the better approach for e-mail editing, but I think Markdown is a useful, light-weight HTML editing solution, and this overview will show how easy it is to get working inside Dynamics CRM.

Fundamentally this solution behaves the same as its TinyMCE cousin:

  1. Use JavaScript to open a popup window with the e-mail text displayed in a Markdown-enabled textarea.
  2. Use JavaScript to write the e-mail body back to the CRM e-mail description field and close the popup window.

The only visible difference (other than the use of Markdown itself) is that for the e-mail editing screen in this example, we will have a live preview of the HTML in a separate container because the input text area only shows Markdown, not HTML.

Here is what the editor window will look like when we're done (you have to supply your own awesome imagefor the body):

E-mail editor window

Enabling Markdown support in the browser

To work with Markdown in the browser, we will be using PageDown, which is what StackOverflow uses for Markdown previewing. The PageDown project includes three JavaScript files:

  1. Markdown.Converter.js - This does the Markdown->HTML conversion.
  2. Markdown.Sanitizer.js - This lets you whitelist the HTML tags you want to allow. For example, you might not want to render script tags. We will not be sanitizing the HTML output in this example.
  3. Markdown.Editor.js - This enables a live preview of the Markdown->HTML conversion.

In addition to those files, the PageDown project offers a few editing demo resources:

  1. demo.css - This is a stylesheet used for formatting the demo editor objects.
  2. wmd-buttons.png#img-thumbnail - This is used to show the editor menu bar.

Because, unlike in the TinyMCE example, there's not a CDN that hosts the PageDown resources, you'll need to upload the JavaScript, CSS and image files as web resources. For my example, I've renamed demo.css to Markdown.Editor.css, and I've renamed wmd-buttons.png#img-thumbnail to wmd.buttons.png#img-thumbnail (CRM disallows naming a resource with a "-" character).

I have customized the files and saved them here for you to download - markdown-files.zip. You will need to make one customization to the Markdown.Editor.css file. After you upload the wmd.buttons.png#img-thumbnail file, go to line 78 in the Markdown.Editor.css file and replace "new_wmd.buttons.png#img-thumbnail" with whatever name you gave your wmd.buttons.png#img-thumbnail resource.

Generating the e-mail editor window

Once you have uploaded and published the JavaScript, CSS and image web resources, you need to also upload the editor launching web resource. This is almost identical to the launcher from the TinyMCE example, except the popup window it generates is PageDown-ized. You can use the version I included in the markdown-files.zip archive, but you will need to update the paths to the web resources on lines 10-12.

Here is the script that generates the editor window:

function openEditWindow() {  
 //get the content of the e-mail description field  
 var emailBody = parent.Xrm.Page.getAttribute("description").getValue();  
 //build the content of the editor popup window  
 var editContent = '<html>\n<head>';  
 editContent += '<title>Lucas Alexander\'s Better CRM E-mail Markdown Editor</title>\n';  
 editContent += '<link rel="stylesheet" type="text/css" href="/WebResources/new_Markdown.Editor.css" />\n';  
 editContent += '<scr'+'ipt type="text/javascript" src="/WebResources/new_Markdown.Converter.js"></scr'+'ipt>\n';  
 editContent += '<scr'+'ipt type="text/javascript" src="/WebResources/new_Markdown.Editor.js"></scr'+'ipt>\n';  
 editContent += '<scr'+'ipt>\n';  
 //this function is used to update the crm e-mail body field and close the editor popup  
 editContent += 'function updateEmailForm() {\n';  
 editContent += 'window.opener.parent.Xrm.Page.getAttribute("description").setValue(document.getElementById("wmd-preview").innerHTML);\n';  
 editContent += 'window.opener.parent.Xrm.Page.data.entity.attributes.get("description").controls.get(0).setFocus();\n';  
 editContent += 'this.window.close();\n';  
 editContent += '}';  
 editContent += '</scr'+'ipt>';  
 editContent += '</head>\n';  
 editContent += '<body>\n';  
 editContent += '<div class="wmd-panel">\n';  
 editContent += '<div id="wmd-button-bar"></div>\n';  
 editContent += '<textarea class="wmd-input" id="wmd-input">'+emailBody+'</textarea>\n';  
 editContent += '</div>\n';  
 editContent += '<div id="wmd-preview" class="wmd-panel wmd-preview"></div>\n';  
 editContent += '<br /><button onclick="updateEmailForm();">Update e-mail form and close</button>';  
 editContent += '<scri'+'pt type="text/javascript">\n';  
 editContent += '(function () {\n';  
 editContent += 'var converter = new Markdown.Converter();\n';  
 editContent += 'var editor = new Markdown.Editor(converter);\n';  
 editContent += 'editor.run();\n';  
 editContent += '})();\n';  
 editContent += '</scri'+'pt>\n';  
 editContent += '</body>\n';  
 editContent += '</html>\n';  

 //open the editor popup window  
 var editWindow = window.open("","editorwindow","height=700,width=1000,scrollbars=yes,resizable=yes");  

 //write the editContent string to the editor popup  
 editWindow.document.write(editContent);  

 //close the document stream  
 editWindow.document.close();  
}  

Once you publish the editor launching page and embed it on your e-mail form, you're all set. Happy e-mailing!

comments powered by Disqus