DistinctFieldValuesFieldType solution (Sharepoint 2007)

Сегодня столкнулся с проблемой при разработке одного модуля на sharepoint 2007. Очень нужно сделать поле выбора который бы брал свои значения из другого списка, причем уникальные. Стандартного такого нету, в интернете поиск тоже ничего не дал. Потратил 3 часа и проект готов.  Рассмотрим что получилось.

1) Создаем пустой проект под Sharepoint

2) Добавляем CustomFieldType из шаблонов WSPBuilder

3) Нам нужны 3 переменные "WEB_URL", "LIST_NAME", "FIELD_NAME"

WEB_URL = путь к узлу где находится LIST_NAME = список , и FIELD_NAME = поле списка значения которого будут использованы.

В фале fldtypes_DistinctFieldValuesFieldType.xml укажем эти 3 переменные:

<Fields>
        <Field Hidden="TRUE" Name="WEB_URL"            DisplayName="Web URL"          Type="Text" MaxLength="500" >        </Field>
        <Field Hidden="TRUE" Name="LIST_NAME"          DisplayName="List Name"        Type="Text" MaxLength="255" >        </Field>
        <Field Hidden="TRUE" Name="FIELD_NAME"         DisplayName="Field Name"       Type="Text" MaxLength="255" >        </Field>        
</Fields>

Так же подредактируем сам Editor.

<wssuc:InputFormControl runat="server"
	LabelText="Параметры выбора"	>
	<Template_Control>
	
	<table>
	<tr><td class="ms-authoringcontrols"><asp:Label id="lblurl" runat="server" Visible="True" Text="URL узла"/></td></tr>
	<tr><td><asp:TextBox ID="txturl" runat="server" CssClass="ms-input" Columns="35"></asp:TextBox></td></tr>
	<tr><td class="ms-authoringcontrols"><asp:Label id="lbllist" runat="server" Visible="True" Text="Название списка"/></td></tr>
	<tr><td><asp:TextBox ID="txtlist" runat="server" CssClass="ms-input" Columns="35"></asp:TextBox></td></tr>
	<tr><td class="ms-authoringcontrols"><asp:Label id="lblfield" runat="server" Visible="True" Text="Название поля"/></td></tr>
	<tr><td><asp:TextBox ID="txtfield" runat="server" CssClass="ms-input" Columns="35"></asp:TextBox></td></tr>
	</table>
        

	</Template_Control>
</wssuc:InputFormControl>

И код:

public class DistinctFieldValuesFieldTypeFieldEditor : UserControl, IFieldEditor
    {
        // Fields
        protected TextBox txturl;
        protected TextBox txtlist;
        protected TextBox txtfield;
        private DistinctFieldValuesFieldType _DistinctFieldValuesFieldType;

        public void InitializeWithField(SPField field)
        {
            this._DistinctFieldValuesFieldType = field as DistinctFieldValuesFieldType;

            if (this.Page.IsPostBack)
            {
                return;
            }

            if (_DistinctFieldValuesFieldType != null)
            {
                this.txturl.Text = _DistinctFieldValuesFieldType.WEB_URL;
                this.txtlist.Text = _DistinctFieldValuesFieldType.LIST_NAME;
                this.txtfield.Text = _DistinctFieldValuesFieldType.FIELD_NAME;
            }
          
        }
        
        public void OnSaveChange(SPField field, bool bNewField)
        {
            DistinctFieldValuesFieldType fld = (DistinctFieldValuesFieldType)field;

            fld.IsNew = bNewField;
            fld.WEB_URL = this.txturl.Text.Trim();
            fld.LIST_NAME= this.txtlist.Text.Trim();
            fld.FIELD_NAME= this.txtfield.Text.Trim();
        }
        

        // Properties
        public bool DisplayAsNewSection
        {
            get
            {
                return false;
            }
        }



    }

Собственно и код

public class DistinctFieldValuesFieldTypeControl : BaseFieldControl
    {
        private DistinctFieldValuesFieldType field;
        private DropDownList ddlist;

        public DistinctFieldValuesFieldTypeControl(DistinctFieldValuesFieldType parentField)
        {
            this.field = parentField;
        }
      
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            try
            {
                ddlist = new DropDownList();
                ddlist.CssClass = "ms-long DistinctFieldValuesFieldType_" + this.field.Id;
                ddlist.Attributes.Add("DistinctFieldValuesFieldType", this.field.Id.ToString());
                //добавим класс и аттрибут DistinctFieldValuesFieldType чтобы с помощью javascript можно было манипулировать котролом.

                if(!this.field.Required)
                {
                    ddlist.Items.Add(new ListItem("Нет",""));
                }

                if (!string.IsNullOrEmpty(this.field.WEB_URL) && !string.IsNullOrEmpty(this.field.LIST_NAME) && !string.IsNullOrEmpty(this.field.FIELD_NAME))
                {
                    SPSecurity.RunWithElevatedPrivileges(
                        delegate
                        {
                            using (SPSite site = new SPSite(this.field.WEB_URL))
                            {
                                using (SPWeb web = site.OpenWeb())
                                {
                                    SPList list = web.Lists[this.field.LIST_NAME];

                                    if (list.Fields.ContainsField(this.field.FIELD_NAME))
                                    {
                                        SPField groupFld = list.Fields[this.field.FIELD_NAME];
                                        if (groupFld.Type != SPFieldType.Text & groupFld.Type != SPFieldType.Boolean & groupFld.Type != SPFieldType.Number & groupFld.Type != SPFieldType.DateTime & groupFld.Type != SPFieldType.Currency)
                                        {throw new Exception("Cannot get distinct values.Type is not Text, Number, Currency, DateTime, or Boolean.");}

                                        object[,] columnItems;
                                        uint numberValues = list.GetDistinctFieldValues(groupFld, out columnItems);
                                        
                                        for (int j = 0; j < numberValues; j++)
                                        {
                                            string uniqValue = SPEncode.HtmlEncode(columnItems.GetValue(0, j).ToString());
                                            ddlist.Items.Add(uniqValue);
                                        }
                                    }
                                }
                            }

                        });
                }

                this.Controls.Add(ddlist);
            }
            catch (Exception ex)
            {
                Label lblerror=new Label();
                lblerror.Text = ex.Message;
                lblerror.Style.Add("color","red");
                this.Controls.Add(lblerror);
            }
        }

        public override object Value
        {
            get
            {
                EnsureChildControls();
                if (this.ddlist != null)
                    return this.ddlist.SelectedValue;
                else return string.Empty;
            }
            set
            {
                EnsureChildControls();
                if (this.ddlist != null && value != null && !string.IsNullOrEmpty(value.ToString()))
                {
                    this.ddlist.Text= value.ToString();
                }
            }
        }

        public override void Validate()
        {
            base.Validate();

            if (Field.Required &&
               (Value == null || Value.ToString().Length == 0))
            {
                this.ErrorMessage = Field.Title + " Необходимо задать значение для этого обязательного поля.";
                IsValid = false;
                return;
            }

        }
    }

:

 Собственно что у нас получилось:

 

 

 

Добавить комментарий

Loading