﻿// QuickSearch v0.1
// Created by Jan Tielens, http://weblogs.asp.net/jan
// This sample code is provided on an “as is” basis and without warranty of any kind.

// *** Customizable parameters ***
var quickSearchConfig = {
    delay: 500,             // time to wait before executing the query (in ms)
    minCharacters: 3,       // minimum nr of characters to enter before search
    scope: "All Sites",     // search scope to use
    numberOfResults: 6,    // number of results to show
    resultsAnimation: 200,  // animation time (in ms) of the search results
    resultAnimation: 0      // animation time (in ms) of individual result (when selected)
};

var quickSearchTimer;
var quickSearchSelectedDivIndex = -1;

function showResultsDiv(text) {
    var div = $("#quickSearchResults");
    var prevTable = div.prev();
    var nextTable = div.next();

    var divCss = {
        "position": "absolute",
        "top": 38,
        "left": 70,
        "width": "304px",
        "background": "transparent",
        "z-index": "100000",
        "font-weight": "bold",
        "max-width": "350px"
    };

    div.css(divCss).append(text).slideDown(quickSearchConfig.resultsAnimation);
}

$(document).ready(function() {

    $('.search-textbox-moss input').keyup(function(event) {
        var previousSelected = quickSearchSelectedDivIndex;


        // catch some keys
        switch (event.keyCode) {
            case 13:    // enter
                var selectedDiv = $("#quickSearchResults>div:eq(" + quickSearchSelectedDivIndex + ") a");
                if (selectedDiv.length == 1)
                    window.location = selectedDiv.attr("href");
                break;
            case 38:    // key up
                quickSearchSelectedDivIndex--;
                break;
            case 40:    // key down
                quickSearchSelectedDivIndex++;
                break;
        }

        // check bounds
        if (quickSearchSelectedDivIndex != previousSelected) {
            if (quickSearchSelectedDivIndex < 0)
                quickSearchSelectedDivIndex = 0;
            if (quickSearchSelectedDivIndex >= $("#quickSearchResults>div").length - 1)
                quickSearchSelectedDivIndex = $("#quickSearchResults>div").length - 2;
        }

        // select new div, unselect the previous selected
        if (quickSearchSelectedDivIndex > -1) {
            if (quickSearchSelectedDivIndex != previousSelected) {
                unSelectDiv($("#quickSearchResults>div:eq(" + previousSelected + ")"));
                selectDiv($("#quickSearchResults>div:eq(" + quickSearchSelectedDivIndex + ")"));
            }
        }

        // if the query is different from the previous one, search again
        if ($('.search-textbox-moss input').data("query") != $('.search-textbox-moss input').val()) {
            if (quickSearchTimer != null) // cancel the delayed event
                clearTimeout(quickSearchTimer);
            quickSearchTimer = setTimeout(function() { // delay the searching
                $("#quickSearchResults").fadeOut(200, initSearch);
            }, quickSearchConfig.delay);
        }
    });
});

function unSelectDiv(div) {
    // first stop all animations still in progress
    $("#quickSearchResults>div>div").stop(true, true);

    div.removeClass("quickSearchResultDivSelected").addClass("quickSearchResultDivUnselected");
    $("#details", div).hide();
}

function selectDiv(div) {
    div.addClass("quickSearchResultDivSelected");
    $("#details", div).slideDown(quickSearchConfig.resultAnimation);
}

function initSearch() {
    // first store query in data
    $('.search-textbox-moss input').data("query", $('.search-textbox-moss input').val());

    // clear the results
    $("#quickSearchResults").empty();

    // start the search
    var query = $(".search-textbox-moss input").val();
    if (query.length >= quickSearchConfig.minCharacters) {
        showResultsDiv("Haetaan ..."); // display status
        search(query);
    }
}

function search(query) {
    quickSearchSelectedDivIndex = -1;
    //var selectedScope = $("#ctl00_PlaceHolderSearchArea_ctl00_SBScopesDDL option:selected");


    var queryXML =
        "<QueryPacket xmlns='urn:Microsoft.Search.Query' Revision='1000'> \
        <Query domain='QDomain'> \
         <SupportedFormats><Format>urn:Microsoft.Search.Response.Document.Document</Format></SupportedFormats> \
         <Context> \
          <QueryText language='en-US' type='STRING' >SCOPE:\"" + quickSearchConfig.scope + "\"" + query + "</QueryText> \
         </Context> \
        <SortByProperties><SortByProperty name='Rank' direction='Descending' order='1'/></SortByProperties> \
         <Range><StartAt>1</StartAt><Count>" + quickSearchConfig.numberOfResults + "</Count></Range> \
         <EnableStemming>false</EnableStemming> \
         <TrimDuplicates>true</TrimDuplicates> \
         <IgnoreAllNoiseQuery>true</IgnoreAllNoiseQuery> \
         <ImplicitAndBehavior>true</ImplicitAndBehavior> \
         <IncludeRelevanceResults>true</IncludeRelevanceResults> \
         <IncludeSpecialTermResults>true</IncludeSpecialTermResults> \
         <IncludeHighConfidenceResults>true</IncludeHighConfidenceResults> \
        </Query></QueryPacket>";

    var soapEnv =
        "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> \
          <soap:Body> \
            <Query xmlns='urn:Microsoft.Search'> \
              <queryXml>" + escapeHTML(queryXML) + "</queryXml> \
            </Query> \
          </soap:Body> \
        </soap:Envelope>";

    $.ajax({
        url: "/_vti_bin/search.asmx",
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        complete: processResult,
        contentType: "text/xml; charset=\"utf-8\""
    });

    function processResult(xData, status) {
        var html = "";
        $(xData.responseXML).find("QueryResult").each(function() {
            var divWidh = $("#quickSearchTable").width() - 13;

            var x = $("<xml>" + $(this).text() + "</xml>");
            x.find("Document").each(function() {
                var title = $("Title", $(this)).text();
                var url = $("Action>LinkUrl", $(this)).text();
                var description = $("Description", $(this)).text()

                html +=
                    "<div class='quickSearchResultDivUnselected' style='width:" + divWidh + "px;max-width:" + divWidh + "px'> \
                        <a href='" + url + "'>" + title + "</a> \
                        <div style='font-weight: normal; display:none' id='details' style='margin-left:10px'>"
                            + description +
                            "<br/>" + url + " \
                        </div> \
                    </div>";
            });
            if (x.find("TotalAvailable").text() != "")
                html += "<div class=\"quickSearchResultCounter\">Hakutuloksia yhteensä: " + x.find("TotalAvailable").text() + "</div>";
            else
                html += "<div class=\"quickSearchResultCounter\">Hakutuloksia yhteensä: 0</div>";

            html += "<div class=\"quickSearchFooter\">&nbsp;</div>";

        });

        $("#quickSearchResults").empty().append(html);
        $("#quickSearchResults>div>a").hover(
            function() { selectDiv($(this).parent()); },
            function() { unSelectDiv($(this).parent()); }
        );
        showResultsDiv();
    }
}

function escapeHTML(str) {
    return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}    
