通过SharePoint 2013 EditForm提交隐藏字段的值

最近在一个项目中对某个SharePoint List的NewForm、EditForm和DisplayForm做了大量UI层面的定制,目的在于实现复杂的联动以及提升用户体验,并不会影响前两个表单的数据保存功能,这一功能依然由SharePoint原生提供。

该List包含大量Field,并且其中有一个Field会保存非常冗长的JSON字符串,姑且叫其JSONData。当JSONData的值增长到某种程度时,这几个Form加载起来就会变得异常漫长,有时候甚至会让浏览器失去响应。

JSONData中保存的值并不会直接呈现给用户,而是由JavaScript来消费的,但SharePoint会将Form中出现的所有Field的值输出到页面中的一个JavaScript变量中,正因如此,页面体积变得异常庞大,问题就产生了。 那么倘若把JSONData从这几个Form中隐藏了呢?这样它就不会输出到页面中,当页面载完成之后,再通过JavaScript调用SharePoint 2013的RESTful API单独获取JSONData的值,然后进行消费,这样应该能够解决页面加载的问题。

隐藏JSONData并不复杂,配置ContentType或者在页面上执行下面的JavaScript代码均可:

var ctx = new SP.ClientContext(_spPageContextInfo.webAbsoluteUrl);
var field = ctx.get_web().get_lists().getByTitle('List Name').get_fields().getByInternalNameOrTitle('JSONData');
field.setShowInEditForm(false);
field.setShowInNewForm(false);
field.setShowInDisplayForm(false);
ctx.load(field);
ctx.executeQueryAsync(function(){
console.log('done');
});

然而问题又来了,前面提到数据保存功能依然是由SharePoint原生提供的,那么将JSONData隐藏后,如何继续让SharePoint为其保存数据呢?当然通过RESTful API是可以做到的,但我们并不希望对保存过程做太大的改动,所以想别的办法。

SharePoint 2013新增了一组JavaScript ClientForm API,允许使用JavaScript接管Field在Form中的表现(包括编辑器渲染、取值等等),那么我们只需要想办法接管JSONData的取值过程即可,因为JSONData并不在Form中,所以我们需要借助其他Field来“帮把手”。

首先在List中增加一个Field,名为JSONDataShadow,类型随意,这里选择Yes/No作为示例。

接下来以Edit Form为例,在List的Ribbon中点击List选项卡中的Form Web Parts,选择Default Edit Form:

然后编辑Form Web Part的属性,在Miscellaneous分类下找到JS Link,填入一个JavaScript文件的相对路径:

接下来就编辑这个JavaScript文件,加入下面的代码:

(function () {
"use strict";

function edit(ctx) {
var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);

formCtx.registerGetValueCallback(formCtx.fieldName, function() {
return false;
});

formCtx.registerGetValueCallback('JSONData', function() {
var value = new Date();
return value;
});
}

var ctx = {
Templates : {
Fields : {
'JSONDataShadow' : {
'EditForm' : edit
}
}
}
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctx);
}());

这段代码会在Form渲染之前执行,它会告诉SharePoint Form模板管理器,有一个名为JSONDataShadow的Field需要接管其在EditForm中的表现,具体接管内容请调用edit函数。

在edit函数内,为当前Field(即JSONDataShadow)注册GetValue回调函数,当用户点击了Form上的Save按钮时,SharePoint就会调用已注册的GetValue回调,获取其对应字段的值。这里需要再额外为JSONData注册一个GetValue回调(示例代码返回了当前日期),这样一来,JSONData的值也可以交由SharePoint来保存了。

以上步骤完成之后,页面中不会再输出冗长的JSONData值,而是会输出一个简单的JSONDataShadow值,这一值本身没什么意义,只是为了借助它来为JSONData注册GetValue回调,所以在UI定制中,尽管将其隐藏即可(但不可以将其从Form中隐藏,因为无法接管隐藏Field的模板)。

发表评论

电子邮件地址不会被公开。 必填项已用*标注