在Dynamics CRM中自定义一个通用的查看编辑注释页面

关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复162或者20151016可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me!
注释在CRM中的显示是比较特别,我们可以自定义一个页面来显示注释吗?如果可以,可以做成通用的吗?这篇博文将会带你制作一个通用的注释显示页面,并为每条注释生成了超级链接,点击可以在弹出页面中查看或者编辑注释。
首先要新建一个类型为 HTML Page 类型的Web资源,操作步骤如下。我这里使用了Developer Toolkit进行无缝开发,怎么配置请参考我这篇文章:为Dynamics CRM 2015配置Visual Studio准备无缝开发
 
 
 然后我更改下这个新增文件的Display Name,让其跟File Name属性一样,还更改Unique Name如下,加入反斜线为了构造目录,有利于引用文件。当然这两个属性不改动也可以的。
 
值得吐槽的是OData的表达式的filter条件不支持跨实体,比如我想用的是注释实体的IsDocument 属性为true,然后还要用来和它关联的客户的Id字段,却告诉我不能这么用。比如我想使用这个URL:http://lyazurevm.cloudapp.net:5555/Demo/xrmservices/2011/OrganizationData.svc/AnnotationSet?$select=DocumentBody,FileName,MimeType&$expand=Account_Annotation&$filter=Account_Annotation/AccountId eq guid'858AB47F-494A-E511-80D2-000D3A802FAC' and IsDocument eq true
却告诉我:filter conditions of different entity types, in the same expression, are not supported ,囧。如果有谁找到OData查询条件能跨实体的方法请联系
 
我这里列举一个以某某开头这种OData语法,也是为了让大家知道更多 http://lyazurevm.cloudapp.net:5555/Demo/xrmservices/2011/OrganizationData.svc/AnnotationSet?$select=DocumentBody,FileName,MimeType&$expand=Account_Annotation&$filter=startswith(Account_Annotation/Name,'A. Datum') 
查询出来两条是正确的:
 
当然我们实际上要使用的语法是类似这样的:http://lyazurevm.cloudapp.net:5555/Demo/xrmservices/2011/OrganizationData.svc/AnnotationSet?$select=DocumentBody,FileName,MimeType&$expand=Account_Annotation&$filter=Account_Annotation/AccountId eq guid'858AB47F-494A-E511-80D2-000D3A802FAC'
 
