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