Search code examples
c#jqueryasp.nettypeahead.jsbloodhound

How can i get remote call on bootstrap twitter typeahead to work, by calling asp.net web method


I am trying to load my typeahead.js by using bloohound's remote function where i can call my Web Method. I have seen similar threads where a querystring is being used :

  1. Integrating Typeahead.js with ASP.Net Webmethod
  2. Typeahead.js and Bloodhound.js integration with C# WebForms WebMethod
  3. http://yassershaikh.com/using-twitter-typeahead-js-with-asp-net-mvc-web-api/

And many more....

However, i cannot find an example where ajax is used to call the webmethod from typeahead.js.

So this is what i have currently and it works:

WebMethod

    [WebMethod]
    public static string GetEmployeeTypeahead()
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        jss.MaxJsonLength = 100000000;
        string json;

        using (var rep = new RBZPOS_CSHARPEntities())
        {
            var result = rep.Employees
                            .Where(x => x.EMPLOYEESTATE == 1)
                            .Select(x => new { 
                                x.EMPLOYEEID,
                                x.FULLNAME,
                                x.MANNO,
                                x.NRC
                            }).ToList();

            json = jss.Serialize(result);
        }

        return json;
    }

The Client

        function LoadEmployeeJSON() {
        $.ajax({
            type: "POST",
            url: "/WebMethods/Test.aspx/GetEmployeeTypeahead",
            data: "{}",
            contentType: "application/json",
            dataType: "json",
            success: function (msg) {
                empList = $.parseJSON(msg.d);                  //otherwise does not work

                LoadEmployeeTypeahead();
            },
            error: function (msg) {
                alert("error:" + JSON.stringify(msg));
            }
        });

    }
    function LoadEmployeeTypeahead() {
        var empData = empList;

        var fullname = new Bloodhound({
            datumTokenizer: function (d) {
                return Bloodhound.tokenizers.whitespace(d.FULLNAME)
            },
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            local: empData,
            limit: 10
        });

        fullname.initialize();
        // Make the code less verbose by creating variables for the following
        var fullnameTypeahead = $('#<%=txtFullName.ClientID %>.typeahead');

        // Initialise typeahead for the employee name
        fullnameTypeahead.typeahead({
            highlight: true
        }, {
            name: 'FULLNAME',
            displayKey: 'FULLNAME',
            source: fullname.ttAdapter(),
            templates: {
                empty: [
                                    '<div class="empty-message">',
                                    'No match',
                                    '</div>'
                ].join('\n'),
                suggestion: function (data) {
                    return '<h6 class="">' + data.FULLNAME + "<span class='pull-right text-muted small'><em>" + data.NRC + "</em></span>" + '</h6>';
                }
            }
        });

        var fullnameSelectedHandler = function (eventObject, suggestionObject, suggestionDataset) {
            /* See comment in previous method */
            $('#<%=txtFullName.ClientID %>').val(suggestionObject.FULLNAME);
            $('#<%=txtEmployeeID.ClientID %>').val(suggestionObject.EMPLOYEEID);
            $('#<%=txtManNo.ClientID %>').val(suggestionObject.MANNO);
            $('#<%=txtNRC.ClientID %>').val(suggestionObject.NRC);

        };

        // Associate the typeahead:selected event with the bespoke handler
        fullnameTypeahead.on('typeahead:selected', fullnameSelectedHandler);
    }
     function clearAndReInitilize() {

        $('.typeahead').typeahead('destroy');
        $('.typeahead').val('');
    }

So as you can see i am making a local call instead of remote.

How can i get the remote function to call my webthod and fill the typeahead without using any querystrings


Solution

  • Okay finally got it to work via an ashx generic handler. So instead of using a web method i used the following ashx handler:

     public class Employess : IHttpHandler
    {
    
        public void ProcessRequest(HttpContext context)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            jss.MaxJsonLength = Int32.MaxValue;
            string json;
            string prefixText = context.Request.QueryString["query"];
    
            using (var rep = new RBZPOS_CSHARPEntities())
            {
                var result = rep.Employees
                                 .Where(x => x.EMPLOYEESTATE == 1 && x.FULLNAME.Contains(prefixText.ToUpper()))
                                 .Select(x => new
                                 {
                                     x.EMPLOYEEID,
                                     x.FULLNAME,
                                     x.MANNO,
                                     x.NRC
                                 }).ToArray();
    
                json = jss.Serialize(result);
            }
    
            context.Response.ContentType = "text/javascript";
            context.Response.Write(json);
        }
    
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
    

    Below is the jquery and the ajax call to the ashx handler

     $(document).ready(function () {
            $(document).ajaxStart($.blockUI).ajaxStop($.unblockUI);
            LoadEmployeeTypeahead();
          //  LoadEmployeeJSON();
        });
     function LoadEmployeeTypeahead() {
            //var empData = empList;
    
            var fullname = new Bloodhound({
                remote: {
                    url: '/Employess.ashx?query=%QUERY',
                    wildcard: '%QUERY'
                },
                datumTokenizer: function (d) {
                    //var employees = $.parseJSON(msg.d);
                    return Bloodhound.tokenizers.whitespace(d.FULLNAME)
                },
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                limit: 10
            });
    
            fullname.initialize();
            // Make the code less verbose by creating variables for the following
            var fullnameTypeahead = $('#<%=txtFullName.ClientID %>.typeahead');
    
            // Initialise typeahead for the employee name
            fullnameTypeahead.typeahead({
                highlight: true
            }, {
                name: 'FULLNAME',
                displayKey: 'FULLNAME',
                source: fullname.ttAdapter(),
                templates: {
                    empty: [
                                        '<div class="empty-message">',
                                        'No match',
                                        '</div>'
                    ].join('\n'),
                    suggestion: function (data) {
                        return '<h6 class="">' + data.FULLNAME + "<span class='pull-right text-muted small'><em>" + data.MANNO + "</em></span><span class='pull-right text-muted small'><em>" + data.NRC + "</em></span>" + '</h6>';
                    }
                }
            });
    
            var fullnameSelectedHandler = function (eventObject, suggestionObject, suggestionDataset) {
                /* See comment in previous method */
                $('#<%=txtFullName.ClientID %>').val(suggestionObject.FULLNAME);
                $('#<%=txtEmployeeID.ClientID %>').val(suggestionObject.EMPLOYEEID);
                $('#<%=txtManNo.ClientID %>').val(suggestionObject.MANNO);
                $('#<%=txtNRC.ClientID %>').val(suggestionObject.NRC);
    
            };
    
            // Associate the typeahead:selected event with the bespoke handler
            fullnameTypeahead.on('typeahead:selected', fullnameSelectedHandler);
        }