Přidání potvrzení odstranění na straně klienta (VB)
V rozhraních, která jsme zatím vytvořili, může uživatel nechtěně odstranit data kliknutím na tlačítko Odstranit, když chtěl kliknout na tlačítko Upravit. V tomto kurzu přidáme potvrzovací dialogové okno na straně klienta, které se zobrazí po kliknutí na tlačítko Odstranit.
Úvod
Během několika minulých kurzů jsme viděli, jak používat naši architekturu aplikace ObjectDataSource a ovládací prvky data web společně k poskytování možností vkládání, úprav a odstraňování. Odstraňovací rozhraní, která jsme dosud prozkoumali, se skládají z tlačítka Odstranit, které při kliknutí způsobí postback a vyvolá metodu ObjectDataSource s Delete()
. Metoda Delete()
pak vyvolá nakonfigurovanou metodu z vrstvy obchodní logiky, která rozšíří volání do vrstvy přístupu k datům a vygeneruje skutečný DELETE
příkaz do databáze.
Zatímco toto uživatelské rozhraní umožňuje návštěvníkům odstranit záznamy prostřednictvím GridView, DetailsView, nebo FormView ovládací prvky, chybí jakýkoli druh potvrzení, když uživatel klikne na tlačítko Odstranit. Pokud uživatel omylem klikne na tlačítko Odstranit, když chtěl kliknout na Upravit, záznam, který chtěl aktualizovat, se místo toho odstraní. Abychom tomu předešli, přidáme v tomto kurzu potvrzovací dialogové okno na straně klienta, které se zobrazí po kliknutí na tlačítko Odstranit.
Funkce JavaScriptu confirm(string)
zobrazí vstupní parametr řetězce jako text uvnitř modálního dialogového okna, které je vybaveno dvěma tlačítky – OK a Zrušit (viz Obrázek 1). Funkce confirm(string)
vrátí logickou hodnotu v závislosti na kliknutí na tlačítko (true
pokud uživatel klikne na OK a false
jestli klikne na Zrušit).
Obrázek 1: Metoda JavaScriptu confirm(string)
zobrazí modální Client-Side messagebox
Pokud se během odesílání formuláře vrátí hodnota false
z obslužné rutiny události na straně klienta, odeslání formuláře se zruší. Pomocí této funkce můžeme nechat obslužnou rutinu události na straně onclick
klienta odstranit tlačítko vrátit hodnotu volání .confirm("Are you sure you want to delete this product?")
Pokud uživatel klikne na Zrušit, confirm(string)
vrátí hodnotu false, což způsobí zrušení odeslání formuláře. Bez zpětného odeslání se produkt, na který jste klikli na tlačítko Odstranit, neodstraní. Pokud však uživatel klikne v potvrzovací dialogovém okně na OK, zpětné odeslání bude pokračovat bez omezení a produkt se odstraní. Další informace o této technice confirm()
najdete v tématu Použití metody řízení odesílání formulářů pomocí javascriptové metody .
Přidání potřebného skriptu na straně klienta se mírně liší při použití šablon od použití CommandField. Proto se v tomto kurzu podíváme na příklad FormView i GridView.
Poznámka
Při použití technik potvrzení na straně klienta, jako jsou ty probírané v tomto kurzu, se předpokládá, že vaši uživatelé používají prohlížeče, které podporují JavaScript, a že mají povolený JavaScript. Pokud některý z těchto předpokladů není pro konkrétního uživatele pravdivý, kliknutím na tlačítko Odstranit okamžitě dojde k zpětnému odeslání (nezobrazí se potvrzovací okno se zprávou).
Krok 1: Vytvoření ovládacího prvku FormView, který podporuje odstranění
Začněte přidáním objektu FormView na ConfirmationOnDelete.aspx
stránku ve EditInsertDelete
složce a vytvořte vazbu s novým objektem ObjectDataSource, který prostřednictvím metody třídy s GetProducts()
stáhne informace o ProductsBLL
produktu. Nakonfigurujte také ObjectDataSource tak, aby ProductsBLL
byla metoda třídy s DeleteProduct(productID)
namapována na metodu ObjectDataSource s Delete()
. Zajistěte, aby rozevírací seznamy karet INSERT a UPDATE byly nastaveny na hodnotu (None). Nakonec zaškrtněte políčko Enable Paging (Povolit stránkování) v inteligentní značce FormView.
Po provedení těchto kroků bude nový deklarativní kód ObjectDataSource vypadat takto:
<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>
Stejně jako v našich minulých příkladech, které nepoužíly optimistickou souběžnost, chvíli se vymazejte vlastnost ObjectDataSource OldValuesParameterFormatString
.
Vzhledem k tomu, že byla vázána na ObjectDataSource ovládací prvek, který podporuje pouze odstranění, FormView ItemTemplate
s nabízí pouze tlačítko Odstranit, chybí tlačítka New a Update. Deklarativní kód FormView však obsahuje nadbytečné EditItemTemplate
a InsertItemTemplate
, které lze odebrat. Chvíli si přizpůsobte ItemTemplate
, aby se zobrazovala jenom podmnožina polí s daty o produktech. Nakonfiguroval jsem svůj tak, aby zobrazoval název produktu v nadpisu <h3>
nad názvem dodavatele a kategorie (spolu s tlačítkem Odstranit).
<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>
Díky těmto změnám máme plně funkční webovou stránku, která uživateli umožňuje přepínat produkty po jednom, s možností odstranit produkt jednoduchým kliknutím na tlačítko Odstranit. Obrázek 2 ukazuje snímek obrazovky s naším dosavadním pokrokem při prohlížení v prohlížeči.
Obrázek 2: Objekt FormView zobrazuje informace o jednom produktu (kliknutím zobrazíte obrázek v plné velikosti)
Krok 2: Volání funkce confirm(string) z odstranit tlačítka Client-Side onclick Událost
Po vytvoření objektu FormView je posledním krokem konfigurace tlačítka Odstranit tak, aby se při kliknutí návštěvníkem vyvolala funkce JavaScriptu confirm(string)
. Přidání skriptu na straně klienta do události Button, LinkButton nebo ImageButton na straně onclick
klienta lze provést pomocí OnClientClick property
, který je v ASP.NET 2.0 novinkou. Vzhledem k tomu, že chceme vrátit hodnotu confirm(string)
funkce, jednoduše nastavte tuto vlastnost na: return confirm('Are you certain that you want to delete this product?');
Po této změně by deklarativní syntaxe Delete LinkButton měla vypadat přibližně takto:
<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 je všechno! Obrázek 3 ukazuje snímek obrazovky s tímto potvrzením v akci. Kliknutím na tlačítko Odstranit se zobrazí dialogové okno pro potvrzení. Pokud uživatel klikne na Zrušit, postback se zruší a produkt se neodstraní. Pokud však uživatel klikne na OK, postback pokračuje a objectDataSource s Delete()
metoda je vyvolána, což vyvrcholilo odstranění záznamu databáze.
Poznámka
Řetězec předaný funkci JavaScriptu confirm(string)
je oddělený apostrofy (nikoli uvozovkami). V JavaScriptu je možné řetězce oddělovat pomocí libovolného znaku. Apostrofy zde používáme, aby oddělovače pro řetězec předaný do confirm(string)
nezanesly nejednoznačnost s oddělovači použitými pro OnClientClick
hodnotu vlastnosti.
Obrázek 3: Po kliknutí na tlačítko Odstranit se teď zobrazí potvrzení (kliknutím zobrazíte obrázek v plné velikosti)
Krok 3: Konfigurace vlastnosti OnClientClick pro tlačítko Odstranit v CommandField
Při práci s Button, LinkButton nebo ImageButton přímo v šabloně můžete přidružit potvrzovací dialogové okno jednoduše tak, že nakonfigurujete jeho OnClientClick
vlastnost tak, aby vracela výsledky funkce JavaScriptu confirm(string)
. Pole CommandField , které přidává pole tlačítka Odstranit do objektu GridView nebo DetailsView, však neobsahuje OnClientClick
vlastnost, kterou lze deklarativně nastavit. Místo toho musíme programově odkazovat na tlačítko Odstranit v GridView nebo DetailsView příslušné DataBound
obslužné rutiny události a pak nastavit jeho OnClientClick
vlastnost tam.
Poznámka
Při nastavování vlastnosti tlačítka OnClientClick
Odstranit v příslušné DataBound
obslužné rutině události máme přístup k datům svázaná s aktuálním záznamem. To znamená, že můžeme rozšířit potvrzovací zprávu tak, aby obsahovala podrobnosti o konkrétním záznamu, například "Opravdu chcete produkt Chai odstranit?". Takové přizpůsobení je také možné v šablonách pomocí syntaxe vazby dat.
Pokud si chcete procvičit nastavení OnClientClick
vlastnosti pro tlačítka Delete v CommandField, pojďme na stránku přidat Objekt GridView. Nakonfigurujte tento objekt GridView tak, aby používal stejný ovládací prvek ObjectDataSource, který formView používá. Také omezte BoundFields GridView tak, aby zahrnoval pouze název produktu, kategorii a dodavatele. Nakonec zaškrtněte políčko Povolit odstranění u inteligentní značky GridView. Tím přidáte CommandField do kolekce GridView s Columns
jeho ShowDeleteButton
vlastností nastavenou na true
.
Po provedení těchto změn by deklarativní značky GridView měly vypadat takto:
<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>
CommandField obsahuje jednu Delete LinkButton instance, ke které lze přistupovat programově z GridView obslužné RowDataBound
rutiny události. Jakmile na tento odkaz odkazujeme, můžeme odpovídajícím způsobem nastavit jeho OnClientClick
vlastnost. Vytvořte obslužnou rutinu RowDataBound
události pro událost pomocí následujícího kódu:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
' reference the Delete LinkButton
Dim db As LinkButton = CType(e.Row.Cells(0).Controls(0), LinkButton)
' Get information about the product bound to the row
Dim product As Northwind.ProductsRow = _
CType(CType(e.Row.DataItem, System.Data.DataRowView).Row, _
Northwind.ProductsRow)
db.OnClientClick = String.Format( _
"return confirm('Are you certain you want to delete the {0} product?');", _
product.ProductName.Replace("'", "\'"))
End If
End Sub
Tato obslužná rutina události pracuje s řádky dat (ty, které budou mít tlačítko Odstranit) a začíná programovým odkazem na tlačítko Odstranit. Obecně použijte následující vzor:
Dim obj As ButtonType = _
CType(e.Row.Cells(commandFieldIndex).Controls(controlIndex), ButtonType)
ButtonType je typ tlačítka, které používá CommandField – Button, LinkButton nebo ImageButton. Ve výchozím nastavení používá CommandField LinkButtons, ale to lze přizpůsobit pomocí CommandField s ButtonType property
. CommandFieldIndex je pořadový index CommandField v rámci GridView s Columns
kolekce, zatímco controlIndex je index tlačítka Odstranit v kolekci CommandField.Controls
Hodnota controlIndex závisí na umístění tlačítka vzhledem k ostatním tlačítkům v CommandField. Pokud je například jediným tlačítkem zobrazeným v CommandField tlačítko Odstranit, použijte index 0. Pokud je však před tlačítkem Odstranit tlačítko Upravit, použijte index 2. Důvodem použití indexu 2 je to, že CommandField před tlačítko Odstranit jsou přidány dva ovládací prvky: tlačítko Edit a LiteralControl, který se používá k přidání mezery mezi tlačítka Edit a Delete.
Pro náš konkrétní příklad CommandField používá LinkButtons a jako pole úplně vlevo má commandFieldIndex 0. Vzhledem k tomu, že v CommandField nejsou žádná další tlačítka kromě tlačítka Odstranit, použijeme controlIndex 0.
Po odkazování na tlačítko Odstranit v CommandField, dále vezmeme informace o produktu svázané s aktuálním řádkem GridView. Nakonec nastavíme vlastnost tlačítka OnClientClick
Odstranit na příslušný JavaScript, který obsahuje název produktu. Vzhledem k tomu, že javascriptový řetězec předaný do confirm(string)
funkce je oddělený pomocí apostrofů, musíme všechny apostrofy, které se objeví v názvu produktu, utéct. Zejména všechny apostrofy v názvu produktu jsou uváděné znakem "\'
".
Po dokončení těchto změn se po kliknutí na tlačítko Odstranit v zobrazení GridView zobrazí přizpůsobené potvrzovací dialogové okno (viz Obrázek 4). Stejně jako u potvrzovacího pole zprávy z ovládacího prvku FormView, pokud uživatel klikne na Zrušit, zpětné odeslání se zruší, čímž se zabrání odstranění.
Poznámka
Tuto techniku lze použít také pro programový přístup k tlačítku Odstranit v CommandField v zobrazení DetailsView. Pro DetailsView však můžete vytvořit obslužnou rutinu DataBound
události pro událost, protože DetailsView nemá RowDataBound
událost.
Obrázek 4: Kliknutím na tlačítko Odstranit gridView zobrazíte vlastní potvrzovací dialogové okno (kliknutím zobrazíte obrázek v plné velikosti).
Použití polí šablon
Jednou z nevýhod CommandField je, že k jeho tlačítkům musí být přístup prostřednictvím indexování a že výsledný objekt musí být přetypován na příslušný typ tlačítka (Button, LinkButton nebo ImageButton). Použití "kouzelných čísel" a pevně zakódovaných typů vyvolává problémy, které nelze zjistit, dokud se nedají zjistit za běhu. Pokud například vy nebo jiný vývojář přidáte do pole CommandField v určitém okamžiku v budoucnu nová tlačítka (například tlačítko Upravit) nebo změníte ButtonType
vlastnost, stávající kód se stále zkompiluje bez chyby, ale při návštěvě stránky může dojít k výjimce nebo neočekávanému chování v závislosti na tom, jak byl kód napsán a jaké změny byly provedeny.
Alternativním přístupem je převést Objekty CommandFields GridView a DetailsView na TemplateFields. Tím se vygeneruje TemplateField s objektem ItemTemplate
, který má tlačítko LinkButton (nebo Tlačítko nebo ImageButton) pro každé tlačítko v CommandField. Tyto vlastnosti tlačítek OnClientClick
se dají přiřadit deklarativně, jak jsme viděli v zobrazení FormView, nebo je možné k těmto vlastnostem přistupovat programově v příslušné DataBound
obslužné rutině události pomocí následujícího vzoru:
Dim obj As ButtonType = CType(e.Row.FindControl("controlID"), ButtonType)
Kde controlID je hodnota vlastnosti s ID
tlačítka. I když tento vzor stále vyžaduje pevně zakódovaný typ pro přetypování, odstraňuje potřebu indexování, což umožňuje, aby se rozložení změnilo, aniž by to vedlo k chybě za běhu.
Souhrn
Funkce JavaScriptu confirm(string)
je běžně používaná technika řízení pracovního postupu odeslání formuláře. Po spuštění funkce zobrazí modální dialogové okno na straně klienta, které obsahuje dvě tlačítka OK a Zrušit. Pokud uživatel klikne na OK, confirm(string)
funkce vrátí true
; kliknutím na Zrušit vrátí .false
Tuto funkci spolu s chováním prohlížeče ke zrušení odeslání formuláře, pokud obslužná rutina události během procesu odeslání vrátí false
, lze použít k zobrazení potvrzovací zprávy při odstraňování záznamu.
Funkce confirm(string)
může být přidružena k obslužné rutině události webového ovládacího prvku button na straně onclick
klienta prostřednictvím vlastnosti ovládacího prvku s OnClientClick
. Při práci s tlačítkem Odstranit v šabloně – buď v jedné ze šablon FormView s, nebo v TemplateField v DetailsView nebo GridView – lze tuto vlastnost nastavit deklarativně nebo programově, jak jsme viděli v tomto kurzu.
Šťastné programování!
O autorovi
Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .