Wednesday, 23 January 2013

Customising the NewForm.aspx of a List using Server Side Code

Edit - I am getting some feedback from other devs the sum of which is "forget this and do it via jQuery instead".  It is worth noting that this is NOT the recommended way of customising a NewForm or EditForm aspx page, so proceed at your own risk. JQuery is downloadable for free at When I figure out how to use it I will post a follow up!

I've been meaning to write this for ages. The first thing I should mention is that you're not meant to do this. Believe me I have fought the Sharepoint markup generator every step of the way on this one. It wants you to use JQuery and the ECMA client script. But god JQuery is a pain and I don't know it. And it's hard to read or pick up, and dammit I want to use C flippin sharp and nothing and no-one is going to stop me.

OK. As we say in Ireland when someone asks for directions: "If I were you, I wouldn't start from here." But if you DO start from here...

Firstly, you aren't allowed to run code on aspx pages that run in SharePoint. So you have to go into the web config, go to the <PageParserPaths> section and enter something like the following:
<PageParserPath VirtualPath="http://myserver/mySiteColl/MyList/MyForm.aspx" CompilationMode="Always" AllowServerSideScript="true" />

More info on Page Parser Paths here...

OK run an iisreset and that will allow you to customise the NewForm.aspx. Microsoft do not recommend fiddling with the form itself as if you break it, you break the list. So fire up SharePoint Designer to create a new page.

More info on customising the page here

Now I'm aware that there's this nifty plugin called InfoPath which will do the forms for you. Do we have that in my workplace? Not a chance. Not on the cards until we upgrade. So just in case you ask me "what about infopath", that's the answer.

Right. I do this in SharePoint designer. Now that the MyForm.aspx has been created, click the "Code" tab. But before we continue it is important to note the following:

None of the standard SharePoint OK or Cancel buttons is customisable.

Trust me. I tried. Your best bet is hiding and creating a custom HTML command button of your own. Then you can have runat=server, onclick = "DoTheWork" etc. Then, of course, you have to create a script to do the work :)

So, right up the top of your HTML, put up the following. Note that

(1) when getting the list name, I am using the request parameter and ascertaining the position of the string "MyForm". This means I can re-use the code in other lists if I want.

(2) The ContentPlaceHolder bit of code is how I get to "talk" to the sharepoint form controls through the code. Trying to figure out where the controls are and what they're called and how to get the damn data out of them is like breaking into Fort Knox. So if I want to save back to the list (remember, there is no way to get to the save routine via the OK button BECAUSE I HAVE TRIED)

I need to go right into the markup, grab the guid of the data form web part and then furthermore pull out the name from the the properties tab on the left in SP Designer (it's always ff_number) and then get the value. And don't talk to me about radio buttons. I can't get it to work with radio buttons.

I've done a uservalue control because it's the trickiest.

(3) The ID at the end of the request string will always be the ID on the list item you're looking for, so I used that to retrieve the item.

(4) All saving of items is done through the SPListItem object and the Update() method

(5) I don't have a sharepoint environment and compiler with me right now, so chances are there are a couple of errors in the script, but nothing major. Code below the jump - enjoy!

 <script type="text/c#" runat="server">
        protected void SendMailToUser(object sender, EventArgs e)
            string cSiteName = "http://myserver/mysitecoll/";
            string cListName = string.Empty;
            SPSite site = new SPSite(cSiteName);
            SPWeb web = site.OpenWeb();
        //which list is it?
            int start = 0;
            int end = 0;
            string requestUrl = Request.Url.ToString();
            start = requestUrl.IndexOf("Lists");
            start = start + 6;
            end = requestUrl.IndexOf("/MyForm");
            cListName = requestUrl.Substring(start, end - start);
        //retrieve list item
            ContentPlaceHolder holder =     (ContentPlaceHolder)Master.FindControl("PlaceHolderMain");
            DataFormWebPart dwp = (DataFormWebPart)holder.FindControl("c2a69f84-b81f-4cd6-a952-4b27add4c177");
            FormField userCtrl = (FormField)dwp.FindControl("ff8_1");
            string userValue = userCtrl.Value.ToString();
            int pos = userValue.IndexOf("#");
            userValue = userValue.Substring(pos + 1);      
            //get request param id
            string param=Server.UrlDecode(Request.QueryString["ID"]).ToString();
            int itemID = Int32.Parse(param);
            SPList list = web.Lists[cListName];
            SPListItem item = list.GetItemById(itemID);
            //get user
            string userValue1 = item["User Field"].ToString();                                      
            SPFieldUserValue fieldUserValue = new     SPFieldUserValue(web,userValue1);              
            SPUser user = fieldUserValue.User;
            string requesterEmail = user.Email;
            //send email IT Support
            string body = string.Empty;
            string subject = string.Empty;
            body = "Dear " + user.Name + " this is a link to <br/><br/> <a href='http://connect/grp/it/Lists/" + list.Title.Replace(" ", "%20") + "/MyForm.aspx?ID=" + itemID.ToString() + "'>Click the following link</a>";
            subject = "Approval Required for New Request";
            errorArgs = "line 6";
            SPUtility.SendEmail(web, false , false, requesterEmail, subject, body, false);
         //confirm done
         string done = "<script language='javascript'>alert('Email sent to user'" + user.Name + ");</scrirt>";
            done = done.Replace("scrirt","script");
        catch (Exception ex)
            Response.Redirect(cSiteName + "/Lists/" + cListName + "/MyItems.aspx");

No comments:

Post a Comment