关注本人微信和易信公众号: 微软动态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>
 
然后我放入我的测试用的自定义实体,不用修改代码就可以显示,搞定。
 

最新文章

  1. 1877: [SDOI2009]晨跑
  2. Yii rbac原理和实践
  3. C# 完整List例子
  4. HDU 2509 Be the Winner nim博弈变形
  5. HDU 1710 Binary Tree Traversals(二叉树遍历)
  6. Codeforces 727 D T-shirts Distribution
  7. 关于Oracle的性能调整(一)
  8. Odoo10尝鲜: 退货
  9. CPU供电维修
  10. C++之运算符重载(1)
  11. 在Mac下如何开Wifi
  12. UPdate 延时盲注之小技巧
  13. Android 7.0 调取系统相机崩溃解决android.os.FileUriExposedException
  14. 浅析java的深拷贝与浅拷贝
  15. loss函数和cost函数
  16. Tarjan求割点(割顶) 割边(桥)
  17. 【emWin】例程二十五:窗口对象——Iconview
  18. img2html实现将图片转换成网页
  19. delphi编写与调用DLL(delphi7下测试通过)
  20. CIDR的IP地址的表示与划分方法

热门文章

  1. idea搜索不到任何插件
  2. Spring Boot 2 快速教程:WebFlux 集成 Thymeleaf(五)
  3. SSM整合1(springMVC+mybatis)
  4. This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app&#39;s Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value
  5. eclipse git 主干代码合并到分支
  6. RAID&amp;LVM有关磁盘的故障
  7. java8-12-Optional类
  8. 对比keep-alive路由缓存设置的2种方式
  9. npm --save-dev 和 --save 的区别
  10. Django 缓存 cache基本使用