“真正”的标题为:我如何创建一个SharePoint 列表来替换一个原先每月在15个经理手里转一圈的Excel电子表格,通过为每一个经理创建一个Web部件页来显示一个有关雇员信息的经过过滤后的可编辑的表格,易于阅读和修改。其中会用到Tab页,网站栏,级联下拉框,DVWP,EasyTabs,表单操作工作流,PreSaveAction(),SPServices/jQuery,XSL以及CSS的知识。
终于,我们进行到扩展DVWP系列的第35部分。在过去的18周内,我们分析了工具本身,技术,进行了各种尝试,修复遇到的错误,实际上是针对同一个解决方案,最终是为了解决如下的一个简单问题:
问题: “我有一个需要每个月都重新创建一次并发给15个经理的Excel 文档。每个经理都负责15个文档中之一,但是我要把所有的电子表格都发给每一个经理,并希望他们更新其中正确的部分。我也要很小心,只能在特定的字段处填写数据,并且要注意不要把之前设定好的公式给盖掉。
有没有办法通过SharePoint改善这一切?”
我们的解决方案满足具备下列需求:
• 避免通过email的方式将文件传来传去
• 可以使每一名经理方便的对他们自己那一部分的数据进行查看和修改
• 为高层管理者提供一个试图可以查看所有区域的所有雇员
• 对当前数据的修改要进行审计,支持历史记录报告。
• 使常规的修改尽可能容易
• 使非常规的修改尽可能变得直观
• 给经理提供多样化的雇员视图,根据雇员类别进行聚合
• 提供小计和总计功能
最终的效果类似下面这样:
完整指南
那个看起来很像Excel电子表格的WebPart是数据视图Web部件(DVWP),通过它我们可以在页面中显示某个区域的所有雇员,并可以直接在页面中进行编辑。因此,我们将从DVWP着手,将其扩展以满足我们的需求。
有关该项目的所有内容都包含在其自己的子网站中,所以主页和快速启动区域都是与雇员(Full-Time Employee,简称FTE)项目相关的。所以新建页面时最容易的方法是直接创建一个和默认主页相同功能的页面(因此也包含快速启动),通过SPD可以直接基于现有的页面进行创建。
右击 default.aspx ,在上下文菜单中点击 New from Existing Page
我们并不需要这上面的这些webpart,但可以很方便的基于此页进行修改:
我们的新创建的web部件页是基于该站点的default.aspx页
假设我们将来会用到共享文档这个库,比如放一些希望共享的文档……没关系,让我们新建一个别的文档库来存放我们新创建的页面,这里将新建一个名为Locations的文档库。
• 在 Web Site 选项卡下,在窗口中右击打开上下文菜单。
在窗口中右,选择 New -> SharePoint Content…
• 选择 Document Libraries 下的Document Library,并为新库起一个名字
选择Document Libraries 下的Document Library,并填写一个名称
• 在你新建的文档所在选项卡下,点Save,将其保存到新建的库。
将新建的页保存到新建的文档库,这里我起名为 LocationsMaster.
现在,有了一个可以开始操作的页面了。在本例中,我们不需要右侧的web部件区域。与其直接删除该区域,不如删除包裹右侧区域和之间空格的外层TD。
很简单,如上图中的步骤1-2-3…噢,还有4
- 在拆分视图中,点击设计视图中的图片WebPart。将会在代码视图中选中整个webpart的HTML/XSL内容,同时还将在标记面包屑导航条上高亮该ImageWebPart。
- 如果我们点击标记条中的 WebPartZone#Right,整个web部件区域的 HTML/XSL 会被选中——包括其中的webpart——也会被选中,但不包括其外层的ID。
- 该标记左侧紧挨着的就是TD,点击该标记会选中整个TD。
- 同时,我们还想删除前面的一个TD,所以按住 Shift 键,并点击上面第244 行中TD标记的左侧(你的行号可能不同)来选中它。
这是再通过 Delete 键将所有这些都删掉。
在设计视图中,我们看到右边这块还是有一大片空白。
删掉右侧的Web部件区域后留下一大片空白。我们将会把它给填上。
为了将左侧区域拉伸到右侧:
- 点击左侧区域红的某个webpart,然后
- 在标记面包屑导航条中点击最近的td,以便
- 在代码视图中定位到该td标记的顶部,这里你会
- 注意到宽度被设置为70%.
- 修改为 100% 后将收回我们的失地。同时…
- 我们发现在这下面还有一个td,所以
- 删除它,这样我们的DVWP就可以填满整个区域了
对于 Announcements 和Calendar, 我们不需要删除WebPart区域,只删webpart。所以,对与每一个webpart:
- 在设计视图中点击该 webpart,
- 鼠标悬停在标记面包屑导航条中高亮显示的标记上,
- 点击下箭头打开上下文菜单,然后
- 选择 Remove Tag
现在我们就可以添加DVWP。
添加DVWP
现在我们有了一个页面,可以作为我们DVWP的外壳。现在就开始创建我们的DVWP。
- 点击WebPart区域中的链接,以便在SPD中将其高亮选中。
根据链接的指示去操作
这样就可以使该WebPart区域进入可以插入WebPart的状态,以便接受DVWP。
在 Data Source Library 选项卡下,点击包含你所要数据的列表旁的下拉框。然后,点击 Show Data.
• SPD 将切换到 Data Source Details 选项卡,在这里我们可以选择要包含的字段。
注意: SPD 将会根据我们在数据源详细信息面板中点选的顺序把选中的字段以从左到右的顺序铺在DVWP中。按住Ctrl键再点击可以选中多个栏,同时决定将来显示的顺序。
• 当我们有了想要的字段,就可以点击 Insert Selected Fields as…
……然后选择 Multiple Item View。
DVWP初始载入的状态
格式化DVWP
现在,页面上已经有了DVWP,接下来就可以开始对其进行自定义了,首先是通过配置界面进行修改,这样就可以最大限度的减少XSL的修改。
对于我的项目有一点很明确的需求就是使用多个DVWP来管理数据,而不是一块一块的每次看10项。
格式化数据视图属性:分页
红框框住的链接将打开数据视图属性(Data View Properties)对话框的分页(Paging)选项卡。
你也可以通过菜单将其打开: Data View -> Paging…
默认情况下,分页设置为10项。我们将选择 Display all items。
在这个窗口中,我顺便修改一些其他的设置。
格式化数据视图属性: 列标题排序
允许用户在页面中进行排序是一个很好的体验,所以我们从 General 选项卡下将该项设置启用。
默认设置是没有工具栏。我们将“对列标题启用排序和筛选” (Enable sorting and filtering on column headers)。
格式化数据视图属性:编辑
我们允许用户可以在DVWP上进行插入,编辑和删除操作,所以让我们在“编辑”(Editing)选项卡下将其开启。
所有的操作链接默认都是关闭的。我们把3个都勾选上。
开始的几个DVWP扩展: 直接编辑,不分页,和列标题排序/筛选。
我花了一小会儿才在SPD中加载出数据,因为我有486 条记录。当然我不希望我的用户必须一次加载这么多的数据,所以让我们添加一些筛选和分组条件。
格式化数据视图属性:筛选
筛选DVWP 可以使我们根据Location把列表数据分成几块。
像分页 (Paging)一样,你也可以通过菜单打开筛选条件对话框: Data View -> Filter…
格式化数据视图属性:排序和分组
我们希望对现有数据进行排序和分组。
默认情况下是按创建时间(Created)升序排列的。我们改成按 Group 进行分组,同时按 Worker进行排序,均为升序。
格式化数据视图属性:编辑列…(Edit Columns…)
现在我们会根据Location 进行筛选并根据 Group进行分组,所以不再需要显示这两列。
通过高亮选中列并点击<< Remove移除 Location 和 Group 列。
格式化数据视图布局:WebPart标题,列标题,和显示格式
在开始扩展我们的解决方案前,还有其他一些小的微调工作。
标题
由于我们打算将相同的一个WebPart用于多个区域,所以需要方便的对WebPart的标题进行修改。
这个WebPart默认的标题是所显示的列表的名称。我们将把它修改成Operations 以便反映出我们设置的筛选项。
列标题
现在我已经有了一个载入数据的部件,HR部门决定把列标题修改成他们自己的术语:他们希望看到"Job Title" 而不是 "Position," "Employee" 而不是 "Worker," "Shift"而不是"Work Shift," "Effective"而不是 "EffDate."
每个列标题都包含在一个名为dvt.headerfield的模版中,传一个显示名称。
在设计视图中点击列标题,以便在代码视图中高亮对应的模版调用。
在该模版(template)中, fieldtitle 和 displayname这两项是修改标题行文本时必须要改的。 (见第 245-6行):
<xsl:call-template name="dvt.headerfield" ddwrt:atomic="1" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
<xsl:with-param name="fieldname">@Positions</xsl:with-param>
<xsl:with-param name="fieldtitle">Job Title</xsl:with-param>
<xsl:with-param name="displayname">Job Title</xsl:with-param>
<xsl:with-param name="sortable">1</xsl:with-param>
<xsl:with-param name="fieldtype">x:string</xsl:with-param>
</xsl:call-template>
修改列标题后
显示格式
Effective Date 的时间部分实际上没有什么意义;可以看到在这里总是显示12:00 AM。让我们通过修改数据格式来将其隐藏。
日期格式默认是显示时间的。我们取消选中 Show Time 复选框以将其改成只显示日期。我们还可以修改日期的显示格式。
扩展DVWP
至此,我们已经完成了格式化的工作,现在可以开始扩展DVWP了。
首先要做的是重新排列栏,把edit 和delete 链接放在页面右侧。我们必须在默认值模版,编辑模版,以及插入模版上都操作一遍。
接下来,我们把所有的表单操作链接放在一行中,并把其中的几个变成按钮的形式。
根据我们的需要对外观进行修改后,我们将打开这些操作链接,研究一下它们的工作原理,添加一个PreSaveAction(),挂接一个工作流,重新排列执行顺序,并修复其中的错误。
然后,我们将传递一些工作流变量给该工作流,通过变量传递一些信息,并添加更多信息,添加更多的变量用于jQuery和PreSaveAction(),以便进行表单验证,或者进行审计记录的写入。
为了使用户输入数据或者修改数据变得更容易,我们创建了一些网站栏,加载上数据,并在网站栏间创建关系列表(并通过两种方式中的一种来填充数据)。接着我们就可以把这些网站栏和关系列表加工成级联下拉框(分别实现了两级和三级联动)。
有时,我们会填充大量的数据,所以设置一些默认值将对我们非常有利。比如,在我们的关系列表中,Title基本上是多余的。它只是为了告诉我们两个存在关系的栏中是什么内容的数据。我们可以让SharePoint 利用jQuery自动填写该数据。或者我们也可以引发一个工作流来做这件事情。
现在我们的数据流转的很好了,我们可以设置一个审计跟踪功能来捕获对该列表进行的任何修改。
由于我们的编辑模板(edit template)和我们的默认值模板(default template)看起来很类似,所以用户可能会感到迷惑,不清楚自己当前处于什么状态。因此,我们需要修改编辑模板,通过一些简单的图形化元素使该状态变得更加明显些。同时,我们还可以创建另一个版本的编辑模板,来捕获当一个列表项删除时的信息。这个remove模板可以被单独格式化,以便满足我们的需求。我们甚至可以独立于编辑模板,单独修改其表单操作工作流。
为了将大量数据展现给不同的用户时变得更直观,我们需要重用前面创建的WebPart,通过Christophe Humbert的Easy Tabs代码以及内容编辑器(Content Editor Web Part ,简称CEWP )添加所需数量的DVWP,来对应不同的区块,每一个只需要修改一下筛选和排序条件即可。
在保存该WebPart前,我们还应该对insert模板进行一些修改以填入默认值。但是要注意,我们是在多个DVWP的情况下,所以需要有一些特殊的考量以保证我们的默认值设置到正确的tab页上。
最后,为了使其看起来更棒,我们格式化了一下总计和小计行的外观,并用图标替换了一些表单操作链接。
重用我们的WebPart
我们花了18周才进行到这儿。如果让你没创建一个tab页,或者一个新的Location后将每一步重做一遍显然是一件很恐怖的事情。幸运的是,我们不必这么做。我们只需要导出之前改好的WebPart并重用它即可。
我们将在浏览器中来操作。
- 点击 网站操作(Site Actions )->编辑页面(Edit Page)。
- 点击WebPart右上角菜单 编辑(edit) -> 导出(Export…)
将它保存到一个容易找到的地方。
然后,当我们要用到它时,我们只要:
- 点击 Add a Web Part 按钮
- 点击 Advanced Web Part gallery and options
- 点击 Browse… 按钮
- 定位到你的WebPart并点击 Open
- 点击 Upload 按钮
- 把该WebPart拖到页面上
- 为页面中的每一个tab重复该步骤
- 在每个tab中,为该tab调整筛选,排序和分组
- 最后,点击 Exit Edit Mode
进球了!
尽管我们已经到了扩展DVWP系列的尾声部分,但实际上还只是触碰了数据视图WebPart整个功能的冰山一角。DVWP更多的功能还有待于大家在将来的工作中继续挖掘。
我很荣幸献上这一系列的内容,同时也很希望能听到您关于DVWP使用方面的奇思妙想。
赠送部分
最近来自社区的朋友问到如何在空白的列表中处理insert表单操作链接遇到的问题。我的解决方案将作为本系列的赠送部分附上。敬请期待!
参考资料
SharePoint:Extending the DVWP - Part 35:Putting it All Together