父子关系在现实场景中很常见。在SharePoint里,表现为两个SharePoint列表通过一个位于子列表中的查阅项字段进行关联。通过这种形式,就可以在列表间建立一个父子关系。
我们往往需要实现在父列表表单中(DispForm.aspx,EditFrom.aspx,NewForm.aspx)展现子项。为此,我创建了一个SharePoint自定义字段类型:“ParentChildrenField”。
实例
本例的目的是实现一个自定义的选项卡对话框的导航,用于替换SharePoint网站默认的顶部导航,为此我创建了两个SharePoint 列表:Tabs和Sub-Tabs。我新建了一个网站栏“Parent Tab”,类型为查阅项,数据来源于Tabs的“标题”。这个栏被添加到“Sub-Tabs”列表中。
创建“My Child Items”字段
为了在Tab的表单(Display,Edit和New)中显示子项(sub-tabs),我新建了一个SharePoint网站栏“My Child Items”,类型为前面定义的“ParentChildrenField”。这个栏被添加到父列表“Tabs”中。通常情况下,添加栏到列表内容类型比直接添加到列表要好。
源代码
public class ParentChildrenFieldControl : TextField
{
int NumOfChildren = 0;
LiteralControl literalCtrl;
SPList childList = null;
Guid listID = SPContext.Current.List.ID; //.ToString();
HyperLink linkAddNew = new HyperLink();
protected override void CreateChildControls()
{
base.CreateChildControls();
if (this.ControlMode == SPControlMode.Display ||
this.ControlMode == SPControlMode.Edit ||
this.ControlMode == SPControlMode.New)
{
literalCtrl = new LiteralControl();
base.Controls.Add(literalCtrl);
base.Controls.Add(linkAddNew);
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
string childListname = this.Field.GetCustomProperty("ChildListName").ToString();
try
{
try
{
childList = SPContext.Current.Web.Lists[childListname];
}
catch
{
throw new ConfigurationErrorsException(@"Child List " + childListname + " doesn't exist at the site.");
}
StringBuilder sb = new StringBuilder();
try
{
SPQuery query = new SPQuery(childList.DefaultView);
query.Query = string.Format(@"
<Where>
<Eq>
<FieldRef Name='{0}' LookupId='true' />
<Value Type='Integer'>{1}</Value>
</Eq>
</Where>", LookupField.InternalName, this.Item.ID.ToString());
sb.Append(childList.RenderAsHtml(query));
}
catch (Exception ex)
{
sb.Append("<p>There was an error loading the list information:<br />");
sb.Append(ex.Message);
sb.Append("</p>");
}
literalCtrl.Text = sb.ToString();
// Add new
linkAddNew.Text = "Add New";
string navigateUrl = string.Format("/NewForm.aspx?{0}={1}&Source={2}", SPEncode.UrlEncode(LookupField.Title), SPContext.Current.ListItem.ID.ToString(), SPEncode.UrlEncode(this.Page.Request.Url.ToString()));
linkAddNew.NavigateUrl = childList.RootFolder.ServerRelativeUrl + navigateUrl;
}
catch (Exception ex)
{
literalCtrl.Text = ex.Message;
}
}
SPField _LookupField = null;
SPField LookupField
{
get
{
if (_LookupField == null) {
foreach (SPField field in childList.Fields) {
if (field is SPFieldLookup && listID == new Guid(((SPFieldLookup)field).LookupList)) {
_LookupField = field;
break;
}
}
}
return _LookupField;
}
}
protected override void Render(HtmlTextWriter output)
{
literalCtrl.RenderControl(output);
// Add New link
if (this.ControlMode == SPControlMode.Display ||
this.ControlMode == SPControlMode.Edit)
linkAddNew.RenderControl(output);
}
public override void UpdateFieldValueInItem()
{
this.EnsureChildControls();
try
{
this.Value = NumOfChildren;
this.ItemFieldValue = this.Value;
}
catch (Exception)
{
;
}
}
}
添加一个新的子项
当用户添加新子项时,我们应该在NewForm.aspx表单中自动为用户选中“Parent Tab”下拉框中相应的项。这就是为什么我们要在查询字符串中添加查阅项字段的名称和值:“NewForm.aspx?Parent%20Tab=1&Source=...”。
将如下的JavaScript代码放置在子列表的NewForm.aspx中。最好的位置当然是放在“PlaceHolderBodyAreaClass”里。
<script type="text/javascript">
var qs = location.search.substring(1, location.search.length);
var nameVal = qs.split("&")[0].split("=");
SetLookupFieldValue(unescape(nameVal[0]), nameVal[1]);
function SetLookupFieldValue(fieldName, val) {
var theSelect = getTagFromIdentifierAndTitle("select",
"Lookup", fieldName);
if (theSelect != null) {
theSelect.value = val;
return;
}
// if theSelect is null,
// it means that the target list has more than 20 items,
// and the Lookup is being rendered with an input element
var theInput = getTagFromIdentifierAndTitle("input",
"", fieldName);
theInput.value = val;
}
function getTagFromIdentifierAndTitle(tagName, identifier, title) {
var len = identifier.length;
var tags = document.getElementsByTagName(tagName);
for (var i = 0; i < tags.length; i++) {
var tempString = tags.id;
if (tags.title == title && (identifier == "" ||
tempString.indexOf(identifier) == tempString.length - len))
return tags;
}
return null;
}
</script>
解决方案包下载安装
解决方案包“ParentChildRelationship.wsp”是用Visual Studio Extensions VseWSS v1.3开发的。打开“Setup.bat”,设置你的网站集和网站的URL地址:
set DefaultWebUrl=http://YourWeb
set DefaultSiteUrl=http://YourSite
然后运行setup.bat即可完成安装。卸载时,运行setup.bat -u。
安装完成后,创建一个网站栏(比如MyChildren),类型为ParentChildrenField。输入子列表的名称(不是url)。然后,将该栏添加到父列表中即可。
源代码 安装包
参考资料
SharePoint List Parent /Child Relationship
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com