SharePoint offers a lot of options to create custom list forms like jQuery, SharePoint Designer, InfoPath (last Release) and of course ASPX forms. Regarding the last point i demonstrated a shorter “how to” at the Shareconf 2014 in Düsseldorf and would like to share the idea behind the ASPX Forms in this post.
The ASPX Forms (SPForms) which i mean are based on the use of the rendering templates along with ascx user controls.
The rendering template contains all elements which are needed by the listform. You can find the default rendering templates used by SharePoint in the 14 Hive or 15Hive in the controltemplate folder. It is the user control DefaultTemplates.ascx in which you’ll find the “Listform” template. Copy this one and add in your solution the mapped folder for controltemplates. In your user control add the copied template and rename the template id.
[sourcecode language=”csharp”]
Custom New Form
|
[/sourcecode]
You also should add a register control of the “wssuc” which is needed:
<%@ Register TagPrefix=
"wssuc"
TagName=
"ToolBar"
src=
"~/_controltemplates/15/ToolBar.ascx"
%>
I also added a h3 tag which indicates that the listform uses my template. In order to use this template, we should connect it to our list. Therefore you can use it by code
[sourcecode language=”csharp”]
SPWeb web = site.RootWeb;
try
{
if (web != null)
{
SPList list = web.GetList(SPUrlUtility.CombineUrl(web.ServerRelativeUrl, “/Lists/listname”));
SPContentType ct = list.ContentTypes[0];
ct.NewFormTemplateName = “RenderingTemplateID”;
ct.Update();
[/sourcecode]
or by Powershell
[sourcecode language=”csharp”]
Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue
$web = Get-SPWeb http://server/sites/sitecollection
$list = $web.Lists[“listname”]
$ct = $list.ContentTypes[0]
$ct.NewFormTemplateName = “NewForm_Zaehlerstand”
$ct.Update()
$ct.NewFormTemplateName
$ct.EditFormTemplateName = “EditForm_Zaehlerstand”
$ct.Update()
$ct.EditFormTemplateName
[/sourcecode]
After that is working, we now can add more logic. In the rendering template it’s not possible to add code behind. So therefore it’s better to put it into another user control. In the first step, we add a new user control. This user control contains some fields of our list.
[sourcecode language=”csharp”]
(Pflichtfeld)
[/sourcecode]
You should map it to your list column names and can define a different styling or structure for your form. I just use the default.
This user control we now reference in the rendering template by just registering the control:
[sourcecode language=”csharp”]
< %@ Register TagPrefix=
"ShareConf"
TagName=
"FormFields"
src=
"~/_controltemplates/15/RC_Fields.ascx"
%>
[/sourcecode]
and then add it in the template itself just before the listfielditerator
[sourcecode language=”csharp”]
[/sourcecode]
If it is working it should look like this:
Now we add a third user control, in which we customize the save button and cancel button behaviour. In this user control we add the following
[sourcecode language=”csharp”]
|
&amp;#160; |
|
[/sourcecode]
And in the code behind, we now can override the save button:
[sourcecode language=”csharp”]
protected override void OnInit(EventArgs e)
{
//In the init method you overrite the event handler for saving with your save button action
base.OnInit(e);
savebutton2.ItemContext.FormContext.OnSaveHandler += new EventHandler(mySaveHandler);
}
//My Save Button Function
protected void mySaveHandler(object sender, EventArgs e)
{
Page.Validate();
if (Page.IsValid)
{
SPListItem item = SPContext.Current.ListItem;
item[“Kundennummer”] = “ShareConf”;
item.Update();
}
}
[/sourcecode]
Now we have to reference this user control again in the rendering template and remove the default save buttons (2 per form) with our User Control.
Register Control: <%@ Register TagPrefix=
"ShareConf"
TagName=
"SaveButtons"
src=
"~/_controltemplates/15/RC_SaveButtons.ascx"
%>
[sourcecode language=”csharp”]
< %--
–%>
[/sourcecode]
If it is working your item should be saved and add also the value to the other list column.
That’s the magic. That could be the starting point for your form strategy in your company. Use style guides, best practices for usability of forms and help your developers to achieve creating custom and nice forms. You now have the full control of your listform cause it is based on aspx.
The negative point is, that it is not possible to use this for Office 365. But if you’re working on On-Premise it might be an interesting starting point. Especially if you’re using forms which should interact with your LOB-systems or should have more features.
Just a quick view on my visual studio project and the controltemplates:
Hope you can reuse it.
Interesting article. Did you test it on SharePoint 2013 environment or is it supposed to run in SP 2013?
runs on SP2013 too but not in office 365.
Karsten,
Good article! I have a comment and a question:
Comment: The code for referencing the FormFields control on the article has an extra ‘/code’ closing tag, so it’s not formatting correctly.
Question: Where would be a good place to put the code to connect the template to our list? When I have a feature, I put such code in the Feature Activation. In this case, I don’t know where to put it. Any advice?
Thanks!
Hi,
if list is not based on Content type then how I can tell to my list to use which template.
$web = Get-SPWeb https://demoapp.presys.de/sites/EntwicklerAPPsite
$list = $web.Lists[“Feststellungen”]
$list.temp
$ct = $list.ContentTypes[0]
$ct.NewFormTemplateName = “FeststellungenEditForm”
$ct.Update()
$ct.NewFormTemplateName
is valid only if content type is present,
Best Regards
Hi, normally every list contains at minimum one content type even if you cannot see it. You can check it with Powershell. What is the result if you check $list.ContentTypes?