zoukankan      html  css  js  c++  java
  • 通过自定义字段类型实现SharePoint列表的父子关系

    父子关系在现实场景中很常见。在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[i].id;
            if (tags[i].title == title && (identifier == "" || 
                tempString.indexOf(identifier) == tempString.length - len))
                return tags[i];
        }
        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

  • 相关阅读:
    企业库应用实践系列五:创建模板引擎Library
    关于HtmlHelper:是MVC自作聪明,还是我不够明白?
    企业库应用实践系列二:对象创建原理详解
    企业库应用实践系列三:自定义构造函数
    专业导论 计算机科学概论
    企业短期项目,缺人手
    光脚丫学LINQ(040):引发未将对象引用设置到对象的实例的异常
    光脚丫学LINQ(045):如何表示计算所得列(LINQ to SQL)
    光脚丫学LINQ(042):如何将列表示为由数据库生成的列
    光脚丫学LINQ(043):为实体类的列成员指定在数据库中的数据类型
  • 原文地址:https://www.cnblogs.com/Sunmoonfire/p/1837273.html
Copyright © 2011-2022 走看看