这个Web资源我使用的全部代码如下,各位看官做实验的时候要确保在HTML Web资源中引入的JavaScript文件在CRM中已经存在,请注意引用时候使用的路径要对。当然 ClientGlobalContext.js.aspx 这个文件是CRM自带的,注意引用路径就好了。XrmServiceToolkit 这个文件请自行到 这里 下载。
<!DOCTYPE HTML>
<html>
 <head>
  <title>微软MVP罗勇测试注释</title>
        <style type="text/css">
            table {
                border:1px solid #666666;
                border-collapse:collapse;
            }
            table thead th {
                 padding: 8px;
                    border:1px solid #666666;
                 background-color: #dedede;
            }
            table tbody td {
                border: 1px solid  #666666;
             padding: 8px;
             background-color: #ffffff;
            }
            table thead tr th {
                font-family:Microsoft YaHei,SimSun,Tahoma,Arial;
                font-size:12px;
                font-weight:bold;
                color:#000000;
            }
            table tbody tr td {
                color:#444444;
                font-family:Microsoft YaHei,SimSun,Tahoma,Arial;
                font-size:12px;
            }
        </style>
        <script type="text/javascript" src="../../ClientGlobalContext.js.aspx"></script>
        <script type="text/javascript" src="../common/jquery.min.js"></script>
        <script type="text/javascript" src="../common/XrmServiceToolkit.min.js"></script>
        <script type="text/javascript">
            Date.prototype.format = function (fmt) {
                var o = {
                    "M+": this.getMonth() + 1,//月份   
                    "d+": this.getDate(),//
                    "h+": this.getHours(),//小时   
                    "m+": this.getMinutes(),//
                    "s+": this.getSeconds()//
                };
                if (/(y+)/.test(fmt))
                    fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
                for (var k in o)
                    if (new RegExp("(" + k + ")").test(fmt))
                        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ?
                                 (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
                return fmt;
            }

            $(function () {
                var clientUrl = GetGlobalContext().getClientUrl();
                //var id = window.parent.Xrm.Page.data.entity.getId(); //这种方法可以获取表单中的很多信息,包括id
                var match = RegExp('[?&]id=([^&]*)').exec(window.location.search);//这里是外接通过url传递id的值过来
                var id = match && decodeURIComponent(match[1].replace(/+/g, ' '));
                XrmServiceToolkit.Rest.RetrieveMultiple(
                "AnnotationSet",
                "?$select=AnnotationId,Subject,NoteText,MimeType,FileName,FileSize,IsDocument,CreatedOn,CreatedBy,ModifiedOn,ModifiedBy&$filter=Account_Annotation/AccountId eq guid'" + id + "'&$orderby=CreatedOn asc",
                function (results) {
                    for (var i = 0; i < results.length; i++) {
                        var tr = $("<tr></tr>");
                        tr.appendTo($("#notestable tbody"));
                        var td = $("<td>" + (i+1) + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].Subject == null ? "" : results[i].Subject) + "</td>");
                        td.appendTo(tr);
                        td = $("<td><a href='" + clientUrl + "/main.aspx?etn=annotation&pagetype=entityrecord&id=%7B" + results[i].AnnotationId + "%7D' target='_blank'>" + results[i].NoteText + "</a></td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].CreatedBy.Name + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].CreatedOn.format('yyyy-MM-ddThh:mm:ssZ') + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].ModifiedBy.Name + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].ModifiedOn.format('yyyy-MM-ddThh:mm:ssZ') + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].IsDocument ? "" : "") + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].FileName == null ? "" : results[i].FileName) + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].FileSize == null ? "" : Math.round((results[i].FileSize)/1024)) + "</td>");
                        td.appendTo(tr);
                    }
                },
                function (error) {
                    alert(error.message);
                },
                function () {
                },
                true
                );
            });
        </script>
 </head>
 <body>
        <table id="notestable">
            <thead>
               <tr>
                   <th>序号</th>
                   <th>注释标题</th>
                   <th>注释内容</th>
                   <th>创建人</th>
                   <th>创建时间</th>
                   <th>修改人</th>
                   <th>修改时间</th>
                   <th>是否包含附件</th>
                   <th>附件名称</th>
                   <th>附件大小(KB)</th>
               </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
 </body>
</html>
 
在Visual Studio中部署下,也就是右击名称为 CrmPackage 的项目,选择 部署。
 
我进入解决方案修改客户实体的窗体内容为主要的那个窗体,增加一个一列的的选项卡,并在这个选项卡中插入前面创建的Web资源,主要设置如下,还在 格式化 Tab设置了 不现实边框。
 
可以看到我勾选了 将记录对象类型代码和唯一标识符作为参数传递,这个打勾以后将会通过URL的查询参数向Web资源传递什么参数?弹出来看看如下,可以知道传递了CRM组织的基础语言参数orglcid,组织的名称orgname,用户使用CRM时候选择的语言userlcid,当前实体的整数标识type (按照SDK的说法,除了标准实体,自定义的实体这个数字在不同的CRM中可能不同),当前实体的逻辑名称typename,当前记录的唯一id这些参数,当然还有可能会有data,如果在前面设置了 自定义参数(数据) 的话。具体请参考SDK的 Webpage (HTML) web resources 章节。
 
 
然后发布解决方案,按F5刷新浏览器,如果文件被缓存,可以按 F12,在如下地方清除缓存后试试:
 
我们去看效果如下,请原谅我是写代码的,显示的内容不一定美观,呵呵:
 
 可以看到显示的数据正常,而且注释内容页面我做了一个超级链接,是可以点击的,点击效果如下:我也顺手测试了一下,是可以编辑保存的,但是点击 保存并新建按钮是会报错的。
 
