0

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>
4

1 に答える 1

0

問題の解決策を見つけました。

テキストボックスのIDを使用してオートコンプレートを開始しました:

$("input[id$='<%= txtCustomerName.ClientID %>']").autocomplete({...});

これを、テキスト ボックスに設定した特定の css クラス (この場合は artworkcopylookup) に変更しました。オートコンプリートを開始するときは、css クラスを使用してテキスト ボックスを選択します。

$("input[class$='artworkcopylookup']").autocomplete({...});

以前に読み込まれた texbox を id で検索する代わりに、スクリプトは正しいクラス セットを持つ入力を検索します。このようにして、新しくロードされた texbox が見つかり、すべてが魅力的に機能します。

于 2013-06-05T14:46:55.500 に答える