Автозаполнение jQuery и ASP.NET
Я просмотрел весь этот сайт и веб-сайт для хорошего и простого примера автозаполнения с использованием jQuery и ASP.NET. Я хотел бы разоблачить данные, используемые автозаполнением, с помощью webservice (и, вероятно, это сделает следующий). В то же время, я получил эту работу, но она кажется немного взломанной...
На моей странице у меня есть текстовое поле:
<input id="txtSearch" type="text" />
Я использую автозаполнение jQuery, настроенное по их примеру:
<link rel="stylesheet" href="js/jquery.autocomplete.css" type="text/css" />
<script type="text/javascript" src="js/jquery.bgiframe.js"></script>
<script type="text/javascript" src="js/jquery.dimensions.pack.js"></script>
<script type="text/javascript" src="js/jquery.autocomplete.js"></script>
Вот где он начинает хакать... Я вызываю страницу вместо webservice:
<script type="text/javascript">
$(document).ready(function(){
$("#txtSearch").autocomplete('autocompletetagdata.aspx');
});
</script>
На странице я удалил ВСЕ html и просто получил это (в противном случае в раскрывающемся списке автозаполнения отображаются различные биты HTML):
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="autocompletetagdata.aspx.cs" Inherits="autocompletetagdata" %>
И в моем autocompletetagdata.aspx я использую SubSonic для запроса, форматирования и возврата данных из базы данных (по одному элементу данных в строке):
protected void Page_Load(object sender, EventArgs e)
{
// Note the query strings passed by jquery autocomplete:
//QueryString: {q=a&limit=150×tamp=1227198175320}
LookupTagCollection tags = Select.AllColumnsFrom<LookupTag>()
.Top(Request.QueryString["limit"])
.Where(LookupTag.Columns.TagDescription).Like(Request.QueryString["q"] + "%")
.OrderAsc(LookupTag.Columns.TagDescription)
.ExecuteAsCollection<LookupTagCollection>();
StringBuilder sb = new StringBuilder();
foreach (LookupTag tag in tags)
{
sb.Append(tag.TagDescription).Append("\n");
}
Response.Write(sb.ToString());
}
Если вы не делаете запрос LIKE, он возвращает все, что содержит совпадение для символов (ов), которые вы вводите, например, ввод "a" будет включать в себя "Ask" и "Answer", а также "Март" и "Мега". Я просто хотел, чтобы он начинал с матча.
В любом случае, он работает, и его довольно легко настроить, но есть ли лучший способ?
Ответы
Ответ 1
Недавно я реализовал автозаполнение, и он выглядит довольно похожим. Я использую ashx (Generic Handler) вместо aspx, но в основном это тот же код в коде.
Используя ashx, он будет выглядеть примерно так:
<script type="text/javascript">
$(document).ready(function(){
$("#txtSearch").autocomplete('autocompletetagdata.ashx');
});
</script>
[WebService(Namespace = "http://www.yoursite.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AutocompleteTagData : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Note the query strings passed by jquery autocomplete:
//QueryString: {q=a&limit=150×tamp=1227198175320}
LookupTagCollection tags = Select.AllColumnsFrom<LookupTag>()
.Top(context.Request.QueryString["limit"])
.Where(LookupTag.Columns.TagDescription).Like(context.Request.QueryString["q"] + "%")
.OrderAsc(LookupTag.Columns.TagDescription)
.ExecuteAsCollection<LookupTagCollection>();
foreach (LookupTag tag in tags)
{
context.Response.Write(tag.TagDescription + Environment.NewLine);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Ответ 2
Я просто разместил это по другому вопросу, но вы можете переопределить функцию синтаксиса на подключаемом модуле автозаполнения jQuery, чтобы он поддерживал любой вывод.
Пример:
$("#<%= TextBox1.ClientID %>").autocomplete("/Demo/WebSvc.asmx/SuggestCustomers", {
parse: function(data) {
var parsed = [];
$(data).find("string").each(function() {
parsed[parsed.length] = {
data: [$(this).text()],
value: $(this).text(),
result: [$(this).text()]
};
});
return parsed;
},
dataType: "xml"
});
Все это ожидает массив строк в XML... Очень легко сделать... Если вы используете SubSonic, вы должны проверить RESTHandler (это скрытый GEM!!!), он поддерживает базовые запросы на всех ваших объектов и может возвращать JSON/XML. Вот пример запроса, используя его...
/Demo/services/Customers/list.xml?CustomerName=JOHN
Если вы измените list.xml на list.json, он изменит результаты на JSON. Вышеуказанный запрос вернет строго типизированный объект "Клиент". Вы можете изменить параметр для поддержки LIKE, NOT LIKE и т.д. Очень мощный, и вся сантехника выполнена arleady...
Вот видео на нем: http://subsonicproject.com/tips-and-tricks/webcast-using-subsonic-s-rest-handler/
Ответ 3
Веб-служба или служба WCF предоставят вам потенциал для лучшего интерфейса. Оба они также могут быть настроены для сериализации Json.
Поскольку я беру класс WCF, когда пишу (я нахожусь на перерыв, действительно!), я нарисую метод WCF.
[OperationContract]
[WebInvoke(RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json)]
public LookupTagCollection LookupTags( int limit, string q )
{
return Select.AllColumnsFrom<LookupTag>()
.Top(limit)
.Where(LookupTag.Columns.TagDescription)
.Like(q+ "%")
.OrderAs(LookupTag.Columns.TagDescription)
.ExecuteAsCollection<LookupTagCollection>();
}
LookupTagCollection должен быть Serializable.
Ответ 4
Jquery 1.8 Autocomplete использует термин "term", а не "q" в качестве параметра querystring. это короткая и сладкая версия, которую я реализовал. Надеюсь, это поможет кому-то.
JavaScript:
$(function () {
$("#autocomplete").autocomplete({
source: "/pathtohandler/handler.ashx",
minLength: 1,
select: function (event, ui) {
$(this).val(ui.item.value);
}
});
});
Обработчик ASHX:
public class SearchHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var term = context.Request.QueryString["term"].ToString();
context.Response.Clear();
context.Response.ContentType = "application/json";
var search = //TODO implement select logic based on the term above
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string json = jsSerializer.Serialize(search);
context.Response.Write(json);
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}