SharePoint:扩展DVWP - 第22部分:jQuery实现基于其他字段自动创建标题
当我们填充关系列表数据时,要保证网站栏没有设成必填项,这样才能在数据表视图中一次填充一栏数据。当时我们也讨论了在这种情况下通过工作流来自动填写标题会遇到的问题。我们甚至无法通过一个计算栏来解决该问题,因为查阅项类型的栏在计算栏设置页面上是不可见的。
但是,当我们需要维护这个列表时会是怎么一个情况?
如果你是用一个完整的数据清单一次性的对某个下拉框列表进行更新,那么你要做的事和前面讨论的一样。但如果你是一条数据一条数据的添加的话,自动创建标题内容就会对你很有帮助了,可以避免机械性的劳动。
PreSaveAction()前来支援
当然,还是要用到jQuery...
假设我们的关系列表的NewForm.aspx(也就是添加一条关系的页面)如下图所示:
这里两个网站栏设置为必填项,而标题栏设置为可选项
我们要在做两件事情都是在jQuery中进行,因此无需unghost该页面:
1、隐藏标题行 - 我们将通过jQuery而不是列表设置来实现。因为我们并不是要它始终被隐藏;只是需要在这块里隐藏即可。因为接下来我们要...
2、在用户点确定时,把两个网站栏的选择项连起来,然后将其作为标题进行保存。
这里是具体实现功能的jQuery代码,稍后我会进行解释:
<script src="/Asset/js/jquery.js" type="text/javascript"></script> <script language="javascript" type="text/javascript"> $(document).ready(function() { $("input[title=标题]").parent().parent().parent().hide(); }); function PreSaveAction() { var txtCountries=$("select[title=Countries] option[selected]").text(); //alert(txtCountries); var txtStates = $("input[title=States]").val(); $("input[title=标题]").val(txtCountries+ ' - ' + txtStates ); return true; }; </script>
隐藏标题行
在$(document).ready(function() {})里运行的代码块会在页面加载完成后运行。下面的HTML来源于在该页面上“查看源代码”,显示了当页面加载完成后的样子:
<TR> <TD nowrap="true" valign="top" width="190px" class="ms-formlabel"><H3 class="ms-standardheader"> <nobr>标题</nobr> </H3></TD> <TD valign="top" class="ms-formbody" width="400px"> <!-- FieldName="标题" FieldInternalName="Title" FieldType="SPFieldText" --> <span dir="none"> <input name="ctl00$m$g_7ce6f1ae_8fa4_4f07_90cc_035d0c63a180$ctl00$ctl04$ctl00$ctl00$ctl00$ctl04$ctl00$ctl00$TextField" type="text" maxlength="255" id="ctl00_m_g_7ce6f1ae_8fa4_4f07_90cc_035d0c63a180_ctl00_ctl04_ctl00_ctl00_ctl00_ctl04_ctl00_ctl00_TextField" title="标题" class="ms-long" /><br> </span> </TD> </TR>
这是我们需要隐藏的整个一行内容。最方便的定位到它的方法是通过所数据的数据查找表单字段(或文本框)。就是其中<input ... title="标题" .../>标记部分。注意其中的title属性设置为与其左侧TD中的H3的标签内容相同。
在jQuery里,我们用类似$("搜索条件")的语法进行搜索。因此,这里就是.$("input[title=标题]"),换句话说就是“查找title属性为"标题"的input标记”,这样找到的正是我们所要的。
接下来,我们向上或着说是向外层查找HTML标记:
1、我们找到的input标记位于一个span标记内,所以...
2、.parent()会得到span标记,它位于一个TD标记内,所以...
3、.parent()会得到TD标记,它位于一个TR标记内,所以...
4、.parent()会得到TR标记,正是我们要隐藏的,所以...
5、.hide()将其隐藏。
也可以直接使用closest()函数。可以使代码更简洁。(closest会首先检查当前元素是否匹配,如果匹配则直接返回元素本身。如果不匹配则向上查找父元素,一层一层往上,直到找到匹配选择器的元素。如果什么都没找到则返回一个空的jQuery对象。)这是牛人Marc D Anderson在评论中提出的宝贵建议。
直接这么写:
$("input[title=标题]").closest("TR").hide();
标题行就被隐藏了;我们会通过编程的方式为其设置值,然后再执行保存。
连接字段创建标题
在以前的一篇博文中,我们讨论了PreSaveAction()在DVWP中的使用。那时,我们可以实现当点击一个表单操作链接时,在表单操作被执行前进行一些额外的调用。
对于一个默认的(ListFormWebPart)ghosted页面,PreSaveAction()会在点击确定按钮时自动被调用。也就是说,我们要做的只是往函数里放代码就可以了,SharePoint会在提交修改到数据库之前执行它。
与标题控件类似,我们也可以通过input标记(或者,选择项比较少时是select标记)及其title属性(值为该栏的显示名称)查找另外的两个下拉框。
因此,对于第一个查阅项控件:
1、$("select[title=Countries] option[selected]")就可以找到该控件的被选中项,然后...
2、.text()可以获取选中项对应的文本内容,我们将其...
3、存在我们创建的一个变量:txtCountries 中
对于第二个查阅项控件:
1、$("input[title=States]")就可以找到该控件,然后...
2、.val()可以获取value属性的内容,我们将其...
3、存在我们创建的一个变量:txtStates 中
现在,我们需要再次找到Title控件:
1、$("input[title=Title]"),但是...
2、接下来不是要获取其值,而是通过.val()来设置value属性为...
3、txtCountries+"-"+txtStates
由于这两个栏都是必填项,只有两者都有值时页面才可以保存。当然在保存前会首先设置标题的值。
Countries被设置为USA,States被设置为New York。jQuery会连接这两个值生成标题(已隐藏),然后再保存。
可以看到,通过jQuery成功设置了标题的内容!
如果愿意,你也可以在EditForm.aspx中做同样的事情,但这样可能是矫枉过正,依赖于进行修改的频率以及标题的重要程度而定。
下一次:我们将通过一个工作流来完成相同的工作。
参考资料
SharePoint: Extending the DVWP – Part 22: Creating Title Based on Other Fields with jQuery