javascript 在 ASP.NET 中使用 JQuery UI 自动完成的有效方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20226785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 18:02:40  来源:igfitidea点击:

Efficient way of using JQuery UI Autocomplete with ASP.NET

c#javascriptjqueryasp.netajax

提问by Aishwarya Shiva

I am using JQuery UI Autocomplete with my ASP.NET-C# Website.

我在我的 ASP.NET-C# 网站上使用 JQuery UI 自动完成。

JavaScript:

JavaScript:

$(function () {
        var availableTags = [
            <%=GetAvaliableTags() %>
        ];
        $("input.tag_list").autocomplete({
            source: availableTags
        });
    });

C# Function in code-behind:

代码隐藏中的 C# 函数:

public string GetAvaliableTags()
{
    var tags = new[] { "ActionScript", "Scheme" };
    return String.Join(",", tags.Select(x => String.Format("\"{0}\"", x)));
}

This is working fine. But I have a doubt that if I fetch the big amount of tags from database, it will load all those tags on page load at once, making it slow. The efficient way that came to my mind is to use Ajax. But I am not a Ajax programmer and know little about it. Can any one please tell me how to do it with Ajax efficiently? How to call GetAvailableTagson demand?

这工作正常。但我怀疑如果我从数据库中获取大量标签,它会在页面加载时一次性加载所有这些标签,从而使其变慢。我想到的有效方法是使用 Ajax。但我不是 Ajax 程序员,对此知之甚少。谁能告诉我如何有效地使用 Ajax 做到这一点?如何GetAvailableTags按需调用?

UPDATE

更新

I tried like this:

