Tagged: advanced search

Using jQuery to Build a More Intuitive Advanced Search Experience in SharePoint 2010 – Part 2: Advanced.aspx

Update 3/28/12: If you have already downloaded the code for this solution, please download it again! Several bugs were fixed in this latest release.

This entry is part 2 of a multi-part blog series on enhancing the advanced search experience for SharePoint 2010 end users using jQuery. Part 1 may be found here. I will link to subsequent entries in this series from here once they have been written.

In part 1 of this series, I wrote about what I believe are some serious flaws with the way advanced searches are handled out of the box in SharePoint 2010. If you so much as follow one navigational link from the search results page after performing an advanced search, then decide you wish to change your advanced search parameters in any way, you are forced to re-enter all your search parameters on an empty advanced search page, even though the page URL contains a query string parameter that includes everything you searched for!

Enter jQuery

I know I can use JavaScript to parse parameters from a query string. This post details one of the most elegant ways I have seen to do this. Since the advanced.aspx URL already includes all of my advanced search criteria (in the k query string parameter), I will use this method to parse that value. Once I have that value, through a combination of jQuery and JavaScript RegExp (regular expression) parsing, I can take all of my search criteria and repopulate the appropriate text boxes, check boxes, and dropdowns so that the end user doesn’t have to needlessly re-enter this information.

The key to being able to populate the appropriate controls is knowing the IDs of each of the controls on the advanced search page. I can then use jQuery to set the values of the respective text boxes and dropdowns using the .val() method for text boxes and the .prop() method for check boxes and dropdowns (although .val() can also be used for setting the selected value in a dropdown, I encountered a problem with the dynamically populated dropdowns in the property restrictions area that required me to set the selectedIndex property of those dropdowns instead). Using my trusty F12 developer tools, I was able to determine how the controls on the advanced search page are named. The image below displays the last part of the “name” value associated with each of these controls. I can then use attribute selectors to choose each specific element (based on the name of that element ending with the given string) and set its value accordingly.

Deploying jQuery and this Script

A thorough discussion of how best to deploy jQuery in a given site collection is beyond the scope of this blog post. Suffice it to say, my preferred approach for deploying jQuery is as a sandboxed solution that includes a jQuery module. Jan Tielens outlines this solution in greater detail here. Keep in mind that you can use any method you would like to deploy jQuery on your Search Center site as long as you properly reference the location of your jQuery script on the advanced.aspx page. The functionality I have created for this blog post requires jQuery 1.6 or above.

Keep in mind that the advanced.aspx page in a SharePoint Search Center is a fully customizable web part page. With that in mind, once you have deployed jQuery in your site collection and referenced it from this page, you can deploy this script in a Content Editor Web Part and be good to go. The general algorithm followed by this script is:

  1. Store the k query string parameter in a variable, k.
  2. Look for regular expression matches in k for the various keyword searches (ALL(), ANY(), “”, and NONE()). Populate the appropriate text boxes with the words found.
  3. Look for regular expression matches in k for the various language filters (DetectedLanguage).
  4. Look for regular expression matches in k for the result type (IsDocument=True or FileExtension=).
  5. Parse out any property restrictions (property, type of match, the text itself, and the and/or operand associated with it). This script should handle the out of the box properties without any issue. It also properly handled the custom mapped properties I had previously configured in my environment (but please feel free to let me know if you run into any specific issues with this script in your environment).

The Solution in Action

Download the script here (it is available as both a standalone text file or an exported Content Editor Web Part) and try it out for yourself. Again, the steps to deploy it are as follows:

  1. Download jQuery 1.6 or greater and deploy it in your environment.
  2. Ensure jQuery is referenced from your advanced search page, advanced.aspx.
  3. Add a Content Editor Web Part to advanced.aspx and reference this script. Alternately, you could import and add the .dwp file that can also be downloaded from the link above.

Let’s try it out!

