5. Alphabetical List View Quick Filter
This article the first of The Power of Content Editor WebPart series. Other parts:
This is an easy kind-of hack where we’ll use SharePoint’s URL. Our goal is to have a small section above the list view that will filter the list according to first letter of every item in the list as seen on the screenshot below.
This comes in handy with large lists. In our example we’ll continue to work on the list of customers that we’ve already "pimped" with the quick search functionality.
Let’s take a look at filters
For this purpose we’ll take a look at our list – what happens when we use the list filter:
The page URL gets additional parameters: View, FilterField1 and FilterValue. For working in list view you can easily skip the View parameter and the filter will still work.
So FilterField1 determines according to which column the list should be filtered (we have to use column internal names) and FilterValue1 parameter sets the filter value. And yes, since they both have number 1 added to them, you can add multiple filters (FilterField2, FilterValue2, FilterField3, …).
Let’s do it
Great. So now we can take advantage of this. Because we don’t want to have each unique value in the filter options we need an additional column with the first name of a customer. The column must be displayed in the view in order for filter to work. For the column to be as discrete as possible, I recommend using a short column name, something like FL (first letter). Let’s go ahead and add the column.
The column should be of type "Calculated" and the formula is simple:
=LEFT([LastName])
The value in square brackets is the display name of the column. When entering the formula the square brackets should also be present. All the settings for a new column are presented below:
And as mentioned the column should be in the view where we’ll add the filter.
Time for CEWP and JavaScript
OK. Now let’s insert the CEWP and JavaScript. After insertion, and linking to the external content file the "Hello world" is ready:
We could do this entirely without the JavaScript. All we’d need is to enter hyperlinks like below:
A
B C
And that would just work fine.
But going on the wild side and to raise the complexity of this article I want to make this a bit more dynamic and page-independant. In the code above the problem is that this is bound to the AllItems.aspx page. What if you’d want to re-use the code somewhere else? Plus you have to do a lot of copy-paste and corrections for minor items.
So JavaScript to the rescue. To avoid repetitive typing we’ll create a JavaScript array of all possible values for filter and build the links in a for loop. So first let’s define an array of possible filter values.
Next we create a loop for all of the values to create the filter just before the tag:
for (var i = 0; i < filterValues.length; i++) { document.write("" + filterValues[i] + " "); }
And that would do the trick. We’d end up with a filter:
By using the document.location.pathname in the script we’ve removed strict binding to any particular page.
That’s it. If you’re satisfied with a filter like that you can stop reading right here. If you wish to "pimp" the filter a bit more, continue reading.
Expanding our example
Now let’s add a bit more configurability. We wish to be able to configure a delimiter between the filter values and we wish to be able to configure the filter column. So immediately after the first line (
var filterField = "FL"; var filterValuesDelimiter = " : ";
And we’ll modify the for loop to be writing links into a new array instead of directly to the document. So we modify the loop to take into account the filter field and take out the delimiter at the end. At the end we’ll use a join function for an array of links to add the delimiter between and write to the document.
So we replace entire "for" loop in the code with the following:
for (var i = 0; i < filterValues.length; i++) { filterLinks.push(""); } document.write(filterLinks.join(filterValuesDelimiter));
By now the result should look something like the following:
And the first three lines of code give you configuration capabilities for filter field, filter values and filter values delimiter.
Neat. Want to complicate even more? Wouldn’t it be nice if the filter would highlight the selected value? And let’s make the highlighted style also configurable. At the beginning of the script first we need to declare a configuration variable for selected value.
var selectedValueStyle = "font-weight: bold;";
Now we need to know which filter value is selected. How do we get to know that? In URL we need to read the value of the "FilterValue1" parameter. Since JavaScript has no built-in function for this we need a supporting queryString function. I’ve published one on my JavaScripts Library. It’s the qs function. We’ll insert this function before any JavaScript code, so immediately after the first line. But because we already use the iterator i in the for loop we need to fix the i iterator in the qs function.
function qs(paramName) { var args = document.location.search.substring(1).split("&"); for(j = 0; j < args.length; j++) { nameValues = args[j].split("="); if(nameValues[0] == paramName) return nameValues[1]; } return null; }
And now we update the for loop in our script to be checking if the value of the FilterValue1 parameter equals the filter value from the array. We do this by injecting the shorthand if statement like the one below:
(qs("FilterValue1") == filterValues[i] ? "style="" + selectedValueStyle + "" " : "")
in the part where the links are being constructed (
for (var i = 0; i < filterValues.length; i++) { filterLinks.push(""); }
And as a final touch let’s not have those links jammed to the upper left corner. We’ll wrap a layer around with a configurable style. So at the beginning of our script we add another parameter:
var filterDivStyle = "margin: 5px;";
and we update the "document.write" line to add the surrounding div.
document.write("
And the final result looks like this (having applied filter for "A":
The full code is below:
And because results can be configurable, you can easily vary the look of the alphabet filter. For example a configuration like:
var filterField = "FL"; var filterValuesDelimiter = "-"; var selectedValueStyle = "border: 1px black solid"; var filterDivStyle = "margin: 5px; font-size: 15px;";
would result in
Happy scripting everyone!
Other articles from this series:
[…] 5. Alphabetical List View Quick Filter […]
This is great. I’ve been looking for something exactly like this and it will work for my needs.
One question I have would be is there a way to add another link in the “abcd…” array that would clear the filter out? I have messed around with it a little bit, but now knowing what I am doing does not help. Thanks.
Probably something simple, but is there a way to add an “All” option that would clear the filter?
Yep. Just add the hyperlink to the same page you’re viewing without the “FilterField1” and “FilterValue1” parameters.
Awsome i will try this . but you think it will work with sharepoint 2010 also .
either way i think its million dollar blog if works
When I add this to a SharePoint 2010 site, nothing is displayed. I don’t get an opportunity to select any of the A to Z filter values. Somehow the document.write function is not working.
I cannot seem to get this to work. I am working on SharePoint 2010, everything is setup as above.I have copied the code above onto my CEWP HTML Source….Is there anything else I need to do to get this to work?
Is there a reason why this wouldn’t work with WSS 3.0? When I try it in WSS 3.0 nothing happens.
The sample is made also in SharePoint 3. It should be working. Maybe you can debug if the script starts by putting an alert() at the beginning of your script.
Tested . it works with Sharepoint2010 . document.write is working . What it does every time i edit the page and save it back it create another row of filters. that can be some thing with the code but it works fine on sp2010.
very useful solution but I have problems to configure it correctly. With the manually entered links everythinks works fine, but with the javascript code I see no links to klick on. I tried it out with Sharepoint 2007 and 2010 german server. Do you have any hints for me, was it wrong?
Thanks
britta
Hi, working in WSS 3.0, but unable to get this to work. I have tracked the problem to the construction of the href reference, I can get the concatenated string document.location.pathname + “?FilterField1=FL&FilterValue1=” + filterValues[i], and this displays in the CEWP, one for each letter as expected. If I leave the off and put in single quotes again this is displayed in the CEWP with no problem, although the href fails to put the string into quotes as needed. The moment that I try to double the quotes up the CEWP goes blank. Any clues as to what is going on?
Sorry, the web page has deleted the “greater than a less than” and “greater than /a less than” from my third sentence
Same as Les, but in WSS3.0. I can’t get this to work. I made same as for Quick Search, but CEWP doesn’t render anything in webpart! It is blank! It works with A but final code doesn’t. Any ideas?
Problem solved. If you use single quotes, instead of double quotes, for all the javascript instructions and leave the HTML instructions as double quotes then the code works fine. e.g. replace “HREF”” with ‘HREF”‘. It also makes the code more easily understood for a newbie like me!
[…] could do this entirely without the JavaScript. All we’d need is to enter hyperlinks like below: view plaincopy to […]
WOW !!! good idea simple and clear !!!
It’s not working for me either – it’s just blank. I’m using SP 2010 but tried it on 2007 and still no luck.
I created the calculated field and named it FL. I verified that it is pulling the first letter and I have it shown in the view on the page. Besides that, is there something else we need to do?
It doesn’t work in 2010 for me either. Tried IE version modes 7, 8, 9.
For those trying to make it work on Sharepoint 2010, I was able to make it work by using different quote operators for actual writing (i.e. ‘) and for other purposes. Basically using “<div style="" was not well recieved, but changing it to '<div style="' solved the problem. I did get the same issue as umar though. Did not find a fix for that so far.
I also found the solution to umar’s issue. Basically you need to write your script in a separate file which you upload to the sharepoint site and then link to in the Content Editor webpart. It’s explained in the link below:
http://stackoverflow.com/questions/5020573/sharepoint-2010-content-editor-web-part-duplicating-entries
I cannot seem to get this to work. I am working on SharePoint 2007, everything is setup as above.I have copied the code above onto my CEWP HTML Source….Is there anything else I need to do to get this to work? Do you have a YOUTUBE video that is showing the step by step this is driving me CRAZY!! 🙂 help
var filterValues = new Array(“A”,”B”,”C”,”D”,”E”,”F”,”G”,”H”,”I”,”J”,”K”,”L”,”M”,”N”,”O”,”P”,”Q”,”R”,”S”,”T”,”U”,”V”,”W”,”X”,”Y”,”Z”);
for (var i = 0; i < filterValues.length; i++) {
document.write('<a href="' + document.location.pathname + '?FilterField1=&FilterValue1=’ + filterValues[i] + ‘”>’ + filterValues[i] + ‘ ‘);
}
This is what the script should look like in order for it to work properly in a .js file you save to the site assets or layouts folder.
How can we set only the list webpart to be refreshed without the whole page geting reloaded.
[…] une liste par les lettres de l’alphabet de l’objet principal. J’ai eu recours à un article ( en anglais) très bien rédigé qui m’a beaucoup […]
You can also try this approach
http://nazishqasim.wordpress.com/2012/11/26/using-data-view-web-part-to-achieve-a-z-index-listings/
have you got this working guy in 2010 ?
Thanks
Hi guys, here is a version wokring for 2010
http://pastebin.com/QVeuuQmP
I have changed column’s name to FLoUN though
Hope this helps
Thanks for this solution! Do you mind if I link back to you to attribute information?
Oh, the only thing I could not get to work is the “All” filter. How exactly is that written in the script?
Hi – This is fantastic, thank you for sharing…..Just wondering if anyone has an example of how “All” code can be returned in this script?