Body:
To this day, my most popular blog posts continue to be my posts on how to set up a parent/child list relationship in SharePoint. These blog posts show you how to automatically set the ID of a Lookup field for a “child” list for different versions of SharePoint using various methods:
- Creating a SharePoint List Parent / Child Relationship – Out of the Box (yes, I know the videos are dead on this one. The VIDEO REMIX post is better anyway)
- Passing Multiple Query String Variables Using SPD – Follow Up on Creating Parent / Child List Relationships
- Creating a SharePoint List Parent/Child Relationship – VIDEO REMIX
- Creating A SharePoint Parent/Child List Relationship– SharePoint 2010 Edition
- Creating a SharePoint Parent/Child List Relationship–No SPD Version
- Creating a Parent/Child List Relationship in SharePoint 2013
As helpful as many have found these solutions, they only worked for lists and not for document libraries. The reason for this is that we are using query string variables to pass the ID of the parent list to the child new form. However, when you add a document to a document library there are two forms. The first form is a dialog for uploading your file, and the second form is the page used for entering all the various properties for the file including the lookup field for the parent. When using the query string method from the previous posts, the ID for the parent list item is passed to the upload dialog, NOT the properties page.
So, the problem is that we need to persist the parent item’s ID until the properties form is displayed for our newly uploaded file and then set the form field accordingly. I don’t really want to get into customizing the upload dialog to pass along the query string variable and adding script to the Master Page for this one purpose would be woeful. So, what to do?
C is for Cookie
Sorry, I couldn’t think of any other cookie analogy but by taking advantage of cookies we can set a cookie with our parent list item ID and our properties page will be able to read it.
Why I like the cookie option
Using a cookie ends up being a fairly simple solution and even adds some additional benefits:
- By setting a cookie with your Parent List ID you can easily have multiple child lists that can all easily access the cookie.
- A cookie will work for both lists and document libraries.
- You can store other field values in additional cookies and pass those to your forms as well.
Why I DON’T like the cookie
So, as cool as this cookie idea sounds and as many benefits as I get, I’m still not THRILLED about using a cookie for a couple of reasons:
- When you create a cookie, it remains accessible to your pages until it expires. This has benefits, but it also CAN create issues. You could conceivably have a page use a cookie that you didn’t mean for it to use if you aren’t careful.
- Once a developer (especially inexperienced ones) latch onto a device such as cookies they can go a bit crazy with it and start using it all over the place. I don’t like the thought of someone creating a ton of cookies that they don’t expire and then asking me to debug their form because for SOME reason it ALWAYS sets a form field to the value “42”.
- On that same note, if a developer creates a generic name for a cookie and some other developer on that site decides to use cookies too and uses the same generic name, you’re going to be possibly overwriting each others values. You’re code will work fine on your machine… but have fun debugging that one. Make sure to use a unique cookie name.
- How do I handle expiring a cooking? Expire it right after I’ve used it? Let it expire in 5 minutes? a day? well… “it depends”. Which means you SHOULD give them some thought when use them and not just blindly make a decision. So, it CAN add some complexity. For this blog I chose to keep it simple and let my cookies expire after 5 minutes.
The Solution
As I said, the solution ends up being actually fairly simple, and you can view the video below to see step-by-step how I did it. In the video I’ll be using the cookie for both a child list and a child document library. With just a couple of scripts we can be up and running quite quickly. If you don’t want to watch the video, but want to know what I did, here are the steps to take:
Create the infrastructure
Create your lists and libraries. Create lookup fields to your parent list in your child lists and libraries. For this blog, I’ll stick with my conventions from my previous posts on the subject. I will have a Parent list “Issue”, a child list “Time”, and a new child library “IssueDocuments”. Each child list has a lookup field to the “Issue” list with the name “Issue” and I’m looking up on the “Title” field.
Edit the default display form for your parent list.
Add list view web parts for your children forms onto the page.
Create web part connections from your parent list to your children list filtering the children list by the parent list ID and the child list/library lookup field.
After you have you child list views added and the web part connection set up, go ahead and manually create a couple of entries in your children lists/libraries selecting a valid parent from the lookup field. You will see that only the children for the parent list item will show in the list views on the Issue display form. Now to set it up so you don’t have to manually set the lookup field value for the parent.
Add a script to the default display form of the parent list
Edit the default display form of the parent list again, add a content editor web part and link it to the following script which I’ll be placing in my Site Assets library. In this script I’m creating a cookie for the parent list ID that exists in the query string of my parent display form. I’m giving the cookie the name “IssueID” and having it expire in 5 minutes.
If you’ve followed my previous blogs on the subject, you’ll remember that we had to previously modify the link to the “Add New Item” on the child list view to make it pass the IssueID to the child list form in the query string. Well, since we are using cookies, we don’t need to modify the default “Add new item” or “Add new document” links at all. This also means you can add several child list views without having to modify the above script at all. That’s a nice side benefit of using cookies.
So, now when you load the the display form of your parent list item, a cookie is being set called “IssueID” that contains the ID of that parent list item.
Add a script to our children forms
At this point, all we have to do to make this all work together is add a script to the New Item Form of our child Lists and the Edit Forms of our child Document Libraries.
In this script, the script simply looked for a cookie called “IssueID” and if it found the cookie, it used the value of the cookie and set the form field “Issue” to that value. It then disabled the “Issue” field on the form to stop those pesky users from changing it to something else. If you are passing multiple fields in multiple cookies you would just use the same logic to set the various form fields for each cookie. If you need to know how to set various form fields in a SharePoint form, you can reference my previous blog post on the subject:
A Dummies Guide to SharePoint and jQuery–Getting & Setting SharePoint Form Fields
The last thing I’ll point out about this script is that it takes into account the 20 item lookup field “feature” in SharePoint 2007 and 2010:
Setting SharePoint Lookup Lists w/ jQuery (+/- 20 items)
This does not seem to be an issue in SharePoint 2013 and a lookup field is always a select (unless something has changed since I last tried), so if you are using SharePoint 2013 you don’t need the portion of the script that looks for the “Issue” field as an input.
That’s it! You’re done! Now when you open up the display form for your parent list and click on the “add new…” link for any of your child lists (that you applied the above script to on their respective forms), the parent lookup field value will automatically be set and the lookup field will be disabled.
The Video
So, you don’t like reading and you just want to watch me do it all? Okay, let’s see if I can do it all in one take without screwing up:
Conclusion
So, this solution will work on SharePoint 2007, 2010, 2013 and in Office 365. That’s pretty cool. Will I start using cookies more often? I’ll continue to use them judiciously and when it makes sense. I’m not enamored by the thought of having this data floating around that I no longer need and getting bit by it because some developer didn’t create a unique cookie name and it messes up some other page.
I see this being an extremely useful tool to use though, but please learn all your tool options and use the right one for the right project.
Thanks again for taking the time to read my ramblings. Yes, there’s 100 ways to skin a cat, so if you have a better/easier solution please feel free to share with the class!
Mark, I’m noticing that March 2013 was your last post on this. I’m curious if there have been any developments since then or if you are satisfied that your posted solutions continues to function properly. I was a bit hesitant about trying the ‘Cookie’ solution, so I’m attempting to make the earlier ‘query string’ solution work from your 2012 post. Is there anything that has changed to make this no longer work?
Is it possible that the reference for the anchor element has changed? Curious if you can shed some light on how to find those references through the DOM…I’m not familiar with this process.
TIA!
You can’t use the URL approach with document libraries because of the upload dialog. Cookies are the easiest way to go there. I do have an idea to improve the cookie functionality though, so look for a new blog post on this soon.
Thanks!