Master/Detail Pages in SharePoint 2007

Sometimes (very often) we have to be faced with the user requirements of master-detail lists. If you want to implement a very basic one, it’s very simple: lookup fields can have very big strong. For example, you need to store company data with contact people:
Well, how can you store these info pieces in SharePoint lists? – Of course, you’ll simply have two lists: first one for the companies, and the second one for the contact persons. In this second list you have to make a lookup column referring to the Companies list. In this column we’ll store the info where is that person’s working:
That’s great, but in most cases that’s not enough. You can maintain companies and contacts in different spaces, in different lists. The main problems with this are the followings:
  1. You cannot see the related contacts on the Company’s form. For example, I’d like to have a form for Company1 where I can see Thomas, Spencer, Percy, Harvey and Harold.
  2. You cannot maintain the contacts directly from the companies data form. When you view/edit a contact person, you’ll be redirected to the contacts list’s AllItems.aspx instead of the related company’s DispForm.aspx.
So, would you like to know what I’m talking about? The default display form of a company is something similar this:
Instead of that, I’d like to see something like that:
I’m very sorry because of the Hungarian UI, but to be honestly this example is from my company’s Intranet site. Most probably you’re interested in a few words, so let’s start your first Hungarian lesson:
  • Ügyfél = customer
  • Kapcsolattartó = contact person
  • Bezárás = close
That’s it, I hope you understand everything else 🙂
Well, making a form like that is very simple, you just have to create a Data View webpart with SharePoint Designer. The source list of this Data View is the contacts list, filtered by the current company: create a custom company DispForm webpart based on the URL’s ID parameter, and you can connect this webpart to the Data Views. You need this trick just because the URL contains the company’s ID, but in the Data Views you need the name of that.
In the Data Views, all of the the items’ link redirect you to the selected contact person’s DispForm / EditForm – and very similar, the New Contact (“Új kapcsolattartó”) link placed in the footer of the webpart redirects you to the contacts list’s NewForm.aspx.
That’s well and good, but how are we redirected to the company’s page from these forms? – This step requires two little tricks. First of all, we have to tell the forms where to come back. It’s pretty easy, just place a parameter in the URL. For example, the New Contact (“Új kapcsolattartó”) link is something like this:
where CustomerID is the ID of the current company, and you can read this from the URL as a QueryString parameter:
OK, we’re ready on the companies’ side, let’s jump to the contacts list. Here we should update all forms (DispForm.aspx, EditForm.aspx, NewForm.aspx) and learn them to redirect us to the related company’s DispForm instead of Lists/Contacts/AllItems.aspx. As the logic of this modification is similar on all these forms, let’s only see the NewForm.
First of all, what you have to do to change the default redirecting of Save and Cancel buttons is to replace the default NewForm webpart to a custom one. Changing the redirecting to a static URL is very simple, but in this case we need a dynamic URL in the redirection, because of the CustomerID parameter. Let’s dig into it and see the way of dynamic redirecting step-by-step:
  • Read the CustomerID parameter from the URL (see above).
  • Place the following snippet to the beginning of the Data View webpart’s code. With it you can build the redirect URL (RedirectLoc) in a dynamic way:
    <xsl:param name=”CustomerId” />
        <xsl:variable name=”RedirectLoc”>/cust_site/Lists/Customers/DispForm.aspx?ID=<xsl:value-of select=”$CustomerId” />
  • Finally, replace the default SAVE and CANCEL button to this ones:
    <input name=”SaveButton1″ type=”submit” value=”Save” onclick=”javascr ipt: {ddwrt:GenFireServerEvent(concat(‘__commit;__redirect={‘,$RedirectLoc,’}’))}”/>
    <input name=”CancelButton1″ type=”button” value=”Cancel” onclick=”javascr ipt: {ddwrt:GenFireServerEvent(concat(‘__cancel;__redirect={‘,$RedirectLoc,’}’))}”/>
That’s it! Hope you like it – more to come, stay tuned!