文本编辑器

注意:这是为了从以下位置修复代码中的问题而重新发布的:https : //blogs.msdn.microsoft.com/peterhauge/2015/10/01/how-to-enable-rich-text-in-dynamics-crm -using-ckeditor /,因此与此帖子相关的所有评论均位于上面的URL)。

我最近发现自己处于需要将客户对话中的注释提交到Dynamics CRM中的位置。我喜欢“精美”文本(标题,项目符号,突出显示),以帮助使注释更具可读性,但是Dynamics CRM在其网站上不支持此功能。我没有让笔记变得花哨,而是选择在Dynamics CRM中启用此功能!在本示例中,我们将使用CKEditor,您可以在以下位置找到它:http : //www.ckeditor.com/

在线上已经有一些选项可以执行此操作:

  • 卢卡斯·亚历山大的弹出方法
  • Pavel Cermak在Web资源中捆绑的方法
  • 等等

就我而言,我正在寻找一种更简单的方法,不需要在嵌套的iFrame和我要替换的控件之间进行同步。我正在计划使用CKEditor,它可以很好地替换嵌入式控件,让我们开始吧!

第一步是创建一个Web资源来保存一些JavaScript。我们将使用JavaScript动态地进行所有操作,因此我们不需要任何其他资源,文件,脚本等。您可以通过导航到要更改的表单(需要一些精美文字的表单)来做到这一点。打开表单编辑器。单击工具栏上的“表单属性”按钮,我们可以在其中添加Web资源。在出现的对话框中,单击“添加”

文本编辑器_第1张图片

文本编辑器_第2张图片

在下一个对话框中,我们单击“新建”以添加新的Web资源,在这里我们将JavaScript转换为页面上的控件!

文本编辑器_第3张图片

在下一个对话框(创建新的网络资源)上,我们填写字段(下面的示例),可以上传javascript文件,也可以通过单击“文本编辑器”粘贴到javascript中

文本编辑器_第4张图片
现在来了有趣的部分–无论如何我们应该使用什么JavaScript?好吧,第一步是导入CKEditor库。我们不能直接进行导入,因为它被认为是跨站点脚本编写(因为JS文件位于另一个域中),因此我们需要更加聪明才能完成这项工作。有一种方法可以加载另一个JavaScript文件,即在html的“ ”部分中插入另一个“ script”元素。完成此操作后,浏览器将加载CKEditor JavaScript文件供我们使用。

 

 

var doc = parent.parent.document.getElementById("contentIFrame0").contentWindow.document;

var headblock = doc.getElementsByTagName( 'head' )[0];
var newscriptblock = doc.createElement( 'script' );
newscriptblock.type = 'text/javascript' ;
newscriptblock.src = '//cdn.ckeditor.com/4.5.3/standard/ckeditor.js' ;
headblock.appendChild(newscriptblock);
 

一行一行地,我们首先抓住'head'元素,但是您将在其中看到'parent.parent'位。我们之所以需要这样做,是因为CRM将Web资源放在一个IFrame中,并且该IFrame在另一个IFrame中,作为表单内容的一部分。因此,我们使用“ parent.parent”上移两个级别,然后获取主要内容IFrame,以便我们可以在此处开始添加元素。接下来的几行我们构造了所需的脚本块,最后一行我们将该脚本块附加到了原始的head元素上。

此时,浏览器将开始加载脚本文件!但是,有一个陷阱,我们不能仅仅编写更多的JavaScript来开始替换,因为我们需要首先等待CKEditor.js文件的加载(及其依赖关系)。因此,我们在添加将执行实际替换的脚本块之前注册一个“ onload”事件。像这样:

newscriptblock.onload = function () {
     // We put our code here to get rich text
};