I’ll start by doing a basic search on my favorite subject, SharePoint!

Here are my results:

Now let’s say I want to filter these results by date. I’ll click the Advanced link.

Nothing special here (yet). The advanced search page knows how to put a simple keyword query’s terms in the “All of these words” text box. Now let’s enhance our search by adding some keyword, language, type, author, and date range restrictions:

Pressing Search yields a new set of search results:

The entire string in the search text box reads:

ALL(sharepoint) ANY(rocks awesome) NONE(stinks) (DetectedLanguage=”en” OR DetectedLanguage=”fr”) (IsDocument=”True”) (Author:customer OR Write>=1/1/12 AND Write<=3/1/12)

At this point, the Advanced link points to javascript:history.back(), so clicking it would bring up the advanced search page just as it was when I submitted my query.

Let’s say I want to change the date range being searched, remove one of the selected languages, and put size and URL restrictions in place. I can manually change the search string to read:

ALL(sharepoint) ANY(rocks awesome) NONE(stinks) (DetectedLanguage=”en”) (IsDocument=”True”) (-Path:SitePages AND Path:contoso OR Write>=3/1/12 AND Write<=3/27/12 AND Size>17000)

Pressing the search button yields the following results:

At this point, the Advanced link now points to advanced.aspx with a messy query string parameter called k. Without this script in place, clicking that link would yield a woefully empty advanced search page:

(As an aside, I find it strange that SharePoint has somehow forgotten how to even parse the “All of these words” keywords!)

But with this script installed, the page “magically” reflects all the parameters of my updated query automatically!

Pretty cool, huh? Try it out (you can download the code in a standalone text file or as an exported Content Editor Web Part) and let me know what you think. Feel free to leave any comments, concerns, or ideas for improvement in the comments. Stay tuned for part 3, where I will use jQuery to enhance the advanced search interface directly on the search results page!

Using jQuery to Build a More Intuitive Advanced Search Experience in SharePoint 2010 – Part 1: Introduction

This entry is part 1 of a multi-part blog series on enhancing the advanced search experience for SharePoint 2010 end users using jQuery. Part 2, using jQuery to enhance the advanced search page advanced.aspx can be found here. I will link to subsequent entries in this series from here once they have been written.

The default advanced search experience in a SharePoint 2010 Search Center (basic or enterprise) has always disappointed me. The interface is clean enough, but the execution and navigation leave a lot to be desired, particularly when end users wish to make changes to the search string from the search results page. Out of the box, performing the different types of keyword searches (ALL of these words, ANY of these words, the exact phrase, etc.) displays the combined SharePoint search syntax for that query in the search box. For instance, if I wanted to find documents that contained ALL of the words SharePoint and awesome, the exact phrase Danny Jessee, ANY of the words rocks or rules, and NONE of the words sad or sorry, I would enter the following in the advanced search page:

And the results (if any) appear on the results page, results.aspx:

As you can see, my advanced query was converted to a single search string where the words I entered in the All of these words: were surrounded with ALL(), the words I entered in The exact phrase: were surrounded with quotation marks, and so on with ANY() and NONE(). The entire string that appears in the search box looks like this:

ALL(SharePoint awesome) “Danny Jessee” ANY(rocks rules) NONE(sad sorry)

This (URL-encoded) string also appears as the k query string parameter in the search results page URL:

results.aspx?k=ALL(SharePoint%20awesome)%20%22Danny%20Jessee%22%20ANY(rocks%20rules)%20NONE(sad%20sorry)

This is intuitive enough for most users to follow, and in fact gives users the opportunity to understand some basic SharePoint search syntax. There’s certainly nothing wrong with that. Things start to get more complex, however, when you start to add property restrictions into the mix. What if, in addition to my search query above, I only wanted to return results that were either modified between March 1 and March 10, or were less than 18000 bytes in size? My advanced search page would now look like this:

And the entire string that appears in the search box on the search results page now looks like this:

