Tags

, , , , , , , , ,


Overview

SharePoint developers are thinking what is the benefit of creating a custom  asp.net forms to add items in lists , it’s something like create a normal aspx page to add an item to database ! where is the powerful of SharePoint here in this case specially if there is a change request later to add a new field to list that will make a load for developers to add a new text box or any another control to the form that will insert a new item !

so let’s play with SharePoint controls and list fields that will give us the power to create  dynamically generated  forms  to add and edit items in SharePointlists , this solution will generate a SharePoint Controls rather than normal asp.net controls.

A problem that our solution can fit into it

Suppose you create some SharePoint survey’s  and your task is to create a custom form for answering each one by users

As we know SharePoint survey is a normal SharePoint list , questions are representing as a list columns and answers are representing as  list items , each item contain a “created by” column that contain the username who answer this survey

The traditional way for example create a survey with 5 questions then create a form that contain 5 asp.net controls to add answers, for sure you will map questions types with your controls for example if the question type is a multiple so you will add  checkboxes to your form and you will add a choices number like these which you entered in the question type , this way as you build a normal asp.net form to add an item to a database table !

Or create a data form web part from SharePoint designer , the problem is you will create this web part for each survey and starting enhance the style for it and everything every time you will create a new survey !

But our way is using SharePoint fields and web controls rendering ways to render the controls on form dynamically and it will auto reflect any new question (lits column ) added to the survey and render it as a SharePoint control (not normal asp.net control !) in your form  , you don’t need to add more code for the new added column and also you can use this way with any list just write your code once then change the name of the list , your code will generate a form to add a new item dynamically with saving item code also !

So we will create our example based on this case (survey answering form)

Understanding SharePoint Web Controls , SharePoint List fields objects

1-SPField class represents a list column and it contains and attribute named “FieldRenderingControl” we will use this attribute to return the sharepoint web control for example if we have a column with type single line of text the attribute “FieldRenderingControl” will return TextField object that represent as a SharePoint text field and the same way for all types , here you can find the famous SharePoint web controls that we can return from SPField.FieldRenderingControl

Control
TextField
CheckBoxChoiceField
NumberField
RadioButtonChoiceField
RichTextField
BooleanField
DropDownChoiceField
DateTimeField

2-all sharepoint web controls inherits from BaseFieldControl  that means SPField. FieldRenderingControl

3-each web control must specify some attrbuites to render (except DateTimeField)

Attrbuite Description
ID Id for this control
FieldName The field name that this control will lookup from or to it
ControlMode The mode that will control presenting  , we have three modes (New , Edit , Display)
ItemId Id for the item from column ID
ListId Guid for this list

4-we will loop through an SPList.Fields to get all fields for this list then we will filter then to get our custom fields only , we can use SPField.Reordable attrbuite to specify  the fields which we want to represent as a web controls , for sure you will recive Created By field and if you want to hide it just check through the loop if this field is Created By escape it from rendering

Part 1 Build your form dynamically

-I will describe each part of the code with a  line comment above each part

//our list

_listObj = web.GetList(string.Format(“/Lists/{0}/allitems.aspx”, “Sports Survey”));

/*create a table to add our form controls on it*/

Table table = new Table();

TableRow row = new TableRow();

TableCell cell = new TableCell();

cell.Text = string.Format(“<h3>{0}</h3>”, _listObj.Title);

cell.ColumnSpan = 2;

row.Cells.Add(cell);

table.Rows.Add(row);

foreach (SPField field in _listObj.Fields)

