none
Is there a way to intercept a SharePoint Search request

    Question

  • I would like to be able to intercept an end-user search, augment the search terms, and then allow the search to execute normally within SharePoint.  Is there some sort of Search Event handler I can tap into to accomplish this?
    Tuesday, April 30, 2013 9:46 PM

Answers

  • If it's just manipulating the search query for a single search box (I.e. on an Enterprise Search page), you can easily create a new webpart that inherits from Microsoft.SharePoint.Portal.WebControls.SearchBoxEx, and override the JavaScript function called when the user clicks the search button with your own function (which would augment the search terms). I did this for a people search page.

    E.g.

    Create a new webpart that inherits from Microsoft.SharePoint.Portal.WebControls.SearchBoxEx. Override the CreateChildControls method, essentially just wrapping the search control with a div that has a custom ID, and outputting a script that will run when the page loads, updating the JavaScript function that gets called when the user clicks on the search button.

    WebPart Code

    protected override void CreateChildControls() { this.UseSiteDropDownMode = false; this.ChromeType = PartChromeType.None; this.GoImageActiveUrl = "/_layouts/images/gosearchhover30.png"; this.GoImageUrl = "/_layouts/images/gosearch30.png"; this.DropDownMode = DropDownModes.HideScopeDD; this.DropDownModeEx = DropDownModesEx.HideScopeDD; this.QueryPromptString = String.Empty; this.SearchResultPageURL = SearchResultsUri; //This is a property on the webpart this.AdvancedSearchPageURL = SearchResultsUri; //This is a property on the webpart //Wrap a div around the base search control that get's rendered, so that we can easily access the search //controls <a> elements it once it's loaded Controls.Add(new LiteralControl("<div id=\"searchControlContainer\">")); base.CreateChildControls(); EnsureChildControls(); Controls.Add(new LiteralControl("</div>")); //Write a script to the page that will update the JavaScript function called when a user clicks the search button. Controls.Add(new LiteralControl(String.Format("<Script type=\"text/javascript\">updateSearchHrefScript('{0}','{1}','{2}')</script>", m_searchKeyWordTextBox.ClientID, SearchResultsUri, SearchScope))); }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);    
        ClientScriptManager cs = Page.ClientScript;
        if (!cs.IsClientScriptIncludeRegistered("jquery"))
        {    
            cs.RegisterClientScriptInclude(this.GetType(), "jquery", "/_layouts/incejs/jquery-current.js");
        }
        if (!cs.IsClientScriptIncludeRegistered("incesearchparts"))
        {        
            cs.RegisterClientScriptInclude(this.GetType(), "incesearchparts", "/_layouts/incejs/ince-searchparts.js?v4");
        }
    }


    JavaScript file (assumes jQuery is loaded as well)

    function updateSearchHrefScript(keywordElement, resultsPage, scope) 
    {    
    	//Select the <a> element inside the container div, and change the function that is called when a user clicks the search button
        $('#searchControlContainer a').each(function(index) {
            if (this.title == 'Search') {
                var ref = "javascript:customSearchFunction('" + keywordElement + "','" + resultsPage + "')";
                this.href = ref;
            }
        }
        );
    }
    
    //The custom search function, that appends an aphosphe to the search term, and sets the scope to people
    function customSearchFunction(keywordElement, resultsPage) {
        element_name = keywordElement;
        var i = document.forms[0].elements[keywordElement].value;
        i = i.replace(/\s*$/, "");
        var b = "?s=People";
        if (i == "") 
        {
            alert("Please enter one or more search terms.");
            if (null != event) {
                event.returnValue = false;
                return false;
            }
            else
                return;
        }
        b += "&k="+i+"*";
        window.location = resultsPage + b;
        try {
            if (null != event)
                event.returnValue = false;
        }
        catch (s) {
        }
        return;
    }


    Regards, Matthew
    MCPD | MCITP
    My Blog
    Please remember to click "Mark As Answer" if a post solves your problem or "Vote As Helpful" if it was useful.

    • Marked as answer by Tx_Ryan Monday, May 06, 2013 3:12 PM
    Thursday, May 02, 2013 11:54 AM