在我的情况下,我要替换几个文本字段,因此,我没有为每个文本字段分别编写代码,而是创建了一个包含所有字段名称的字符串数组,并将循环遍历。加载编辑器后,我们还需要在页面上进行一些调整(隐藏字段的“值”版本并显示字段的“编辑”版本),我们需要在用户输入以下内容时更新基础字段。 Rich Text Editor控件,并将整个内容包装在一个函数调用中(因此我们可以从form load方法中调用它。所有脚本都很好地组合在一起–您可以在下面看到全部详细信息!

更新[2016年2月8日]:感谢安东·库尼兹基(Anton Kurnitzky)的帮助,我更新了以下代码,以便与最新的Dynamics CRM Online配合使用!

更新[4/17/2017]:感谢Brian Poff的帮助,下面的代码再次更新以使用表单和更动态的UI。注意:在此版本中,您还有更多要更新的地方,搜索“描述”,列表中的第一个字段应在所有位置更新。谢谢!

1个
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18岁
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
function convertToRichText() {
 
     var CKIFrame = findCKEditorFieldIFrame( "description" );
 
     // import the ckeditor script, but do it without web resources..  so we create a script tag in the DOM
     var headblock = parent.parent.document.getElementById(CKIFrame).contentWindow.document.getElementsByTagName( 'head' )[0];
     var newscriptblock = parent.parent.document.getElementById(CKIFrame).contentWindow.document.createElement( 'script' );
     newscriptblock.type = 'text/javascript' ;
     // we have to wait until the script is loaded before we can use it, so registering a callback event
     newscriptblock.onload = function () {
 
         var CKIFrame = findCKEditorFieldIFrame( "description" );
 
         // some configuration for the CKEDITOR rich text control
         var CKE = parent.parent.document.getElementById(CKIFrame).contentWindow.CKEDITOR;
         CKE.config.allowedContent = true ;
         CKE.config.toolbarCanCollapse = true ;
         CKE.config.toolbarStartupExpanded = false ;
         CKE.config.width = '95%' ;
 
         var fieldsToReplace = [ "description" , "detailedstatus" ];
         for ( var i = 0; i < fieldsToReplace.length; i++) {
              var fieldname = fieldsToReplace[i];
              // We find the 'edit' control for the engagement overview and replace it with a rich text control
              var richtexteditor = CKE.replace(fieldname + '_i' );
              richtexteditor.on( 'instanceReady' , function () {
                 parent.parent.document.getElementById(CKIFrame).contentWindow.document.querySelector( 'div#' + fieldname + ' > div.ms-crm-Inline-Value' ).style.display = "none" ;
                 parent.parent.document.getElementById(CKIFrame).contentWindow.document.querySelector( 'div#' + fieldname + ' > div.ms-crm-Inline-Edit' ).style.display = "inline-block" ;
                 parent.parent.document.getElementById(CKIFrame).contentWindow.document.querySelector( 'div#' + fieldname + ' > div.ms-crm-Inline-Edit' ).style.width = "95%" ;
 
                 ( function (field) {
                     richtexteditor.on( 'change' , function (evt) {
                         // when the value in the rich text control changes, we update the underlying entity field + the 'view' version of the control
                         Xrm.Page.data.entity.attributes.get(field).setValue(richtexteditor.getData());
                     });
                 })(fieldname);
             });
         }
     };
     newscriptblock.src = '//cdn.ckeditor.com/4.5.3/standard-all/ckeditor.js' ;
     headblock.appendChild(newscriptblock);
}
 
function findCKEditorFieldIFrame(fieldName) {
 
     var frameNum = 0;
     var doc = parent.parent.document;
 
     while (doc.getElementById( "contentIFrame" + frameNum.toString()) != undefined) {
         if (doc.getElementById( "contentIFrame" + frameNum.toString()).contentWindow.document.getElementById(fieldName) != undefined)
             return "contentIFrame" + frameNum.toString();
         frameNum++;
     }
}

现在有了脚本,我们将其复制/粘贴到上面创建的Web资源的“文本编辑器”中,然后单击“保存”并关闭Web资源表单,然后在“查找记录”对话框中单击“添加”。 (假设已选择刚刚创建的Web资源)。接下来,在“事件处理程序”下的“表单属性”对话框中,单击“添加”以将函数调用添加到上面包含的JavaScript中。

文本编辑器_第5张图片

这部分是简单的部分,我们只需要上面函数的指针即可!我们将函数命名为convertToRichText,因此我填写了如下对话框:

文本编辑器_第6张图片
单击确定,保存更新的表单并实时发布–您应该一切顺利!此时,在页面加载时,文本字段将被RTF文本字段替换,更改将自动应用到基础字段,并且一切就绪。我特别喜欢这种方法(将DOM与其他元素一起位于DOM内,而不是IFrame内),因为您可以调整编辑器的大小(抓住右下角并拖动)以增大编辑器的大小,并且所有元素都会正确地落在周围它,神奇地自动!
文本编辑器_第7张图片

 

你可能感兴趣的:(文本编辑器)