ALL(SharePoint awesome) “Danny Jessee” ANY(rocks rules) NONE(sad sorry) (Write>=2/29/12 AND Write<=3/11/12 OR Size<18000)

The URL to my results page now looks like this:

results.aspx?k=ALL(SharePoint%20awesome)%20%22Danny%20Jessee%22%20ANY(rocks%20rules)%20NONE(sad%20sorry)%20(Write%3E%3D2%2F29%2F12%20AND%20Write%3C%3D3%2F11%2F12%20OR%20Size%3C18000)

Although this syntax is still fairly intuitive, I have found that some end users begin to feel intimidated (or at least uncomfortable) as the size of this search string grows (especially when you start nesting clauses in parentheses or have to enclose property values that include spaces in quotation marks).

It gets better!

Did you know that if you include enough advanced search parameters in your query, the string that SharePoint puts in the search box for you is truncated so that it ends in “…” instead?

That’s all well and good, but what if the user makes (what he or she believes to be) a simple change to the search query, such as changing the spelling of a word at the beginning of the search string? Pressing the search button yields the following unpleasant result:

Your query is malformed. Please rephrase your query. Wow.

But back to the problem at hand…

What if I had meant for that query to include any document less than 20,000 bytes in size? I could click the Advanced link to adjust my query. Note that on the first results page displayed after submitting a query from the advanced search page, this link actually invokes the JavaScript method history.back(). On any subsequent results pages (or if you follow a link that returns you to the first result page), the link instead goes to advanced.aspx, repeating the k query string parameter that also exists in the URL to the results.aspx page.

Why does this matter?

When you follow a link that goes to javascript:history.back(), your browser reloads the previous page from its history list. This means that the state of controls on this page is preserved from when the form on that page was submitted and you can easily tweak the search parameters you specified before pressing the Search button. In the case of the example above, clicking the Advanced link on the “no results found” page reloads the advanced search form just as I had left it. But what happens if I change my search parameters in the search box instead?

If I update my search string to be ALL(SharePoint awesome) “Danny Jessee” ANY(rocks rules) NONE(sad sorry) (Write>=2/29/12 AND Write<=3/11/12 OR Size<20000) and press the search button (magnifying glass), the search results page appears (reflecting my updated query). However, since I was not directed to results.aspx from advanced.aspx, the Advanced link will now point to:

advanced.aspx?k=ALL%28SharePoint%20awesome%29%20%22Danny%20Jessee%22%20ANY%28rocks%20rules%29%20NONE%28sad%20sorry%29%20%28Write%3E%3D2%2F29%2F12%20AND%20Write%3C%3D3%2F11%2F12%20OR%20Size%3C20000%29

If I want to change my search parameters again (perhaps by adding another property restriction), clicking this link should enable me to do that with relative ease, right?

WHAT?! I have to enter ALL of my advanced search parameters again? No way!

Sadly, it’s true. Even though the advanced search page URL includes all of my search parameters encoded in the k query string parameter, the out of the box advanced search page has no idea what to do with it! While that definitely explains why SharePoint weakly attempts to hack around this limitation with the history.back() link, it does not satisfy a user base who is accustomed to using search engines that provide a more intelligent advanced search interface. Something needs to be done to address this limitation.

jQuery to the rescue…

In part 2 of this series, I will demonstrate how to use jQuery and JavaScript to parse the k query string parameter on the advanced.aspx page and populate the appropriate controls on that page with the parameters of the active search query. This way, users can feel empowered to change the parameters of their advanced searches without having to re-enter everything on the advanced search page.

In part 3, I will update the results.aspx page itself to display a more intuitive mechanism for inputting and updating search parameters directly on the results page without having to modify a complex search string…all using jQuery and JavaScript!

If you have any ideas about how the default advanced search experience should be improved in SharePoint 2010, or if you have any gripes or frustrations of your own to share, I would love to hear about them in the comments!