Я определил форму ASP.NET, в которой у меня есть, среди многих других, следующие элементы формы: TextBox, HiddenField и DropDownList, определенные следующим образом:
<asp:TextBox ID = "_txtData" runat = "server" ClientIDMode = "Static" />
<asp:HiddenField ID = "_hdnData" runat = "server" ClientIDMode = "Static" Value = "" />
<asp:DropDownList ID = "_ddlData" runat = "server" DataSourceID = "_sdsData" DataTextField = "data" DataValueField = "id" AppendDataBoundItems = "true" AutoPostBack = "true" >
<asp:ListItem Text = "TUTTI" Value = "" Selected = "True" />
</asp:DropDownList>
_ddlData подается из источника данных, определенного следующим образом:
<asp:SqlDataSource
ID = "_sdsData"
runat = "server"
ConnectionString = "<%$ ConnectionStrings:db %>"
ProviderName = "<%$ ConnectionStrings:db.ProviderName %>"
SelectCommand = "
SELECT
id,
data
FROM
table_data
WHERE
(@id IS NULL) OR (id = @id)
ORDER BY targa">
<SelectParameters>
<asp:ControlParameter
ControlID = "_hdnData"
PropertyName = "Value"
Direction = "Input"
ConvertEmptyStringToNull = "true"
DbType = "Int32"
DefaultValue = ""
Name = "id" />
</SelectParameters>
</asp:SqlDataSource>
_hdnData и _txtData передаются через javascript/JQuery следующим образом:
[Исходный код]
var _hdnData = null;
var _txtData = null;
$(function () {
_hdnData = $("input[id$='_hdnData']");
_txtData = $("input[id$='_txtData']");
GetData(_txtData , _hdnData );
});
function GetData(source_widget, dest_widget) {
$.ajax({
type: "POST",
url: "/Service/WSDataService.asmx/GetData",
dataType: "json",
data: "{}",
contentType: "application/json; charset=utf-8",
success: function (data) {
var datafromServer = data.d.split("<br />");
source_widget.autocomplete({
source: datafromServer,
select: function (event, ui) {
var _data = ui.item.value;
var _tokens = _data.split("\t");
if (_tokens.length < 3)
return;
var _value = _tokens[_tokens.length - 1].replace(']', '').replace('[', '');
dest_widget.val(_value).closest("form").submit();
}
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
}
[Оптимизированный код JQuery предоставлен @Tomalak]
var _hdnData = null;
var _txtData = null;
$.postJSON = function (url, data, success) {
return $.ajax({
type: "POST",
url: url,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: success || null
});
};
var raw_data = $.postJSON("/Service/WSDataService.asmx/GetData", {})
.then(function (data) {
return data.d.split("<br />");
})
.fail(function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
});
$(function () {
raw_data.done(function (items) {
$("input[id$='_txtData']").autocomplete({
source: items,
select: function (event, ui) {
var _data = ui.item, _value;
// calculate _value ...
$("input[id$='_hdnData ']")
.val(_value)
.closest("form").submit();
}
});
});
});
Когда происходит событие выбора JQuery autocomplete, форма отправляется, и после ее перезагрузки я заметил две основные проблемы:
_txtData устанавливается на частичное значение, введенное пользователем, когда произошло событие выбора (т. е. не фактическое значение, выбранное/отображаемое в меню autocomplete)
_ddlData значения, представленные до события выбора, объединяются с новыми данными, поступающими из их источника данных.
Кстати, в настоящее время я не хочу менять SQLDataSource или компоненты с привязкой к данным на более новую или обновленную парадигму (например, Microsoft Entities Framework).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


У вас проблема со временем, как в предыдущем вопросе.
Вы отправляете форму в рамках мероприятия select. Выбранное значение записывается в поле формы пользовательским интерфейсом jQuery после события select, но этот код никогда не запускается. .closest("form").submit() немедленно перезагружает страницу. На данный момент поле автозаполнения по-прежнему содержит только то, что набрал пользователь.
Быстрое и грязное решение этой проблемы — отправить форму после небольшой задержки, чтобы дать другим событиям возможность завершиться.
// ...
select: function (event, ui) {
var _data = ui.item,
_value,
$form = $(this).closest("form");
// calculate _value ...
$("input[id$='_hdnData ']").val(_value);
setTimeout(function () { $form.submit(); }, 50);
}
@weirdgyn Тогда вы бы назвали $form.submit(); в обратном вызове успеха вашего автозаполнения.
Я имею в виду, что мне нужно фильтровать данные вместе с вызовом ajax. Код, который вы написали в прошлый раз, заключался в том, чтобы получить данные до итерации пользователя с помощью связанного виджета автозаполнения.
@weirdgyn Это не меняет моего ответа. Виджет автозаполнения будет иметь успешный обратный вызов (в автозаполнении пользовательского интерфейса jQuery это событие ответа ). Вам нужно вызвать $form.submit() внутри этого обратного вызова, то есть после того, как вы получили ответ автозаполнения и записали полученное значение в поле формы, чтобы его можно было передать с помощью формы POST.
возможно, меня смутило мое незнание JQuery, но я почти уверен, что этот код не поддерживает фильтрацию на стороне сервера (без некоторых переделок). Может быть, я не ясно выразился в своем вопросе. Мне нужно обновить его таким образом. На данный момент при загрузке страницы вызов Ajax начинает запрашивать данные из веб-сервиса, но, учитывая объем данных, я получил ошибку... Я нашел решение, реализующее фильтрацию на стороне сервера (т.е. изменение источника: элементы с вызовом ajax), но я' m не может сделать то же самое с этим кодом.
что, если мне нужно выполнить фильтрацию «точно в срок» с помощью автозаполнения?