Quite frequently our customers ask us how they can dynamically filter their related items lists based on a value entered into a field on a form created in Forms Designer. In this post I will describe how you can do that with a lookup, a drop-down choice and a people picker field. Although I will use these three field types, just about any field type will do for the job.
The steps for implementing this functionality are pretty straight-forward:
- Set your related items controls render mode to Client (see screenshot below).
- Add a CSS class name to it (see screenshot below). In following samples I will use the “related-issues” class name, if you use something different then replace “related issues” in the code with your class name.
- Add the appropriate code to the JS-editor. See code samples below.
Lookup field
Say we have an issue form with a lookup to a department list and a related items list of other issues. These related issues need to be dynamically filtered based on the value in the Department field. The form will look something like this:
When we change the department, the list is refreshed straight away:
So, how do we achieve this?
After you have followed through the steps described in the previous section paste the following code into the JavaScript editor of your form:
//first filter on page load setHash(); //and attach an on-change handler that will call the filtering function wherever the value of the field changes fd.field('Department').change(setHash); //this is the actual function that filters the list function setHash(){ //get value var value = fd.field('Department').control('getSelectedText'); if (value == "(None)") { value = ""; } value = encodeURIComponent(escape(value)).replace(/\-/g, "%252D"); //set the URL’s hash value. An explanation on this is at the end of the article. window.location.hash = "InplviewHash" + $(".related-issues [webpartid]").attr("webpartid") + '=FilterField=Department-FilterValue=' + value; }
In this code you will need to replace “Department” with the Internal Name (or Internal Names) of the field you’d like to filter:
- Where it says fd.field('Department'), Department is the Internal Name of the lookup field that we get our value from.
- Where it says FilterField=Department Department is the Internal Name of the field in the target list that is being sorted.
In our case the two Internal Names are the same, but they don’t have to be.
And this is it, now our related issues are auto filtered based on the selected Department whenever user changes the value of the Department field.
Dropdown choice field
Here we will do exactly the same thing, but using the Issue Status field, which is a single-value drop-down choice field.
This is the code:
setHash(); fd.field('Issue_x0020_Status').change(setHash); function setHash(){ var value = encodeURIComponent(escape(fd.field('Issue_x0020_Status').value())).replace(/\-/g, "%252D"); window.location.hash = "InplviewHash" + $(".related-issues [webpartid]").attr("webpartid") + '=FilterField=Issue_x0020_Status-FilterValue=' + value; }
Here you will need to replace “Issue_x0020_Status” with the appropriate Internal Name(s), for details on this see the Lookup field section above.
Single-value Client-mode people picker field
In this case we want to filter our issues based on the Assigned To field:
This is our code:
setHash(); fd.field('Assigned_x0020_To').change(setHash); function setHash(){ var value = ""; //if the people picker field really has a value, get it if (fd.field('Assigned_x0020_To').value() && fd.field('Assigned_x0020_To').value()[0] && fd.field('Assigned_x0020_To').value()[0].DisplayText){ var value = encodeURIComponent(escape(fd.field('Assigned_x0020_To').value()[0].DisplayText)).replace(/\-/g, "%252D"); } window.location.hash = "InplviewHash" + $(".related-issues [webpartid]").attr("webpartid") + '=FilterField=Assigned_x0020_To-FilterValue=' + value; }
As with the previous field types you’ll need to swap “Assigned_x0020_To” for the appropriate Internal Name value(s), see the Lookup section for more detail.
Other fields
You can utilize this feature with pretty much any type of field, but you need to know how to retrieve the value of the field. For a list of field types and corresponding ways to retrieve their values check this page: http://formsdesigner.blogspot.com/2013/04/getting-and-setting-sharepoint-form.html.
Explanation
To make this work we are utilizing the SharePoint URL hash feature that is used with SharePoint 2013 views in the client-side rendering mode.
Have a look at this sample URL:
https://mywebsite.com/Lists/Issue/fd_Item_EditForm.aspx?ID=20#InplviewHash3f6a312c-cd80-4e64-be27-075b976ced40=-FilterField1=Parent-FilterValue1=20-FilterField2=Issue_x0020_Status-FilterValue2=In Progress
What our code samples do is set the “InplViewHash” part of the URL together with its FilterField and FilterValue values, which is what tells the related items control to sort the list. Simple as that.
Hi Dmitry, thanks a lot for the post, the solution works perfectly when i only have one related list, however i can't get it to work when i have multiple related lists, for example i have a tab called "Related" and i placed 3 different related lists in an accordion control inside the related tab. how do i get this to work for them all? I tried to open the link in your post: https://mywebsite.com/Lists/Issue/fd_Item_EditForm.aspx?ID=20#InplviewHash3f6a312c-cd80-4e64-be27-075b976ced40=-FilterField1=Parent-FilterValue1=20-FilterField2=Issue_x0020_Status-FilterValue2=In Progress
ReplyDeletehowever it's not working. Thanks in advance for your response.
Hi Mohamed,
DeleteThe solution should work for multiple Related Items as well. You only need to assign different CSS-classes to those controls and use them in JavaScript as appropriate.
Hi Dmitry,
DeleteThanks a lot for your response, here's the code that i'm using, i only added a couple of lines to set the URL's hash with a different CSS class, however it's not working yet.
//first filter on page load
setHash();
//and attach an on-change handler that will call the filtering function wherever the value of the field changes
fd.field('Project').change(setHash);
//this is the actual function that filters the list
function setHash(){
//get value
var value = fd.field('Project').control('getSelectedText');
if (value == "(None)") {
value = "";
}
value = encodeURIComponent(escape(value)).replace(/\-/g, "%252D");
//set the URL’s hash value. An explanation on this is at the end of the article.
window.location.hash = "InplviewHash" + $(".rel-tasks [webpartid]").attr("webpartid") + '=FilterField=Project-FilterValue=' + value;
window.location.hash = "InplviewHash" + $(".rel-proj [webpartid]").attr("webpartid") + '=FilterField=Title-FilterValue=' + value;
window.location.hash = "InplviewHash" + $(".rel-opp [webpartid]").attr("webpartid") + '=FilterField=Project-FilterValue=' + value;
}
Hi,
DeleteYou need to concatenate the hash instead of replacing it in the end of your script:
var hash = "InplviewHash" + $(".rel-tasks [webpartid]").attr("webpartid") + '=FilterField=Project-FilterValue=' + value;
hash += "#InplviewHash" + $(".rel-proj [webpartid]").attr("webpartid") + '=FilterField=Title-FilterValue=' + value;
hash += "#InplviewHash" + $(".rel-opp [webpartid]").attr("webpartid") + '=FilterField=Project-FilterValue=' + value;
window.location.hash = hash;
Thanks a lot, you're the man :) works like a charm. Merry Christmas and happy new year Dmitry.
DeleteDoes the sample code for lookups require the cross-site lookup application?
ReplyDeleteIs there a way to make these work on a new form rather than an edit form?
This comment has been removed by the author.
ReplyDeleteHi Dmitry, is it possible if we filter the related items based on multiple values e.g. Issue Status, Ticket No etc ? Thanks in advance.
ReplyDeleteMorning Luke
DeleteDid you get a solution for this?