Search code examples
ckeditorcustomizationwysiwygdynamics-crm-2013

Rich Text Editor (WYSIWYG) in CRM 2013


Sometimes it is useful to have the HTML editor in CRM interface. It is possible to implement the editor directly to CRM 2013. As editor we will use ckeditor which allows to use it without installation on the server.


Solution

    1. Identify the field where you would like to use the rich text editor.

    2. Create html-webresource which will define ckeditor. Go to Settings-Customizations-Customize the System-Web Resources.

    Rich Text Editor Web Resource

    1. In html editor of web resource, select the Source tab and insert the following code:
    <html>
    <head>
        <title></title>
        <script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    
        <script type="text/javascript">
    
            function getTextFieldName()
            {
                var vals = new Array();
                if (location.search != "") 
                {
                    vals = location.search.substr(1).split("&");
                    for (var i in vals) 
                    {
                        vals[i] = vals[i].replace(/\+/g, " ").split("=");
                    }
    
                    //look for the parameter named 'data'
                    for (var i in vals) 
                    {
                        if (vals[i][0].toLowerCase() == "data") 
                        {
                            var datavalue = vals[i][2];
                            var vals2 = new Array();
                            var textFieldName = "";
                            vals2 = decodeURIComponent(datavalue).split("&");
                            for (var i in vals2) 
                            {                
                                var queryParam = vals2[i].replace(/\+/g, " ").split("=");
                                if (queryParam[0] != null && queryParam[0].toLowerCase() == "datafieldname")
                                {
                                    textFieldName = queryParam[1];
                                }
                            }
    
                            if (textFieldName == "")
                            {
                                alert('No "dataFieldName" parameter has been passed to Rich Text Box Editor.');
                                return null;
                            }
                            else
                            {
                                return textFieldName;     
                            }
                        }
                        else
                        {
                            alert('No data parameter has been passed to Rich Text Box Editor.');
                        }
                    }
    
                }
                else 
                {
                    alert('No data parameter has been passed to Rich Text Box Editor.');
                }
                return null;
            }
    
            CKEDITOR.timestamp = null;
    
    
          ​// Maximize the editor window, i.e. it will be stretched to target field
            CKEDITOR.on('instanceReady',
             function( evt )
             {
                 var editor = evt.editor;
                 editor.execCommand('maximize');
             });
    
            var Xrm;
    
            $(document).ready(function () 
            {
    
    ​           // Get the target field name from query string
                var fieldName = getTextFieldName();
                var Xrm = parent.Xrm;
    
                var data = Xrm.Page.getAttribute(fieldName).getValue();
                document.getElementById('editor1').value = data;
    
                /*
                // Uncomment only if you would like to update original field on lost focus instead of property change in editor
    
                         //Update textbox on lost focus
                         CKEDITOR.instances.editor1.on('blur', function () 
                {
                 var value = CKEDITOR.instances.editor1.getData();            
                 Xrm.Page.getAttribute(fieldName).setValue(value);
                         });
                */
                // Update textbox on change in editor
                CKEDITOR.instances.editor1.on('change', function () 
                {
                    var value = CKEDITOR.instances.editor1.getData();            
                    Xrm.Page.getAttribute(fieldName).setValue(value);
                });
    
                // Following settings define that the editor allows whole HTML content without removing tags like head, style etc.
                CKEDITOR.config.allowedContent = true;
                CKEDITOR.config.fullPage = true;
            });
    
    
        </script>
        <meta>
    </head>
    <body style="word-wrap: break-word;">
        <textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10"></textarea>
    
    </body>
    </html>
    

    Note: As you can see, there are a few important sections

    a) The following code loads the ckeditor and jquery from web so that they don't have to be installed on server.

    <script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    

    b) Function getTextFieldName() which gets the name of target field where should be rich text editor placed. This information is obtained from query string. This will allow to use this web resource on multiple forms.

    c) Initialization of ckeditor itself - setting the target field and properties of ckeditor. Also binding the editor with predefined textarea on the page.

    1. Open the form designer on the form where you would like to use ​WYSIWYG editor. Create a text field with sufficient length (e.g. 100 000 chars) which will hold the html source code.

    2. Insert the iframe on the form. As a webresource use the resource created in previous steps. Also define Custom Parameter(data) where you should define the name of the text field defined in step 4. In our situation we created new_bodyhtml text field so the parameter holds this value. This value is returned by the getTextFieldName() of the web resource.

    Iframe

    1. Do not forget to save and publish all changes in CRM customization otherwise added webresources and updated form are not available.

    2. That's all, here is example how it looks like: Example