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
Leave a comment