上面的代码不够通用,因为写死了是查询哪个实体对应的注释,如果我放入别的实体中,就需要修改,后来我发现了更加通用的方法,如下:
<!DOCTYPE HTML>
<html>
 <head>
  <title>微软MVP罗勇测试注释</title>
        <style type="text/css">
            table {
                border:1px solid #666666;
                border-collapse:collapse;
            }
            table thead th {
                 padding: 8px;
                    border:1px solid #666666;
                 background-color: #dedede;
            }
            table tbody td {
                border: 1px solid  #666666;
             padding: 8px;
             background-color: #ffffff;
            }
            table thead tr th {
                font-family:Microsoft YaHei,SimSun,Tahoma,Arial;
                font-size:12px;
                font-weight:bold;
                color:#000000;
            }
            table tbody tr td {
                color:#444444;
                font-family:Microsoft YaHei,SimSun,Tahoma,Arial;
                font-size:12px;
            }
        </style>
        <script type="text/javascript" src="../../ClientGlobalContext.js.aspx"></script>
        <script type="text/javascript" src="../common/jquery.min.js"></script>
        <script type="text/javascript" src="../common/XrmServiceToolkit.min.js"></script>
        <script type="text/javascript">
            Date.prototype.format = function (fmt) {
                var o = {
                    "M+": this.getMonth() + 1,//月份   
                    "d+": this.getDate(),//
                    "h+": this.getHours(),//小时   
                    "m+": this.getMinutes(),//
                    "s+": this.getSeconds()//
                };
                if (/(y+)/.test(fmt))
                    fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
                for (var k in o)
                    if (new RegExp("(" + k + ")").test(fmt))
                        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ?
                                 (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
                return fmt;
            }

            $(function () {
                var clientUrl = GetGlobalContext().getClientUrl();
                //var id = window.parent.Xrm.Page.data.entity.getId(); //这种方法可以获取表单中的很多信息,包括id
                var match = RegExp('[?&]id=([^&]*)').exec(window.location.search);//这里是外接通过url传递id的值过来
                var id = match && decodeURIComponent(match[1].replace(/+/g, ' '));
                match = RegExp('[?&]typename=([^&]*)').exec(window.location.search);
                var typename = match && decodeURIComponent(match[1].replace(/+/g, ' '));
                XrmServiceToolkit.Rest.RetrieveMultiple(
                "AnnotationSet",
                "?$select=AnnotationId,Subject,NoteText,MimeType,FileName,FileSize,IsDocument,CreatedOn,CreatedBy,ModifiedOn,ModifiedBy&$filter=ObjectTypeCode eq '" + typename + "' and ObjectId/Id eq guid'" + id + "'&$orderby=CreatedOn asc",
                function (results) {
                    for (var i = 0; i < results.length; i++) {
                        var tr = $("<tr></tr>");
                        tr.appendTo($("#notestable tbody"));
                        var td = $("<td>" + (i+1) + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].Subject == null ? "" : results[i].Subject) + "</td>");
                        td.appendTo(tr);
                        td = $("<td><a href='" + clientUrl + "/main.aspx?etn=annotation&pagetype=entityrecord&id=%7B" + results[i].AnnotationId + "%7D' target='_blank'>" + results[i].NoteText + "</a></td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].CreatedBy.Name + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].CreatedOn.format('yyyy-MM-ddThh:mm:ssZ') + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].ModifiedBy.Name + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + results[i].ModifiedOn.format('yyyy-MM-ddThh:mm:ssZ') + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].IsDocument ? "" : "") + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].FileName == null ? "" : results[i].FileName) + "</td>");
                        td.appendTo(tr);
                        td = $("<td>" + (results[i].FileSize == null ? "" : Math.round((results[i].FileSize)/1024)) + "</td>");
                        td.appendTo(tr);
                    }
                },
                function (error) {
                    alert(error.message);
                },
                function () {
                },
                true
                );
            });
        </script>
 </head>
 <body>
        <table id="notestable">
            <thead>
               <tr>
                   <th>序号</th>
                   <th>注释标题</th>
                   <th>注释内容</th>
                   <th>创建人</th>
                   <th>创建时间</th>
                   <th>修改人</th>
                   <th>修改时间</th>
                   <th>是否包含附件</th>
                   <th>附件名称</th>
                   <th>附件大小(KB)</th>
               </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
 </body>
</html>
 
然后我放入我的测试用的自定义实体,不用修改代码就可以显示,搞定。
 
 
原文地址:https://www.cnblogs.com/luoyong0201/p/Dynamics_365_Create_Custom_General_Notes_View_Edit_Page.html