ASP.NET 動的データ エンティティ Web アプリケーションを作成しました。6000 以上のレコードを含むテーブルへの外部キーがあります。デフォルトでは、動的データ アプリケーションは ForeignKey フィールド テンプレートを使用します。
編集モードまたは挿入モードの場合、ForeignKey フィールド テンプレートは 6000 以上のアイテムを含むドロップダウンになります。これはパフォーマンスを低下させ、まったくユーザーフレンドリーではないため、jquery オートコンプリートを使用するカスタム FieldTemplate と、json を返す WCF REST 対応 Web サービスを作成して、オートコンプリート リストに最大 25 項目を入力しました。カスタム フィールド テンプレートには、名前用と ID 用の 2 つのテキスト ボックスが含まれています。ID のテキスト ボックスは、CSS を使用して非表示にします。名前のテキスト ボックスに入力すると、オートコンプリート機能によって範囲が絞り込まれ、名前を選択すると、javascript を使用して ID が設定されます。
function setAutoCompleteCustomerField() {
if (!window.location.origin) window.location.origin = window.location.protocol + "//" + window.location.host;
$(function () {
$("input[id$='<%= txtCustomerName.ClientID %>']").autocomplete({
source: function (request, response) {
$.ajax({
url: window.location.origin + "/AutocompleteService.svc/CustomerLookup",
data: {
text: request.term,
count: 25
},
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
value: item.Name,
id: item.Id
}
}))
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
},
minLength: 2,
select: function (event, ui) {
$("#<%= txtCustomerId.ClientID %>").val(ui.item.id);
$("#<%= txtCustomerId.ClientID %>").change();
}
});
});
}
ListView pagetemplate を使用して、データを表示、編集、および挿入します。ページ テンプレートは、GridView と FormView を含む UpdatePanel で構成されます。GridView でレコードを選択すると、データが FormView に表示されます。FormView の DefaultMode は Edit に設定されています。名前を入力し始めると、すべてうまくいきます。他の値を選択したり、更新したりできます。これまでのところ、問題ありません。
また、更新パネル内に「新しいレコードを挿入」リンクボタンがあります。このリンクボタンをクリックすると、FormView の FormViewMode が Insert に設定されます。
protected void lnkInsertNew_Click(object sender, EventArgs e)
{
FormView1.ChangeMode(FormViewMode.Insert);
}
挿入モードでは、同じカスタム FieldTemplate が読み込まれますが、オートコンプリートが機能しなくなります。オートコンプリート機能を再開するために 2 つの方法を試しました。
私が最初に試したのは:
if (Sys.WebForms) {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function (sender, args) {
setAutoCompleteCustomerField();
});
}
二番目:
$(document).ready(function () {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(setAutoCompleteCustomerField);
});
どちらも同じ動作になりました。setAutoCompleteCustomerField 関数が実行されます。ただ、処刑は早いようです。setAutoCompleteCustomerField 関数内にアラートを配置して、顧客名のテキスト ボックスの ID を表示すると、null 値が表示されます。これは、要素がまだロードされていないことを示します。
alert($("#<%= txtCustomerName.ClientID %>").attr("id"));
どうすればこの問題を克服できますか? setAutoCompleteCustomerField 関数を呼び出す前に、すべての要素がロードされていることを確認するにはどうすればよいですか? 助けてくれてありがとう!
更新 ListDetails.aspx からコードを追加しました
<asp:Content ID="headContent" ContentPlaceHolderID="head" Runat="Server">
<% if (false) { %><script src="~/Scripts/jquery-1.5-vsdoc.js" type="text/javascript"></script><% } %>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:DynamicDataManager ID="DynamicDataManager1" runat="server" AutoLoadForeignKeys="true">
<DataControls>
<asp:DataControlReference ControlID="FormView1" />
<asp:DataControlReference ControlID="GridView1" />
</DataControls>
</asp:DynamicDataManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<div class="DD"> <asp:DynamicValidator runat="server" ID="GridViewValidator" ControlToValidate="GridView1" Display="None" CssClass="validator" />
<asp:DynamicValidator runat="server" ID="FormViewValidator" ControlToValidate="FormView1" Display="None" CssClass="validator" />
<div id="filterBox">
<a href="#" id="filterToggle"><%= GalleryOnline.Globalization.Resources.Common.Label_ShowOrHideFilters %></a>
<div id="filters">
<asp:QueryableFilterRepeater runat="server" ID="FilterRepeater">
<ItemTemplate>
<span class="filterItem">
<asp:Label runat="server" Text='<%# Eval("DisplayName") %>' OnPreRender="Label_PreRender" />
<asp:DynamicFilter runat="server" ID="DynamicFilter" OnFilterChanged="DynamicFilter_FilterChanged" />
</span>
</ItemTemplate>
</asp:QueryableFilterRepeater>
</div>
</div>
</div>
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridDataSource" EnablePersistedSelection="true"
AllowPaging="True" AllowSorting="True" OnDataBound="GridView1_DataBound" AutoGenerateSelectButton="true"
OnRowEditing="GridView1_RowEditing" OnSelectedIndexChanging="GridView1_SelectedIndexChanging"
OnRowDeleted="GridView1_RowDeleted" OnRowUpdated="GridView1_RowUpdated" ShowHeaderWhenEmpty="true"
OnRowCreated="GridView1_RowCreated" CssClass="grid" OnPreRender="GridView1_PreRender"
RowStyle-CssClass="td" HeaderStyle-CssClass="th" GridLines="None" AutoGenerateColumns="false">
<PagerStyle CssClass="DDFooter" />
<SelectedRowStyle CssClass="td selected" />
<AlternatingRowStyle CssClass="td alternating" />
<PagerTemplate>
<asp:GridViewPager runat="server" />
</PagerTemplate>
<EmptyDataTemplate>
<%= GalleryOnline.Globalization.Resources.Common.Message_NoData %>
</EmptyDataTemplate>
</asp:GridView>
<div class="gridOptions">
<asp:LinkButton ID="lnkInsertNew" runat="server" OnClick="lnkInsertNew_Click" CausesValidation="false">+ <%= GalleryOnline.Globalization.Resources.Common.InsertNewItem %></asp:LinkButton>
</div>
<asp:EntityDataSource ID="GridDataSource" runat="server"/>
<asp:QueryExtender ID="GridQueryExtender" TargetControlID="GridDataSource" runat="server">
<asp:DynamicFilterExpression ControlID="FilterRepeater" />
</asp:QueryExtender>
<asp:Panel ID="DetailsPanel" runat="server" CssClass="tabs">
<asp:FormView ID="FormView1" runat="server" DataSourceID="DetailsDataSource" RenderOuterTable="false"
OnPreRender="FormView1_PreRender" OnModeChanging="FormView1_ModeChanging" OnItemUpdated="FormView1_ItemUpdated"
OnItemInserted="FormView1_ItemInserted" OnItemDeleted="FormView1_ItemDeleted" OnDataBound="FormView1_DataBound" DefaultMode="Edit">
<ItemTemplate>
<asp:DynamicEntity runat="server" />
<div class="formActions">
<asp:Button runat="server" CommandName="Edit" Text="<%# GalleryOnline.Globalization.Resources.Common.Edit %>" />
<asp:Button runat="server" CommandName="Delete" Text="<%# GalleryOnline.Globalization.Resources.Common.Delete %>" OnClientClick='<%# "return confirm(\"" + GalleryOnline.Globalization.Resources.Common.Question_DeleteOrCancel +"\");" %>' />
<asp:Button runat="server" CommandName="New" Text="<%# GalleryOnline.Globalization.Resources.Common.New %>" />
</div>
</ItemTemplate>
<EditItemTemplate>
<asp:DynamicEntity runat="server" Mode="Edit" />
<div class="formActions">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td valign="top"><asp:Button runat="server" CommandName="Update" Text="<%# GalleryOnline.Globalization.Resources.Common.Update %>" ID="btnUpdate" /></td>
<td valign="top"><asp:Button ID="Button5" runat="server" CommandName="Cancel" Text="<%# GalleryOnline.Globalization.Resources.Common.Cancel %>" CausesValidation="false" /></td>
<td valign="top"><asp:Button ID="Button6" runat="server" CommandName="Delete" Text="<%# GalleryOnline.Globalization.Resources.Common.Delete %>" OnClientClick='<%# "return confirm(\"" + GalleryOnline.Globalization.Resources.Common.Question_DeleteOrCancel +"\");" %>' /> </td>
<td valign="top"><asp:Button ID="Button7" runat="server" Text="<%# GalleryOnline.Globalization.Resources.Common.Back %>" CausesValidation="false" OnClientClick='javascript:history.go(-1);' /></td>
<td>
<div id="functionNavBox">
<asp:Button id="btnFunctions" runat="server" OnClientClick="return false;" CssClass="functions" Text="<%# GalleryOnline.Globalization.Resources.Common.Functions %>" />
<ul id="functionNavTree" style="display:none; position:relative; left:80px; bottom:103px; background-color:#fff; border:1px solid #CCC; padding:3px; z-index:1000;">
<li><asp:Button id="Button3" runat="server" OnClientClick='<%# "window.open(\"" + GetRouteUrl("ViewInvoiceDetails", new {invoiceId=Eval("InvoiceId")}) + "\"); return false;" %>' Text="<%# GalleryOnline.Globalization.Resources.Common.PrintProFormaInvoice %>" /></li>
<li><asp:Button ID="btnPrintInvoice" runat="server" CommandArgument='<%# Eval("InvoiceId") %>' OnClick="btnPrintInvoice_Click" OnClientClick='<%# "window.open(\"" + GetRouteUrl("ViewInvoiceDetails", new {invoiceId=Eval("InvoiceId")}) + "\");" %>' Text="<%# GalleryOnline.Globalization.Resources.Common.PrintInvoice %>" /></li>
<li><asp:Button id="btnDelivered" runat="server" CommandArgument='<%# Eval("InvoiceId") %>' OnClick="btnDelivered_Click" Text="<%# GalleryOnline.Globalization.Resources.Common.Delivered %>" /></li>
<li><asp:Button ID="Button2" runat="server" OnClientClick='<%# "window.open(\"" + GetRouteUrl("ViewValuation", new {invoiceId=Eval("InvoiceId")}) + "\"); return false;" %>' Text="<%# GalleryOnline.Globalization.Resources.Common.PrintValuation %>" /></li>
</ul>
</div>
</td>
</tr>
</table>
</div>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DynamicEntity runat="server" Mode="Insert" />
<div class="formActions">
<asp:Button runat="server" CommandName="Insert" Text="<%# GalleryOnline.Globalization.Resources.Common.Insert %>" ID="btnInsert" />
<asp:Button runat="server" CommandName="Cancel" Text="<%# GalleryOnline.Globalization.Resources.Common.Cancel %>" CausesValidation="false" />
</div>
</InsertItemTemplate>
</asp:FormView>
<asp:Panel ID="InitialInvoiceItemDetailsPanel" runat="server" CssClass="extras" Visible="false">
<h4><%= String.Format(GalleryOnline.Globalization.Resources.Common.Label_CreatingInvoiceForArtworkCopy, this.ArtworkSalesPriceContext.Artwork.Name, this.ArtworkSalesPriceContext.CopyNumber) %></h4>
<table class="form">
<tr>
<td class="label"><%= GalleryOnline.Globalization.Resources.EntityMetadata.Price %></td>
<td class="value"><%= this.ArtworkSalesPriceContext.Price.ToString("F2") %></td>
</tr>
<tr>
<td class="label"><%= GalleryOnline.Globalization.Resources.EntityMetadata.VatPercentage %></td>
<td class="value"><asp:DropDownList ID="VatRateDropDown" runat="server"
DataValueField="VatPercentageId" DataTextField="Name" /></td>
</tr>
</table>
</asp:Panel>
<asp:EntityDataSource ID="DetailsDataSource" runat="server" EnableDelete="true"
EnableInsert="true" EnableUpdate="true"
oninserting="DetailsDataSource_Inserting" />
<asp:QueryExtender TargetControlID="DetailsDataSource" runat="server">
<asp:ControlFilterExpression ControlID="GridView1" />
</asp:QueryExtender>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress AssociatedUpdatePanelID="UpdatePanel1" runat="server" DisplayAfter="0" DynamicLayout="true" ID="UpdateProgress1" Visible="true">
<ProgressTemplate>
<div class="loadingProgress"><%# GalleryOnline.Globalization.Resources.Common.Label_Loading %></div>
</ProgressTemplate>
</asp:UpdateProgress>
<script type="text/javascript">
var gridSelectExtender = new GalleryOnline.UI.EasySelectGridViewExtender('<%= GridView1.ClientID %>', '<%= GridView1.UniqueID %>');
if (Sys.WebForms)
{
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function (sender, args)
{
if (args.get_panelsUpdated().length > 0)
gridSelectExtender.extend();
GalleryOnline.UI.FilterManager.initializeFilters();
});
}
$().ready(gridSelectExtender.extend);
$().ready(GalleryOnline.UI.FilterManager.initializeFilterVisibility);
</script>
</asp:Content>