{

if (field.Reorderable)

{

//add a title for each control

row = new TableRow();

cell = new TableCell();

cell.Text = string.Format(“<strong>{0}</strong>”,field.Title );

row.Cells.Add(cell);

table.Rows.Add(row);

//create your sharepoint control from its field

BaseFieldControl webControl =          field.FieldRenderingControl;

//create an id for this control that we will get the value of this control with this id later

webControl.ID = string.Format(“ctrl_{0}”,field.InternalName);

webControl.FieldName = field.Title;

webControl.ItemContext =SPContext.GetContext(HttpContext.Current, _listObj.DefaultView.ID, _listObj.ID, _listObj.ParentWeb);

webControl.RenderContext = SPContext.GetContext(HttpContext.Current, _listObj.DefaultView.ID, _listObj.ID, _listObj.ParentWeb);

webControl.ControlMode = SPControlMode.New;

webControl.ListId = listObj.ID;

//check for the field is not created by field

if (!field.InternalName.ToLower().Equals(“author”))

{

row = new TableRow();

cell = new TableCell();                                                cell.Controls.Add(webControl);

row.Cells.Add(cell);

table.Rows.Add(row);

}

}

}

//add your table to a lable inside your user control or web part

lblContainer.Controls.Add(table);

so we will see our form now , if you change your form name it will render its controls auttmtically , if you will add or delete any field it will reflect here without any code changing like this

Very nice result !

Part 2 add your save button and save code to save your item

1- first thing create a method that get the value from form controls like this

public string getControlValue(Control SPCtrl)

{

if (SPCtrl is TextField)

{

return ((TextField)SPCtrl).Text;

}

if (SPCtrl is CheckBoxChoiceField)

{

return ((CheckBoxChoiceField)SPCtrl).Value.ToString();

}

if (SPCtrl is NumberField)

{

return ((NumberField)SPCtrl).Text;

}

if (SPCtrl is RadioButtonChoiceField)

{

return ((RadioButtonChoiceField)SPCtrl).Value.ToString();

}

if (SPCtrl is RichTextField)

{

return ((RichTextField)SPCtrl).Text;

}

if (SPCtrl is BooleanField)

{

return ((BooleanField)SPCtrl).Value.ToString();

}

if (SPCtrl is DropDownChoiceField)

{

return ((DropDownChoiceField)SPCtrl).Value.ToString();

}

if (SPCtrl is DateTimeField)

{

if (((DateTimeField)SPCtrl).Value == null)

return “NullDateTime”;

else

return ((DateTimeField)SPCtrl).Value.ToString();

}

return “”;

}

This method will check the type of your SharePoint control then return its value , sure you can add more just I add here some famous controls

2-second inside your event handler of save button  we will make a loop again through our list fields (like the one we did when we rendering    ) then just we will find the control inside the label container control with name “ctrl_”+field.InternalName as we named all our controls in rendering with this schema

_listObj = web.GetList(string.Format(“/Lists/{0}/allitems.aspx”, “Sports Survey”));

foreach (SPField field in _listObj.Fields)

{

if (field.Reorderable)

{

Control ctrl = lblContainer.FindControl(string.Format(“ctrl_{0}”, field.InternalName));

//pass the control to our method that will get the value

string  ctrlValue =getControlValue(ctrl);

//create a new list item to added to the list

SPListItem listItem =_listObj.Items.Add();

//check the value if not “NullDateTime” firstly then save the item , I did this solution because if the datatime field with null value and we want to add this field with null value it will occur and error so we will check for this value then escape if it is true

if (ctrlValue != “NullDateTime”)

{

// update each listitem with its value we got the name of the field dynamiclly as we see

listItem[field.InternalName] = ctrlValue;

}

}

//after finish looping for all fields and fill all columns in listitem object with the values returned from the form controls we will update not this

listItem.Update();

you will find your item added dynamically , you can use this code for any type of lists or document libraries just change your name of the list when you create your SPList object

Tips

-You can make this code as a generic user control that take some  paramteres like the name of the list , item id (if you want to view your control in edit mode or display mode for a specific item) , Control Mode (SPControlMode enumeration)

- You can change the layout and style of your form and controls as you want , you can escape the part of using a Table class that I described It here and replace it with your own way like creating MVC asp.net page and render with another way to help web site desinger to apply styles and so on without need to open your code.

Hope it will help

About these ads