All replies

  • Hi Tx,

    How about hide the search box for the “end-user” and also limit “end-user” to access search site?

    Thanks & Regards,
    Emir


    Emir Liu
    TechNet Community Support

    Thursday, May 02, 2013 9:44 AM
  • If it's just manipulating the search query for a single search box (I.e. on an Enterprise Search page), you can easily create a new webpart that inherits from Microsoft.SharePoint.Portal.WebControls.SearchBoxEx, and override the JavaScript function called when the user clicks the search button with your own function (which would augment the search terms). I did this for a people search page.

    E.g.

    Create a new webpart that inherits from Microsoft.SharePoint.Portal.WebControls.SearchBoxEx. Override the CreateChildControls method, essentially just wrapping the search control with a div that has a custom ID, and outputting a script that will run when the page loads, updating the JavaScript function that gets called when the user clicks on the search button.

    WebPart Code

    protected override void CreateChildControls() { this.UseSiteDropDownMode = false; this.ChromeType = PartChromeType.None; this.GoImageActiveUrl = "/_layouts/images/gosearchhover30.png"; this.GoImageUrl = "/_layouts/images/gosearch30.png"; this.DropDownMode = DropDownModes.HideScopeDD; this.DropDownModeEx = DropDownModesEx.HideScopeDD; this.QueryPromptString = String.Empty; this.SearchResultPageURL = SearchResultsUri; //This is a property on the webpart this.AdvancedSearchPageURL = SearchResultsUri; //This is a property on the webpart //Wrap a div around the base search control that get's rendered, so that we can easily access the search //controls <a> elements it once it's loaded Controls.Add(new LiteralControl("<div id=\"searchControlContainer\">")); base.CreateChildControls(); EnsureChildControls(); Controls.Add(new LiteralControl("</div>")); //Write a script to the page that will update the JavaScript function called when a user clicks the search button. Controls.Add(new LiteralControl(String.Format("<Script type=\"text/javascript\">updateSearchHrefScript('{0}','{1}','{2}')</script>", m_searchKeyWordTextBox.ClientID, SearchResultsUri, SearchScope))); }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);    
        ClientScriptManager cs = Page.ClientScript;
        if (!cs.IsClientScriptIncludeRegistered("jquery"))
        {    
            cs.RegisterClientScriptInclude(this.GetType(), "jquery", "/_layouts/incejs/jquery-current.js");
        }
        if (!cs.IsClientScriptIncludeRegistered("incesearchparts"))
        {        
            cs.RegisterClientScriptInclude(this.GetType(), "incesearchparts", "/_layouts/incejs/ince-searchparts.js?v4");
        }
    }


    JavaScript file (assumes jQuery is loaded as well)

    function updateSearchHrefScript(keywordElement, resultsPage, scope) 
    {    
    	//Select the <a> element inside the container div, and change the function that is called when a user clicks the search button
        $('#searchControlContainer a').each(function(index) {
            if (this.title == 'Search') {
                var ref = "javascript:customSearchFunction('" + keywordElement + "','" + resultsPage + "')";
                this.href = ref;
            }
        }
        );
    }
    
    //The custom search function, that appends an aphosphe to the search term, and sets the scope to people
    function customSearchFunction(keywordElement, resultsPage) {
        element_name = keywordElement;
        var i = document.forms[0].elements[keywordElement].value;
        i = i.replace(/\s*$/, "");
        var b = "?s=People";
        if (i == "") 
        {
            alert("Please enter one or more search terms.");
            if (null != event) {
                event.returnValue = false;
                return false;
            }
            else
                return;
        }
        b += "&k="+i+"*";
        window.location = resultsPage + b;
        try {
            if (null != event)
                event.returnValue = false;
        }
        catch (s) {
        }
        return;
    }


    Regards, Matthew
    MCPD | MCITP
    My Blog
    Please remember to click "Mark As Answer" if a post solves your problem or "Vote As Helpful" if it was useful.

    • Marked as answer by Tx_Ryan Monday, May 06, 2013 3:12 PM
    Thursday, May 02, 2013 11:54 AM
  • Thank you Matthew, that is helpful.  I had done some research after posting the question and extending the SearchBoxEx was the path I was going down.

    But I'm not confident that I'll be able to do what I need to do using only javascript.  I need capture the keyword(s) that were entered by the user and pass them along to another piece of software (via REST API), that piece then returns to me a JSON response which may provide additional search terms which I will then add to the original set of query terms and finally allow SharePoint to execute the search normally.

    Appreciate any additional tips on programmatically manipulating the query terms.

    Regards,
    Ryan

    Thursday, May 02, 2013 5:22 PM