删除时添加客户端确认42
简介
正如我们前面教程 在 DataList 中进行数据编辑与删除操作概述中看到的,可以通过以下方式向 DataList 添加删除支持:
- 向 DataList 的 ItemTemplate 添加 Button 、LinkButton 或ImageButton Web 控件;
- 将 Delete 按钮的 CommandName 属性设置为 “Delete” ,以及
- 从 DataList 的 DeleteCommand Event Handler 调用相应的 BLL 删除方法(然后重新绑定数据以便刚删除的项目从DataList 的项目中删除)。
从最终用户的观点来看,单击项目的Delete 按钮能引起回传和删除所选项目,并从 DataList 中将其删除。但是当用户单击 Delete 按钮时,此默认界面没有任何形式的确认。如果用户想单击 Edit 时意外单击了Delete 按钮,则原本要更新的记录将被删除。为了防止这种情况出现,可以添加一个客户端确认对话框,当单击 Delete 按钮时出现该对话框。
JavaScript confirm(string) 函数将其字符串输入参数显示为带两个按钮(OK 和 Cancel )的模态对话框内的文本(参见图 1 )。 confirm(string) 函数根据用户单击的是哪一个按钮返回一个布尔值(如果用户单击 OK 则返回 true ,如果单击 Cancel 则返回 false )。
图1:JavaScript confirm(string) 方法显示一个模态客户端消息框
在表单提交期间,如果从客户端 Event Handler 返回 false 值,则浏览器取消表单提交。使用此功能,我们可以让Delete 按钮的客户端 onclick Event Handler 返回对confirm(" Are you certain that you want to delete this product?") 调用得到的值。如果用户单击 Cancel , confirm(string) 将返回 false 值,从而取消表单提交。如果没有回传,将不会删除被单击 Delete 按钮的产品。不过,如果用户在确认对话框中单击 OK ,回传将继续进行,而产品记录将被删除。有关本技技的更多信息,请参考 使用 JavaScript 的 confirm()方法来控制表单提交。
本教程中,我们将了解怎样向 DataList 中的 Delete 按钮添加这样的客户端确认。
注意:正如本教程中所讨论的,使用客户端确认的方法是假设用户正在使用支持 JavaScript 并且启用了 JavaScript 的浏览器进行访问。如果这些假设对于某个特定用户不成立,则单击 Delete 按钮将立即引起回传(不显示确认消息框)并且删除记录。
步骤1:创建带有 Delete 按钮的 DataList
在我们讨论如何添加客户端确认之前,首先需要一个 DataList ,可以从它删除记录。首先打开 EditDeleteDataList 文件夹中的 ConfirmationOnDelete.aspx 页将 DataList 从工具箱拖放到设计器上,并将其 ID 属性设置为 Products 。接下来,从DataList 的智能标记创建一个名称为 ProductsDataSource 的新的 ObjectDataSource 。将此 ObjectDataSource 配置为使用 ProductsBLL 类的 GetProducts() 方法来检索记录(参见图2 )。由于我们将通过从 DataList 的 DeleteCommand Event Handler 直接与BLL 相联系来执行删除,因此将 Configure Data Source 向导的 INSERT 、UPDATE 和 DELETE 选项卡中的下拉列表设置为“(None)” ,如图 3 所示。
图2 :将 ProductsDataSource 配置为使用 ProductsBLL 类的 GetProducts() 方法
图3 :将 INSERT 、UPDATE 和 DELETE 选项卡的下拉列表设置为 “(None)”
完成 Configure Data Source 向导之后,Visual Studio 将为 DataList 创建一个默认的 ItemTemplate—— 每个数据字段的名称后面都是一个用来显示值的Web 标签控件。更新 ItemTemplate 以便它只显示产品的名称、类别和供应商。再添加一个Delete 按钮并将其 CommandName 属性设置为 “Delete” 。进行这些更改之后,DataList 和 ObjectDataSource 的声明式语法应该与以下类似:
<asp:DataList ID="Products" runat="server" DataKeyField="ProductID"
DataSourceID="ProductsDataSource">
<ItemTemplate>
<h3>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>' />
</h3>
Category:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>' />
<br />
Supplier:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>' />
<br />
<br />
<asp:Button runat="server" ID="DeleteButton"
CommandName="Delete" Text="Delete" />
<br />
<br />
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
图 4 显示通过浏览器查看时此页的样子。由于尚未创建DeleteCommand Event Handler ,因此单击 Delete 只是引起回传,而 DataList 保持不变。
图4 :显示每个产品的名称、供应商和类别以及一个Delete 按钮
步骤2 :添加 DeleteCommand Event Handler
当用户单击Delete 按钮时,出现回传并且触发 DataList 的 ItemCommand 和DeleteCommand events 事件。无论何时从 DataList 中引发 Command 事件都会触发 ItemCommand 事件;此外还引发DeleteCommand 事件,因为引起 Command 事件触发的 Button 将其 CommandName 属性设置为 “Delete” 。
要删除记录以响应被单击的 Delete 按钮,需要完成以下任务:
- 为 DataList 的 DeleteCommand 事件创建一个Event Handler ;
- 确定 Delete 按钮被单击的项目的 ProductID ;
- 调用 ProductBLL 类的 DeleteProduct 方法,以及
- 将数据重新绑定到 DataList 。
必需的代码显示在下面;有关对代码的详细解释,请参考 在DataList 中编辑和删除数据概述教程。
protected void Products_DeleteCommand(object source, DataListCommandEventArgs e)
{
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
// Delete the data
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.DeleteProduct(productID);
// Rebind the data to the DataList
Products.DataBind();
}
步骤3 :向Delete 按钮添加客户端确认
完成DeleteCommand Event Handler 之后,最后的任务是向 Delete 按钮添加客户端确认。这可以以声明方式或通过编程来实现。最简单的方法是通过Button 的 OnClientClick 属性 以声明方式来指定确认。但是,如果确认消息或逻辑依赖于在运行时才能确定的因素,则我们可以在DataList 的 ItemDataBound Event Handler 中引用Delete 按钮并通过编程来设置其 OnClientClick 属性。
让我们来探讨这两个选项,先讨论声明方式这种方法。要添加客户端确认,只需将 Button 的 OnClientClick 属性设置为返回 confirm(message) 。例如,要让确认消息显示为“ Are you certain that you want to delete this product? ”,可以更新 Delete 按钮的声明式标记以便如下所示:
<asp:Button runat="server" ID="DeleteButton" CommandName="Delete" Text="Delete"
OnClientClick="return confirm('Are you sure you want to delete this product?');" />
进行更改之后,单击Delete 按钮会显示出一个模态确认对话框(参见图 5 )。只有当用户单击 Ok 按钮时才出现回传—— 只有此时产品才被删除。
图5 :单击 Delete 按钮可以显示出一个客户端确认对话框
注意:由于使用单引号来分隔传递到 JavaScript confirm 函数的字符串,因此输入字符串内的任何单引号都必须使用\' 来进行转义。也就是说,如果想要将字符串 “You’re sure you want to do this?” 传递到 confirm 方法,就必须将 “You’re” 中的单引号转义,如下所示:return confirm('You\'re sure you want to do this?');.
当为所有的 DataList 项目都显示静态确认对话框时 , 声明方式这种方法能很好地工作。但是,要在逐项的基础上自定义确认消息,就需要通过编程来设置此属性。在每个记录都绑定到DataList 之后触发 DataList 的 ItemDataBound 事件。通过为此事件创建Event Handler , 我们可以引用Delete 按钮并根据绑定到DataList 项目的数据通过编程设置其OnClientClick 属性。以下 ItemDataBound Event Handler 说明如何使确认消息包含产品名称:
protected void Products_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Reference the data bound to the DataListItem
Northwind.ProductsRow product =
(Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
// Reference the Delete button
Button db = (Button)e.Item.FindControl("DeleteButton");
// Assign the Delete button's OnClientClick property
db.OnClientClick =
string.Format("return confirm('Are you sure that you want to delete" +
" the product {0}?');", product.ProductName.Replace("'", @"\'"));
}
}
由于对绑定到DataList 的所有行都可以触发 ItemDataBound 事件—— 包括页眉、脚注和分隔符项—— 因而确保我们正在处理一个项目或替代项目就很重要,因为这些是从ItemTemplate 呈现的项类型。接下来,我们访问 DataListItem 的DataItem 属性,它包含对用于创建此项的 ProductsRow 实例的引用。最后,通过 FindControl("controlID") 方法引用 Delete 按钮并将确认消息 “ Are you sure that you want to delete the product productName? ” 赋给其 OnClientClick 属性。注意产品名中的任何单引号都要进行转义。
在使用编程方式代替声明方式的方法之后花些时间来测试页面。当这次单击 Delete 按钮时,确认消息中包含产品的名称。图 6 显示的是单击 Chai Tea 的 Delete 按钮时的输出。
图6 :现在确认对话框包含产品的名称
小结
JavaScript confirm(string) 函数是用于控制表单提交工作流的常用技术。执行后,该函数显示一个模态客户端对话框,对话框包含两个按钮( OK 和 Cancel )。如果用户单击 OK ,confirm(string) 函数返回 true ; 单击Cancel 则返回 false 。此功能与浏览器的行为结合使用 , 如果 Event Handler 在提交过程中返回 false , 可以用来取消表单提交 , 还可以用来在删除记录时显示确认消息框。
通过控件的OnClientClick 属性confirm(string) 函数可以与Web 按钮控件的客户端 onclick Event Handler 相关联。如同我们在本教程中所看到的,当在 DataList 中使用 Delete 按钮时,可以以声明方式或通过编程设置此属性。
快乐编程!