Search code examples
c#jquery-uijquery-ui-autocompleteashx

jquery ui autocomplete values not being displayed in textbox


am working on a JQuery UI Autocomplete widget that connects to a Google Search Appliance I have tested the widget using both Fiddler and Visual Studio 2010 inbuilt testing tools and can verify that result are being returned from the queries that I am entering.

My problems is that even though results are being returned they do not show in the textbox, currently I am using a combination of JQuery and an ashx web handler to retrieve and display the result, below is the code for the JQuery and the handler:

JQuery

<html lang="en">
<head>
<meta charset="utf-8" />
<title>GSA Autocomplete Widget</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<link rel="stylesheet" href="/content/styles.css" />
<style>
   .ui-autocomplete-loading {
   background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat;
}
</style>
<script type="text/javascript">
    $(function () {
        var cache = {};
        $("#programmes").autocomplete({
            minLength: 2,
            source: function (request, response) {
                var term = request.term;
                if (term in cache) {
                    response(cache[term]);
                    return;
                }
                $.getJSON("handlers/Suggest.ashx", request, function (data, status, xhr) {
                   cache[term] = data;
                   response(data);
                });
           }
       });
   });
</script>
</head>
<body>
<div class="ui-widget">
<label for="programmes">Programmes: </label>
<input id="programmes" />
</div>
</body>
</html>

ASHX Handler

public class Suggest : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        if (string.IsNullOrEmpty(context.Request.QueryString[_QUERY_PARAM]))
            throw new Exception(string.Format("Could not find parameter '{0}'", _QUERY_PARAM));

        // Get the suggestion word from the parameter
        string term = context.Request.QueryString[_QUERY_PARAM];
        // Create an URL to the GSA
        string suggestionUrl = SuggestionUrl(term);
        // Call the GSA and get the GSA result as a string
        string page = GetPageAsString(suggestionUrl);
        // Convert the GSA result to Json
        string data = ConvertToJson(page);
        // Return the JSON
        context.Response.Write(data);
        context.Response.End();
    }

    private string SuggestionUrl(string term)
    {
        // You should modify this line to connect to your
        // own GSA, using the correct collection and frontend
        return "http://google4r.mc.man.ac.uk/suggest?max=10&site=mbs_collection&client=mbs_frontend&access=p&format=rich&q=" + term;
    }

    private string GetPageAsString(string address)
    {
        // Add your own error handling here
        HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream());
            return reader.ReadToEnd();
        }
    }

    private string ConvertToJson(string gsaSuggestResult)
    {
        bool isFirst = true;
        StringBuilder sb = new StringBuilder();
        sb.Append("{ query:");
        foreach (string token in ParseGsaInput(gsaSuggestResult))
        {
            if (isFirst)
            {
                sb.AppendFormat("'{0}', suggestions:[", token.Trim());
                isFirst = false;
            }
            else
            {
                sb.AppendFormat("'{0}',", token.Trim());
            }
        }
        sb.Remove(sb.Length - 1, 1);
        sb.Append(@"]}");
        return sb.ToString();
    }

    private IEnumerable<string> ParseGsaInput(string gsaSuggestResult)
    {
        gsaSuggestResult = gsaSuggestResult.Replace("[", "").Replace("]", "").Replace("\"", "");
        return gsaSuggestResult.Split(',');
    }

    private const string _QUERY_PARAM = "term";
}

Currently the JSON result returns name and type.

how do I go about binding the results from the web handler to the textbox?


Solution

  • I suggest you return the data collected from source as is(unless you have some other requirement for modification) to client side, as

    public void ProcessRequest(HttpContext context)
    {
        if (string.IsNullOrEmpty(context.Request.QueryString[_QUERY_PARAM]))
            throw new Exception(string.Format("Could not find parameter '{0}'", _QUERY_PARAM));
    
        // Get the suggestion word from the parameter
        string term = context.Request.QueryString[_QUERY_PARAM];
        // Create an URL to the GSA
        string suggestionUrl = SuggestionUrl(term);
        // Call the GSA and get the GSA result as a string
        string page = GetPageAsString(suggestionUrl);
        context.Response.Write(page);
        //Should inform about the content type to client
        context.Response.ContentType = "application/json";
        context.Response.End();
    }
    

    then in client side format the response as per autocomplete requirement

    $(function () {
        var cache = {};
        $("#programmes").autocomplete({
            minLength: 2,
            source: function (request, response) {
                var term = request.term;
                if (term in cache) {
                    response(cache[term]);
                    return;
                }
                $.getJSON("/Suggest.ashx", request, function(data, status, xhr) {
                    var suggestions;
    
                    suggestions = $.map(data.results, function(item) {
                        return { label: item.name, value: item.name };
                    });
                    cache[term] = suggestions;
                    response(suggestions);
                });
            }
        });
    });
    

    hope this helps.