Dodawanie potwierdzenia po stronie klienta podczas usuwania (C#)
W interfejsach utworzonych do tej pory użytkownik może przypadkowo usunąć dane, klikając przycisk Usuń, gdy ma kliknąć przycisk Edytuj. W tym samouczku dodamy okno dialogowe potwierdzenia po stronie klienta, które będzie wyświetlane po kliknięciu przycisku Usuń.
Wprowadzenie
W ciągu ostatnich kilku samouczków widzieliśmy, jak używać naszej architektury aplikacji, ObjectDataSource i kontrolek sieci Web danych we wspólnych elementach w celu zapewnienia możliwości wstawiania, edytowania i usuwania. Zbadane do tej pory interfejsy usuwania składają się z przycisku Usuń, który po kliknięciu powoduje powrót i wywołuje metodę ObjectDataSource.Delete()
Następnie Delete()
metoda wywołuje skonfigurowaną metodę z warstwy logiki biznesowej, która propaguje wywołanie warstwy dostępu do danych, wydając rzeczywistą DELETE
instrukcję do bazy danych.
Chociaż ten interfejs użytkownika umożliwia odwiedzającym usuwanie rekordów za pomocą kontrolek GridView, DetailsView lub FormView, nie ma żadnego rodzaju potwierdzenia, gdy użytkownik kliknie przycisk Usuń. Jeśli użytkownik przypadkowo kliknie przycisk Usuń, gdy ma kliknąć przycisk Edytuj, rekord, który miał zaktualizować, zostanie usunięty. Aby temu zapobiec, w tym samouczku dodamy okno dialogowe potwierdzenia po stronie klienta wyświetlane po kliknięciu przycisku Usuń.
Funkcja JavaScript confirm(string)
wyświetla parametr wejściowy ciągu jako tekst w modalnym oknie dialogowym wyposażonym w dwa przyciski — OK i Anuluj (patrz Rysunek 1). Funkcja confirm(string)
zwraca wartość logiczną w zależności od kliknięcia przycisku (true
jeśli użytkownik kliknie przycisk OK, a false
jeśli kliknie przycisk Anuluj).
Rysunek 1. Metoda JavaScript confirm(string)
wyświetla modalne, Client-Side messagebox
W trakcie przesyłania formularza, jeśli wartość jest false
zwracana z procedury obsługi zdarzeń po stronie klienta, przesyłanie formularza zostanie anulowane. Za pomocą tej funkcji możemy użyć procedury obsługi zdarzeń po stronie onclick
klienta przycisku Usuń, aby zwrócić wartość wywołania polecenia confirm("Are you sure you want to delete this product?")
. Jeśli użytkownik kliknie przycisk Anuluj, zwróci wartość false, confirm(string)
co spowoduje anulowanie przesyłania formularza. Bez wycofywania produktu, którego przycisk Usuń został kliknięty, nie zostanie usunięty. Jeśli jednak użytkownik kliknie przycisk OK w oknie dialogowym potwierdzenia, powrót będzie kontynuowany bez szwaku, a produkt zostanie usunięty. Aby uzyskać więcej informacji na temat tej techniki, zapoznaj się z tematem Using JavaScript s Method to Control Form Submission (Używanie metody javaScript do przesyłania formularza sterującegoconfirm()
).
Dodanie niezbędnego skryptu po stronie klienta różni się nieco w przypadku korzystania z szablonów niż w przypadku używania pola polecenia. W związku z tym w tym samouczku przyjrzymy się przykładowi kontrolki FormView i GridView.
Uwaga
Korzystając z technik potwierdzenia po stronie klienta, takich jak te omówione w tym samouczku, przyjęto założenie, że użytkownicy odwiedzają przeglądarki obsługujące język JavaScript i że mają włączoną obsługę języka JavaScript. Jeśli jedno z tych założeń nie jest prawdziwe dla określonego użytkownika, kliknięcie przycisku Usuń spowoduje natychmiastowe wycofanie (nie wyświetla potwierdzenia pola komunikatu).
Krok 1. Tworzenie widoku formularza obsługującego usuwanie
Zacznij od dodania elementu FormView do ConfirmationOnDelete.aspx
strony w EditInsertDelete
folderze, powiązania go z nowym obiektem ObjectDataSource, który ściąga informacje o produkcie za pośrednictwem ProductsBLL
metody klasy .GetProducts()
Skonfiguruj również obiekt ObjectDataSource, aby ProductsBLL
metoda s DeleteProduct(productID)
klasy została zamapowana na metodę ObjectDataSource Delete()
. Upewnij się, że listy rozwijane INSERT i UPDATE są ustawione na wartość (Brak). Na koniec zaznacz pole wyboru Włącz stronicowanie w tagu inteligentnym kontrolki FormView.
Po wykonaniu tych kroków nowy znacznik deklaratywny objectDataSource będzie wyglądać następująco:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DeleteMethod="DeleteProduct" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
<DeleteParameters>
<asp:Parameter Name="productID" Type="Int32" />
</DeleteParameters>
</asp:ObjectDataSource>
Podobnie jak w naszych poprzednich przykładach, które nie używały optymistycznej współbieżności, poświęć chwilę, aby wyczyścić właściwość ObjectDataSource.OldValuesParameterFormatString
Ponieważ jest ona powiązana z kontrolką ObjectDataSource, która obsługuje tylko usuwanie, kontrolka ItemTemplate
FormView oferuje tylko przycisk Usuń, bez przycisków Nowy i Aktualizuj. Znaczniki deklaratywne w usłudze FormView zawierają jednak nadmiarowe EditItemTemplate
i InsertItemTemplate
, które można usunąć. Poświęć chwilę, aby dostosować element ItemTemplate
tak, aby pokazywał tylko podzestaw pól danych produktu. Skonfigurowano moje wyświetlanie nazwy produktu w <h3>
nagłówku powyżej nazw dostawców i kategorii (wraz z przyciskiem Usuń).
<asp:FormView ID="FormView1" AllowPaging="True" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" runat="server">
<ItemTemplate>
<h3><i><%# Eval("ProductName") %></i></h3>
<b>Category:</b>
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>'>
</asp:Label><br />
<b>Supplier:</b>
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>'>
</asp:Label><br />
<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete">
</asp:LinkButton>
</ItemTemplate>
</asp:FormView>
Dzięki tym zmianom mamy w pełni funkcjonalną stronę internetową, która umożliwia użytkownikowi przełączanie się między produktami pojedynczo z możliwością usunięcia produktu przez kliknięcie przycisku Usuń. Rysunek 2 przedstawia zrzut ekranu przedstawiający postęp do tej pory podczas przeglądania przeglądarki.
Rysunek 2. Widok formularza przedstawia informacje o pojedynczym produkcie (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2. Wywoływanie funkcji confirm(string) z przycisków usuwania Client-Side zdarzenia onclick
Po utworzeniu elementu FormView ostatnim krokiem jest skonfigurowanie przycisku Usuń, tak aby po kliknięciu go przez gościa wywołano funkcję JavaScript confirm(string)
. Dodanie skryptu po stronie klienta do elementu Button, LinkButton lub ImageButton zdarzeń po stronie onclick
klienta można wykonać za pomocą OnClientClick property
elementu , który jest nowy do ASP.NET 2.0. Ponieważ chcemy mieć zwróconą wartość confirm(string)
funkcji, po prostu ustaw tę właściwość na: return confirm('Are you certain that you want to delete this product?');
Po tej zmianie składni deklaratywnej Usuń element LinkButton powinien wyglądać następująco:
<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete"
OnClientClick="return confirm('Are you certain you want to delete this product?');">
</asp:LinkButton>
To wszystko jest do tego! Rysunek 3 przedstawia zrzut ekranu przedstawiający to potwierdzenie w akcji. Kliknięcie przycisku Usuń powoduje wyświetlenie okna dialogowego potwierdzania. Jeśli użytkownik kliknie przycisk Anuluj, postback zostanie anulowany i produkt nie zostanie usunięty. Jeśli jednak użytkownik kliknie przycisk OK, powrót będzie kontynuowany, a metoda ObjectDataSource zostanie Delete()
wywołana, zakończone usunięciem rekordu bazy danych.
Uwaga
Ciąg przekazany do confirm(string)
funkcji JavaScript jest rozdzielany apostrofami (zamiast cudzysłowów). W języku JavaScript ciągi można rozdzielać przy użyciu dowolnego znaku. W tym miejscu używamy apostrofów, aby ograniczniki ciągu przekazanego do confirm(string)
elementu nie wprowadzały niejednoznaczności z ogranicznikami używanymi dla OnClientClick
wartości właściwości.
Rysunek 3. Potwierdzenie jest teraz wyświetlane po kliknięciu przycisku Usuń (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 3. Konfigurowanie właściwości OnClientClick dla przycisku Usuń w pole polecenia
Podczas pracy z przyciskiem, elementem LinkButton lub ImageButton bezpośrednio w szablonie można skojarzyć z nim okno dialogowe potwierdzenia, konfigurując jej OnClientClick
właściwość w celu zwrócenia wyników funkcji JavaScript confirm(string)
. Jednak pole CommandField , które dodaje pole przycisków Usuń do kontrolki GridView lub DetailsView , nie ma OnClientClick
właściwości, którą można ustawić deklaratywnie. Zamiast tego musimy programowo odwołać się do przycisku Usuń w programie DataBound
obsługi zdarzeń GridView lub DetailsView, a następnie ustawić jej OnClientClick
właściwość.
Uwaga
Podczas ustawiania właściwości Przycisk OnClientClick
Usuń w odpowiedniej DataBound
procedurze obsługi zdarzeń mamy dostęp do danych powiązanych z bieżącym rekordem. Oznacza to, że możemy rozszerzyć komunikat potwierdzający, aby uwzględnić szczegóły dotyczące określonego rekordu, na przykład "Czy na pewno chcesz usunąć produkt Chai?" Takie dostosowanie jest również możliwe w szablonach przy użyciu składni powiązania danych.
Aby przećwiczyć ustawianie OnClientClick
właściwości przycisków Usuń w pole polecenia, dodajmy element GridView do strony. Skonfiguruj tę kontrolkę GridView, aby używać tej samej kontrolki ObjectDataSource używanej przez kontrolkę FormView. Ogranicz również pole BoundFields elementu GridView, aby uwzględnić tylko nazwę, kategorię i dostawcę produktu. Na koniec zaznacz pole wyboru Włącz usuwanie z tagu inteligentnego GridView. Spowoduje to dodanie pola polecenia do kolekcji GridView Columns
z jej ShowDeleteButton
właściwością ustawioną na true
.
Po wprowadzeniu tych zmian znacznik deklaratywny gridView powinien wyglądać następująco:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
</Columns>
</asp:GridView>
Pole polecenia zawiera pojedyncze wystąpienie Delete LinkButton, do którego można uzyskać dostęp programowo z programu obsługi zdarzeń usługi GridView RowDataBound
. Po odwołaniu możemy odpowiednio ustawić jej OnClientClick
właściwość. Utwórz procedurę obsługi zdarzeń RowDataBound
dla zdarzenia przy użyciu następującego kodu:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// reference the Delete LinkButton
LinkButton db = (LinkButton)e.Row.Cells[0].Controls[0];
// Get information about the product bound to the row
Northwind.ProductsRow product =
(Northwind.ProductsRow) ((System.Data.DataRowView) e.Row.DataItem).Row;
db.OnClientClick = string.Format(
"return confirm('Are you certain you want to delete the {0} product?');",
product.ProductName.Replace("'", @"\'"));
}
}
Ta procedura obsługi zdarzeń współpracuje z wierszami danych (tymi, które będą miały przycisk Usuń) i rozpoczyna się od programowego odwoływania się do przycisku Usuń. Ogólnie rzecz biorąc, należy użyć następującego wzorca:
ButtonType obj = (ButtonType) e.Row.Cells[commandFieldIndex].Controls[controlIndex];
ButtonType to typ przycisku używanego przez pole polecenia — Przycisk, LinkButton lub ImageButton. Domyślnie pole polecenia używa elementu LinkButtons, ale można to dostosować za pomocą polecenia CommandField s ButtonType property
. CommandFieldIndex jest indeksem porządkowym pola polecenia w kolekcji GridViewColumns
, natomiast kontrolkaIndex jest indeksem przycisku Usuń w kolekcji CommandFieldControls
. Wartość controlIndex zależy od położenia przycisku względem innych przycisków w pole polecenia. Jeśli na przykład jedynym przyciskiem wyświetlanym w pole polecenia jest przycisk Usuń, użyj indeksu 0. Jeśli jednak istnieje przycisk Edytuj poprzedzający przycisk Usuń, użyj indeksu 2. Przyczyną użycia indeksu 2 jest to, że dwa kontrolki są dodawane przez pole polecenia przed przyciskiem Usuń: przycisk Edytuj i Kontrolka Literału, która służy do dodawania odstępu między przyciskami Edytuj i Usuń.
W naszym konkretnym przykładzie pole CommandField używa parametru LinkButtons, a jako pole po lewej stronie ma wartość commandFieldIndex 0. Ponieważ nie ma żadnych innych przycisków, ale przycisk Usuń w pole polecenia, używamy kontrolkiIndex 0.
Po odwołaniu się do przycisku Usuń w pole polecenia możemy pobrać informacje o produkcie powiązanym z bieżącym wierszem GridView. Na koniec ustawiliśmy właściwość Przycisk OnClientClick
Usuń na odpowiedni kod JavaScript, który zawiera nazwę produktu. Ponieważ ciąg Języka JavaScript przekazywany do confirm(string)
funkcji jest rozdzielany przy użyciu apostrofów, musimy uniknąć wszelkich apostrofów, które pojawiają się w nazwie produktu. W szczególności wszelkie apostrofy w nazwie produktu są uniknięci znakiem "\'
".
Po zakończeniu tych zmian kliknięcie przycisku Usuń w elemecie GridView spowoduje wyświetlenie okna dialogowego potwierdzenia dostosowanego (zobacz Rysunek 4). Podobnie jak w przypadku skrzynki odbiorczej potwierdzenia z widoku FormView, jeśli użytkownik kliknie przycisk Anuluj postback zostanie anulowany, uniemożliwiając usunięcie.
Uwaga
Ta technika może również służyć do programowego uzyskiwania dostępu do przycisku Usuń w pole polecenia w widoku DetailsView. W przypadku elementu DetailsView należy jednak utworzyć procedurę obsługi zdarzeń dla DataBound
zdarzenia, ponieważ element DetailsView nie ma RowDataBound
zdarzenia.
Rysunek 4. Kliknięcie przycisku Usuń kontrolki GridView powoduje wyświetlenie dostosowanego okna dialogowego potwierdzenia (kliknij, aby wyświetlić obraz pełnowymiarowy)
Korzystanie z pól szablonów
Jedną z wad pola commandfield jest to, że jego przyciski muszą być dostępne za pośrednictwem indeksowania i że wynikowy obiekt musi być rzutowany do odpowiedniego typu przycisku (Button, LinkButton lub ImageButton). Używanie "liczb magicznych" i zakodowanych typów zaprasza do problemów, których nie można odnaleźć do czasu wykonania. Jeśli na przykład ty lub inny deweloper dodajesz nowe przyciski do pola polecenia w pewnym momencie w przyszłości (na przykład przycisk Edytuj) lub zmienisz ButtonType
właściwość, istniejący kod będzie nadal kompilowany bez błędów, ale odwiedzanie strony może spowodować wyjątek lub nieoczekiwane zachowanie, w zależności od tego, jak kod został napisany i jakie zmiany zostały wprowadzone.
Alternatywną metodą jest przekonwertowanie obiektów GridView i DetailsView s CommandFields na templateFields. Spowoduje to wygenerowanie pola szablonu z elementem ItemTemplate
z przyciskiem LinkButton (lub Button lub ImageButton) dla każdego przycisku w pole polecenia. Te właściwości przycisków OnClientClick
można przypisać deklaratywnie, jak pokazano w widoku FormView, lub można uzyskać do nich dostęp programowo w odpowiedniej DataBound
procedurze obsługi zdarzeń przy użyciu następującego wzorca:
ButtonType obj = (ButtonType) e.Row.FindControl("controlID");
Gdzie controlID jest wartością właściwości s przycisku ID
. Mimo że ten wzorzec nadal wymaga zakodowanego typu rzutowania, eliminuje potrzebę indeksowania, co pozwala na zmianę układu bez powodowania błędu w czasie wykonywania.
Podsumowanie
Funkcja Języka JavaScript confirm(string)
jest powszechnie używaną techniką kontrolowania przepływu pracy przesyłania formularzy. Po wykonaniu funkcja wyświetla modalne, po stronie klienta okno dialogowe zawierające dwa przyciski, OK i Anuluj. Jeśli użytkownik kliknie przycisk OK, confirm(string)
funkcja zwróci wartość true
. Kliknięcie przycisku Anuluj zwraca wartość false
. Ta funkcja, w połączeniu z zachowaniem przeglądarki w celu anulowania przesyłania formularza, jeśli program obsługi zdarzeń podczas procesu przesyłania zwraca false
wartość , może służyć do wyświetlania pola komunikatu potwierdzenia podczas usuwania rekordu.
Funkcję confirm(string)
można skojarzyć z procedurą obsługi zdarzeń po stronie klienta kontrolki Przycisk onclick
za pomocą właściwości s kontrolki OnClientClick
. Podczas pracy z przyciskiem Usuń w szablonie — w jednym z szablonów kontrolki FormView lub w polu TemplateField w widoku DetailsView lub GridView — tę właściwość można ustawić deklaratywnie lub programowo, jak pokazano w tym samouczku.
Szczęśliwe programowanie!
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.