按条件决定SharePoint 2010日历颜色
SharePoint 2010中对列表的日历视图有了极大的改进,之前曾经简单写过一篇blog进行了一些简单介绍。新的日历视图的渲染方式与之前完全不同,采用了AJAX后台加载、JavaScript渲染的机制,极大的提高了日历的显示效率(在SharePoint 2007的时候日历渲染是非常非常慢的)。不过也正是因为所有的日历都是使用AJAX加载、然后用JavaScript进行显示的,这也导致了对日历样式的控制变得更加复杂。
最近某个客户有这样一个需求:希望能够在日历视图中,根据不同情况将条目显示为不同的颜色,经过一番研究之后,找到了如下解决方案(不需要编写后台代码,仅通过十几行js代码就可以)。
第一个问题,如果分辨应该使用什么颜色?这个颜色条件可以采用日历列表中“地点”字段来进行判断,比如写成“因私外出”显示成红色、写成“因公外出”显示成蓝色、写成“办公室”显示成绿色,客户同意通过制度来限制此字段的填写(在实际场景中,日历是通过个人的Outlook填写,并同步到SharePoint上的)。
第二个问题,如何将“地点”这个字段显示出来,并且作为能够判断颜色的依据?这方面,可以借助日历视图设置中的“副标题”进行控制。在周视图和日视图中,都可以设置一个字段为“副标题”,显示在标题的下方,在页面中就可以通过js代码来得到这个副标题。那你可能会有一个疑问:在月视图中怎么办?实际上,如果设置了副标题的话,不论是月视图、周视图还是日视图,在显示日历条目的那个div元素上,都会包含一个title属性,格式为:“开始时间 - 结束时间 标题(副标题)”。因此,我们只需要把“地点”字段设置成周视图和日视图的副标题即可(月视图采用周视图的副标题字段作为title属性)。
最后一个问题,如何动态来控制颜色。刚刚曾经提到过,在2010的日历视图中,日历条目都是通过AJAX进行加载的,我研究了一下SharePoint日历渲染的那个js文件(好几百KB),发现没有开放出加载完成的事件接口(这个文件估计是用C#代码转换出来的,比较难读)。因此,我们就只能通过最土的方法:不断轮询页面日历中的条目div,找到之后,再根据div的title属性来判断应该显示为哪种颜色,日历条目的div有一个专门的class:ms-acal-item,通过jquery,我们可以很容易使用class名称来找到这些条目。
综上,实现的方式为:在有日历的页面中添加一个内容编辑器,里面写上如下的js代码:
1: <script src="/_layouts/jslib/jquery.js" type="text/javascript"></script>
2: <script type="text/javascript">
3: var _calColorMap = {"ok":"#ff0000"};
4: function _calColor(){
5: $('div.ms-acal-item').each(function(){
6: var title = $(this).attr('title');
7: if(typeof(title) != 'undefined' && title != null){
8: if(title.lastIndexOf(')') == (title.length - 1)){
9: title = title.substring(title.lastIndexOf('(') + 1, title.length -1);
10: if(typeof(_calColorMap[title]) != 'undefined'){
11: $(this).css('background-color', _calColorMap[title]);
12: }
13: }
14: }
15: });
16: setTimeout('_calColor()');
17: }
18: ExecuteOrDelayUntilScriptLoaded(_calColor, "SP.UI.ApplicationPages.Calendar.js");
19: </script>
稍微对这段代码进行一些解释:
第1行,引用jquery的脚本文件。我这个demo里面只是一个演示,更好的做法是把js的引用通过feature的方式加入到母版页的head标签里面;当然,引用的位置也可以放到文档库里,或者如果企业策略允许服务器访问外网的话,可以直接从jquery网站里面去进行引用。
第3行,这里面设置了一个字典变量,来进行“地点”-“颜色”的映射,这个demo里将“ok”地点显示成红色(#ff0000),当然,这个映射关系完全也可以通过后台的一些配置列表来实现,以js的形式输出到页面中就可以。
中间的部分就是判断div的title属性,找到对应的“地点”,并设置div的颜色。
第16行,将这个方法每隔50毫秒就执行一次。因为2010的日历视图在切换显示时间、显示方式的时候是没有后台代码提交的,页面不会刷新,全都是js操作,所以有必要随时进行页面元素的遍历(不用担心浏览器执行效率,我测试过,50毫秒的间隔对浏览器的CPU占用没有丝毫影响)。
第18行,这个是SharePoint 2010中的方法,意思是在页面加载完“SP.UI.ApplicationPages.Calendar.js”这个js文件之后,再执行_calColor这个方法(SharePoint 2010中很多js文件都是动态加载的)。
下图是这段代码在一个日历视图上的执行效果(月视图,test那个是全天事件,所以没有显示时间):
这个是使用“地点”字段进行颜色的判断,各位看官稍加发挥一下就可以根据自己的需要进行颜色的设置了。
在SharePoint 2007中使用后台代码进行自定义日历显示的时候(使用SPCalendarView控件),是可以设置每个日历项的颜色的,不过这段代码到了2010中似乎会有一些问题,一些老外已经有了blog去描述这个问题(大致解决方法就是将日历视图的显示回复成v3的模式,这个控件有一个属性可以控制是v3模式显示还是v4模式),篇幅所限就不在此赘述了,有需要的看官可以直接去google一下。