我试过这样:

 $(function () {
                var availableTags = [function () {
                    $.ajax({
                        type: "POST",
                        contentType: "application/json; charset=utf-8",
                        url: "CreateTopic.aspx/GetAvaliableTags",
                        data: "{ 'key' : '" + $("input.tag_list").val() + "'}",
                        dataType: "json",
                        async: true,
                        dataFilter: function (data) { return data; },
                        success: function (data) {if (result.hasOwnProperty("d")) {

                          $("input.tag_list").autocomplete({
                              source: result.d
                          });
                      }
                      else {
                          // No .d; so just use result
                          $("input.tag_list").autocomplete({
                              source: result
                          });
                    });
                }];
                $("input.tag_list").autocomplete({
                    source: availableTags
                });
            });

Web Method equivalent of GetAvailableTags()

Web 方法等效于 GetAvailableTags()

[System.Web.Services.WebMethod]
public static string GetAvaliableTags(string key)
{
    var tags = new[] { "ActionScript", "Scheme" };
    return String.Join(",", tags.Select(x => String.Format("\"{0}\"", x)));
}

But the Ajax call is not being fired. What can be the reason?

但是 Ajax 调用并没有被触发。原因是什么?

回答by Karl Anderson

I would recommend using an ASP.NET AJAX Page Method on the server-side and have the jQuery .ajax()function call it to retrieve the data, like this:

我建议在服务器端使用 ASP.NET AJAX 页面方法,并让 jQuery.ajax()函数调用它来检索数据,如下所示:

Code-behind:

代码隐藏:

[WebMethod]
public static string GetAvailableTags()
{
    // Put logic here to return list of tags (i.e. load from database)
    var tags = new[] { "ActionScript", "Scheme" };
    return String.Join(",", tags.Select(x => String.Format("\"{0}\"", x)));
}

Markup:

标记:

$(document).ready(function() {
    $.ajax({
        type: "POST",
        url: "PageName.aspx/GetAvailableTags",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(result) {
            if (result.hasOwnProperty("d")) {
                // The .d is part of the result so reference it
                //  to get to the actual JSON data of interest
                $("input.tag_list").autocomplete({
                    source: result.d
                });
            }
            else {
                // No .d; so just use result
                $("input.tag_list").autocomplete({
                    source: result
                });
            }
        }
    });
});


Note: You will need to change the name of PageName.aspxto the name of your .aspx page. Also, the .dsyntax was an anti-XSS protection put in by Microsoft in the ASP.NET 3.5 release of ASP.NET AJAX; therefore the check to see if the .dproperty is there or not.

注意:您需要将 的名称更改为PageName.aspx.aspx 页面的名称。此外,该.d语法是 Microsoft 在 ASP.NET AJAX 的 ASP.NET 3.5 版本中引入的反 XSS 保护;因此要检查该.d物业是否在那里。

回答by sh1rts

I've got a good solution I implemented in an intranet app; it uses the jQuery UI Autocomplete function with an HttpHandler, and only searches for customers beginning with whatever's in the input; it's also only triggered when there are 3 or more characters typed. This means you're never retrieving the entire table, just a subset of it.

我有一个很好的解决方案,我在一个 Intranet 应用程序中实现了;它使用带有 HttpHandler 的 jQuery UI 自动完成功能,并且只搜索以输入中的任何内容开头的客户;它也仅在输入 3 个或更多字符时触发。这意味着您永远不会检索整个表,而只是检索其中的一个子集。

Firstly the HttpHandler. I won't go into the data-retrieval nuts and bolts cos you can probably figure out that part yourself. SUffice to say it calls a stored procedure to return customers whose name starts with (whatever was sent to the Handler), and returns a JSON-serialized array of matches to the Autocomplete handler.

首先是HttpHandler。我不会深入研究数据检索的具体细节,因为您可能会自己弄清楚那部分。可以说它调用一个存储过程来返回名称以(发送到处理程序的任何内容)开头的客户,并向自动完成处理程序返回一个 JSON 序列化的匹配数组。

using Newtonsoft.Json;

namespace Invoicing.HttpHandlers
{
    [WebService(Namespace = "yournamespace/http-handlers/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class CustomerHandler : IHttpHandler
    {
        #region IHttpHandler Members

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
          // your data-retrieval logic here
          // write json to context.Response
        }
    }

If you're not used to this approach I'll just quickly describe the JSON part.

如果您不习惯这种方法,我将快速描述 JSON 部分。

Basically, I have a small wrapper-type object called "ResponseCustomer" because I only really need Customer ID and Name for the Autocomplete handler, not the complete Customer details: -

基本上,我有一个名为“ResponseCustomer”的小包装类型对象,因为我只需要自动完成处理程序的客户 ID 和名称,而不是完整的客户详细信息:-

[Serializable]
public class ResponseCustomer
{
    public int ID;
    public string CustomerName;
}

IHttpHandler.ProcessRequest invokes my stored procedure, and transforms the results into an IList - this means the JSON returned is as lean as possible: -

IHttpHandler.ProcessRequest 调用我的存储过程,并将结果转换为 IList - 这意味着返回的 JSON 尽可能精简:-

    public void ProcessRequest(HttpContext context)
    {
        string json = string.Empty;

        // note the httpcontext.Request contains the search term
        if (!string.IsNullOrEmpty(context.Request["term"]))
        {
            string searchTerm = context.Request["term"];
            var customers = (data access component).CustomerSearch(searchTerm); // call Search stored proc

            if (customers.Count != 0)
            {
                var transformList = new List<ResponseCustomer>();

                for (int index = 0; index < customers.Count; index++)
                {
                    transformList.Add(new ResponseCustomer
                    {
                        ID = customers[index].ID,
                        CustomerName = customers[index].CustomerName
                    });
                }

                // call Newtonsoft.Json function to serialize list into JSON
                json = JsonConvert.SerializeObject(transformList);
            }

        }

        // write the JSON (or nothing) to the response
        context.Response.Write(json);
    }
    public void ProcessRequest(HttpContext context)
    {
        string json = string.Empty;

        // note the httpcontext.Request contains the search term
        if (!string.IsNullOrEmpty(context.Request["term"]))
        {
            string searchTerm = context.Request["term"];
            var customers = (data access component).CustomerSearch(searchTerm); // call Search stored proc

            if (customers.Count != 0)
            {
                var transformList = new List<ResponseCustomer>();

                for (int index = 0; index < customers.Count; index++)
                {
                    transformList.Add(new ResponseCustomer
                    {
                        ID = customers[index].ID,
                        CustomerName = customers[index].CustomerName
                    });
                }

                // call Newtonsoft.Json function to serialize list into JSON
                json = JsonConvert.SerializeObject(transformList);
            }

        }

        // write the JSON (or nothing) to the response
        context.Response.Write(json);
    }

So far so good ?

到现在为止还挺好 ?

Make sure this HttpHandler is wired into web.config (note you will have to do this differently for IIS6 than for IIS 7+): -

确保此 HttpHandler 已连接到 web.config(请注意,对于 IIS6,您必须以与 IIS 7+ 不同的方式执行此操作):-

      <system.web>

        <!-- Custom HTTP handlers (IIS 6.0) -->
        <httpHandlers>
          <add path="customerHandler.ashx" verb="*" type="(namespace).(handler name), (assembly name)" />

i.e.

      <add path="customerHandler.ashx" verb="*" type="MyProject.Handlers.CustomerHandler, MyProject" />

    and for IIS7: -


  <system.webServer>

    <handlers>
      <!-- Custom HTTP handlers (IIS7+) -->
      <add name="customerHandler" preCondition="integratedMode" verb="*" path="customerHandler.ashx" type="(namespace).(handler name), (assembly name)"" />

Finally wire in the client-side, as you already know: -

最后连接到客户端,正如您已经知道的:-

HTML: -

HTML:-

        <span>Customer</span>
        <span class="ui-widget" style="display:inline-block">
            <input id="txtCustomer" runat="server" clientidmode="Static" />
        </span>

JS: -

JS: -

$(function ()
{
    $("#txtCustomer").autocomplete(
        {
            source: "customerHandler.ashx",
            // note minlength, triggers the Handler call only once 3 characters entered
            minLength: 3,
            select: function (event, ui)
            {
                if (ui.item)
                {
                    $("#txtCustomer").val(ui.item.CustomerName);
                    return false;
                }
            }
        })
        .data("autocomplete")._renderItem = function (ul, item)
        {
            // insert an item into the autocomplete dropdown (YMMV)
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a><table cellpadding='0' cellspacing='0' border='0' width='250px'><tr><td width='200' valign='top' align='left'>"
                + item.CustomerName + "</td><td width='50px' valign='top' align='left'>[ID "
                + item.ID + "]</td></tr></table></a>")
                .appendTo(ul);
        };
});

Let me know if this helps, I can email you the relevant source files if you want.

如果这有帮助,请告诉我,如果您愿意,我可以通过电子邮件将相关源文件发送给您。

回答by Saurabh Singh

If you want real time update of options

如果您想实时更新选项

    $(document).ready(function() {   
            $("textbox").autocomplete({
                source: function (request, response) {
                pageMethod.yourmethodname(request.term,onSuccess)
                function onSuccess(Responce){
                                  data = JSON.parse(Responce)
                                  response($.map(data.d, function (item) {
                                          return {
                                                 value: item
                                                  }
                                     }

    };