As typical in SharePoint, there is usually more than one way to solve an issue. The first way to create an A-Z quick filter is to "hard wire" the solution based on views created when you manually filter a column. For more information on how to do this, refer to:
- SharePoint StackExchange's solution: Page a list via A-Z
- The Salty PC's solution: Create an A-Z quick filter web part
However, JavaScript is the more versatile solution. The plus side of using JavaScript is that you can re-use this code on any site and any list without rewriting the code.
The solution below is applicable to SharePoint 2010 and 2013, but can be applied to SharePoint 2007 using the code at Alphabetical List View Quick Filter by Boris Gomiunik. If you view Gomiunik's site, he goes into the nitty gritty details of the javascript, so I won't repeat his actions, as he does a great job explaining it!
This post provides the instructions on how to implement the solution.
- Create your SharePoint list.
- Open Notepad, copy the code below, and paste it into a new file. (Thanks to Aleksandr for updating the code to SharePoint 2010/2013 requirements, as posted on PasteBin at Nilldot: SharePoint list alphabetic order.)
- Save this file as .txt and upload it to the Site Assets library on the site where your list is saved. You may have to click Site Contents on the quick launch menu on the left to see the Site Assets library.
- Right click on the file now on SharePoint, and click Copy shortcut to get the URL of the file.
- On the page of the list you credit in Step 1, click the cog in the upper-right corner of the page, and click Edit page.
- Click Add a Web Part.
- In the Categories window, click Media and Content. Select Content Editor, and click Add.
- Click the drop-down arrow on the new Content Editor Web Part and select Edit Web Part.
- In the Content Editor properties box, paste the URL for the *.txt file you copied in Step 3 in the Content Link field. Click Test Link to ensure the *.txt file opens. Click OK.
- Click the Page tab and click Stop Editing.
- Activate the list menu by clicking somewhere in the list area (below the Content Editor Web Part, but not on a list link).
- Click the List tab, and List Settings.
- Under the Columns section, click Create column.
- Name the column FL (this is linked to the code line var filterField = "FL" above and stands for first letter). For the Column type, select Calculated (calculation based on other columns). In the Formula field, type =LEFT and double click the column name (in the Insert Column box) from which you want to grab the first letter. Add parentheses around the outside of the column name brackets, and remove the brackets. Click OK.
For instance, in this example, I want to filter by the first letter of the Term column, so my formula looks like this: - Go back to the list page and test your alphabetical quick filter links!
- <script type="text/javascript">
- 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;
- }
- var filterField = "FL";
- var filterValuesDelimiter = " - ";
- 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");
- var selectedValueStyle = "font-weight: bold;";
- var filterDivStyle = "margin: 5px; font-size: 15px;";
- var filterLinks = new Array();
- for (var i = 0; i < filterValues.length; i++) {
- filterLinks.push('<a ' + (qs("FilterValue1") == filterValues[i] ? 'style="' + selectedValueStyle + ' ' : '') + 'href="' + document.location.pathname + '?FilterField1=' +
- filterField + '&FilterValue1=' + filterValues[i] + '">' + filterValues[i] + '</a>');
- }
- document.write('<div style="' + filterDivStyle + '">' + filterLinks.join
- (filterValuesDelimiter) + '</div>');
- </script>
This is EXACTLY what I needed. This is the best walkthrough ever. And your code worked great! Thanks so much.
ReplyDeleteDo you do SharePoint 2013 support or do you just blog?
I second this! It's fantastic! So easy!
DeleteYay! I'm glad it helped!
DeleteI'm so glad it helped you! Right now, I just blog as I have three jobs, so I stay pretty busy. But feel free too reach out to me for help. I have more topics I need to add to the blog, so maybe I have a solution already.
ReplyDeleteI'm so glad it helped you! Right now, I just blog as I have three jobs, so I stay pretty busy. But feel free too reach out to me for help. I have more topics I need to add to the blog, so maybe I have a solution already.
ReplyDeleteWow I'm sure you stay busy. Thanks, I'll probably take you up on that help :) Have a great week!
ReplyDeleteQuick question -- what would you suggest doing for instances where the first letter is a number or symbol? trying to use this for a list of companies, and some of the names do not begin with letters. Any help would be greatly appreciated!
ReplyDeleteIdeally, it would be one section for all numbers, rather than a filter for each number
DeleteAs a start, I created an additional calculated column to switch all numbers to # and tried adding # to the array, but for some reason it is not reading # in the filter.
DeleteMaybe you have found a solution already, but if you wanted to include numbers, you need to change the Script to include the numbers.
DeleteIf you look at the blue text you pasted to the text file, you see the alphabet - that is where you add the numbers in the same format:
("A","B", ... ,"Z", "1", "2", ..., "9", "0");
Important to note that the list in sharepoint will show the letters first and then digits, but you can swap the order by changing the order in the script.
Obviously if you do not want the letters, just delete them from the script.
Similar to that you could extend the filter for the actual names: ("ACME", "APPLE", "IBM",...); but you would have to figure out a way to properly split those names into the FL column in sharepoint (like the =LEFT(Term) above splits the left most character into the FL column).
You could try =LEFT(Term, SEARCH(" ",Term,1)) but you would need the sharepoint entries to contain a space after the company name.
I am not sure it will totally work and you might have to fiddle around with that. Have a look at the official site as well: https://support.office.com/en-us/article/Split-text-into-different-columns-with-functions-49ec57f9-3d5a-44b2-82da-50dded6e4a68
This comment has been removed by the author.
ReplyDeleteThis works pretty well and enables a tech savvy person to start playing around with the system.
ReplyDeleteWhat I was wondering, is if there is a way to include a reset for the filter. As in a filter value that includes everything regardless of content.
It feels like there is an easy answer, but I can't nail it.
This comment has been removed by the author.
DeleteI created an "ALL" link to reset the filter before the for loop. I'm having a hard time pasting that script here but essentially take the filtersLink.push line from within the forloop, paste it above the forloop starts and after document.location.pathname add "+ '">ALL<\/a>');" to finish the line. You'll have to remove the extra '\' before the /a>. I threw that in there to get this to take the HTML tag
DeleteWould you be able to share your code for the "All" link ? Thanks.
DeleteI used this:
ReplyDelete=IF(ISNUMBER(INT(LEFT(Term,1))),"1",LEFT(Term,1))
to make my FL column contain the first letter OR contain a 1 if the first value is a number. Then I just added a "#" after A-Z that has the URL pointing to FieldValue1=1.
This won't work with special characters but you could do nested IF statements with ISNONTEXT I'm guessing
Would you be able to email me the code you're referring to for the 'All' link?
ReplyDeleteIn case anyone else is interested ... I was able to add the "All" link ... Follow Christel's steps above. Add an additional column (Drop down .. Default value "All") to your list and use the code below.
ReplyDelete--------------------------------------------------------------------------------
<\\script type="text/javascript">
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;
}
var AllField = "All";
var AllValuesDelimiter = " - ";
var AllValues = new Array
("All -");
var selectedValueStyle = "font-weight: bold; ";
var AllDivStyle = "margin: 5px; font-size: 28px; ";
var AllLinks = new Array();
for (var i = 0; i < AllValues.length; i++) {
AllLinks.push('<\/a ' + (qs("AllValue1") == AllValues[i] ? 'style="' + selectedValueStyle + ' ' : '') + 'href="' + document.location.pathname + '?AllField1=' +
AllField + '&AllValue1=' + AllValues[i] + '">' + AllValues[i] + '<\/a>');
}
document.write('<\/div style="font-size: 28px !important;display: inline !important; float: left !important; padding-right:3px; " + ' + AllDivStyle + '">' + AllLinks.join
(AllValuesDelimiter) + '<\/div>');
//--------------------------------------------
var filterField = "FL";
var filterValuesDelimiter = " - ";
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");
var selectedValueStyle = "font-weight: bold;";
var filterDivStyle = "margin: 5px; font-size: 28px;";
var filterLinks = new Array();
for (var i = 0; i < filterValues.length; i++) {
filterLinks.push('<\/a ' + (qs("FilterValue1") == filterValues[i] ? 'style="' + selectedValueStyle + ' ' : '') + 'href="' + document.location.pathname + '?FilterField1=' +
filterField + '&FilterValue1=' + filterValues[i] + '">' + filterValues[i] + '<\/a>');
}
document.write('<\/div style="font-size: 28px !important; color: #002b52 !important;display: inline !important; float: left !important;" + '+ filterDivStyle + '">' + filterLinks.join
(filterValuesDelimiter) + '<\/div>');
<\/script>
Hi
ReplyDeletethanks for this. It seems great. I did what you said and finally managed to get the alphabetic search display on my page
Below it is a list I need to seach from alphabetically.
But I get the below error when I click on an alphabet ----
Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Microsoft SharePoint Foundation-compatible HTML editor such as Microsoft SharePoint Designer. If the problem persists, contact your Web server administrator.
Correlation ID:da3af39d-40c6-4000-0cbf-fdb247064042
On SharePoint 2016, I was not able to get my site to work until I changed the FL column calculation to =LEFT([Full Name]), hope this helps someone else:-jmw
ReplyDeleteI am using SharePoint 2016 and added the code above as follows:
ReplyDeletevar filterField = "LEFT([Full Name]),";
I get the A to Z text but I get the error below.
I have tried both Content Editor and Script Editor. Same error.
Any suggestions anyone?
Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Microsoft SharePoint Foundation-compatible HTML editor such as Microsoft SharePoint Designer. If the problem persists, contact your Web server administrator.
Correlation ID:8bd02d9e-c0fa-d010-330f-0405a82d4cfb
Hi all, Thanks for the tip above for SharePoint 2016. I edited the line as follows:
ReplyDeletevar filterField = "LEFT([Full Name]),";
I get the A to Z text but I still get the error mentioned above. I tried both Content Editor and Script Editor, same error. Any suggestions anyone? Thanks.
Hi,
ReplyDeleteIs it posible to use this for a libary? I can't get it to work!
It will not work for a library. The best thing to use for a library is metadata (columns of data) to sort by. If your library is very large, it may mean that you should consider splitting out your files into more than one library.
ReplyDeleteDoes this work for a library view? I am getting this error:
ReplyDeleteOne or more field types are not installed properly. Go to the list settings page to delete these fields.
Correlation ID:483e4a9e-50e0-5000-b68c-f98c3c953da0
I don't believe this will work for a library.
DeleteHey! Thanks for the walkthrough! It is really great.
ReplyDeleteDoes anyone have an idea how to gray the letters that have no list entry?
You're welcome. That's a great question and would be a great addition. Hopefully someone knows.
DeleteHi Christel,
ReplyDeleteJust wanted to say thanks very much for the post. Also the additional contributors who fixed the syntax for SP2016 - excellent collaboration - I hope to use this for a People Search list that I am working on and initial tests with the code are great.
You're welcome! I'm so glad it will be helpful!
ReplyDeleteThank you! I'm glad it is helpful!
ReplyDeleteGreat work and thanks for sharing. I have a requirement of bringing multiple documents from multiple libraries and want them all to be viewed using A-Z on a single page. Is this possible with your solution?
ReplyDeleteThank you Christal for the Content!
ReplyDeleteI have a document library which includes files and folders. This script works well with filis but not for those files which is inside the folders. Any idea how I can change script to make it work?
Hey there! I'm trying to get this to work, but seem to be getting the following above my list?
ReplyDelete<%@ Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=16.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Assembly Name="Microsoft.Web.CommandUI, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="ApplicationPages" Namespace="Microsoft.SharePoint.ApplicationPages.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> -
No A-Z at all. :(
DeleteNow getting:
ReplyDeleteCannot retrieve the URL specified in the Content Link property. For more assistance, contact your site administrator.
HI, Thanks for the code. Very helpful. QQ - When I click on the Alphabet, list is filtered, but the code refreshes the page and renders me to the top of the page. I need the control back to be at the list
ReplyDeleteHello thanks for the code.
ReplyDeleteIt works on my blogspot page.
But "how can I cal a specific category" of my blogger site?
Thanks
This comment has been removed by the author.
ReplyDelete