惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
V
V2EX
博客园 - 【当耐特】
Vercel News
Vercel News
雷峰网
雷峰网
爱范儿
爱范儿
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
NISL@THU
NISL@THU
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
P
Proofpoint News Feed
B
Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
K
Kaspersky official blog
I
InfoQ
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
V
Visual Studio Blog
AI
AI
Schneier on Security
Schneier on Security
B
Blog RSS Feed
T
Tor Project blog
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Cyber Attacks, Cyber Crime and Cyber Security
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
V2EX - 技术
V2EX - 技术
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
Arctic Wolf
Webroot Blog
Webroot Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main

博客园 - 冷火

Lucene.Net学习 Argotic Syndication Framework生成RSS - 冷火 如何在C#中实现图片缩放 [ASP.NET] 限制上传文件类型的两种方法 asp.net采集 在C#怎用一条正则表达式验证用逗号隔开的email地址 关于LumiSoft.Net.POP3.Client接收邮件例子(包括附件) dhtmlXTreeprofessional asp.net导出xml文件 - 冷火 - 博客园 DateDiff Datagridview下一行下一行 GridView控件修改、删除示例(修改含有DropDownList控件) - 冷火 - 博客园 局域网QQ第三版(V1.4) asp.net+JSON+AJAX(基于prototype1.4)做无刷新的2级DropDownList - 冷火 - 博客园 非常好的菜单效果(Accordion风格) 静功解决失眠的问题 ASP.NET中文验证码详解 log4net Config Examples 对XAML进行编辑的辅助类(XamlHelper)
Confirm GridView Deletes with the ModalPopupExtender
冷火 · 2010-02-09 · via 博客园 - 冷火

I was looking for good examples of how the ModalPopupExtender control could be used as a confirmation dialog. I was especially curious in seeing implementations where the popup is used to confirm deletes performed on rows of a GridView. I couldn't find any good samples so I figured I would take a shot at it.

Live Demo

If you would like to view a running version of the sample, just follow the Live Demo link. If don't really care about the step by step break down of this implementation you can jump to the bottom of the page to view the full code sample. As always, feedback is encouraged.

Step 1: Add the GridView to your page, placing it inside an UpdatePanel.
<asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblTitle" runat="server" Text="ToDo List" BackColor="lightblue" Width="95%" />
<asp:GridView
ID="gvToDoList" runat="server" AutoGenerateColumns="false" Width="95%">
<AlternatingRowStyle BackColor="aliceBlue" />
<HeaderStyle HorizontalAlign="Left" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:BoundField DataField="Item" HeaderText="Description" />
<asp:BoundField DataField="IsCompleted" HeaderText="Complete?" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>

Nothing out of the ordinary here, just a basic GridView contained in an UpdatePanel (don't forget to set UpdateMode to Conditional)

Step 2: Add a TemplateField with a Delete button. Wire up an event handler for the button click.
<asp:TemplateField ControlStyle-Width="50px" HeaderStyle-Width="60px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" OnClick="BtnDelete_Click" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>

You can either explicitly use the OnClick event of the delete button or add the CommandName attribute and implement the RowDeleting event. I chose the former for this sample.

* I also thought about adding the ModalPopupExtender embedded in each of the ItemTemplates and having the OK button just be the delete command for the row. I didn't go down this path because doing so would have included all of the popup markup for each row in the grid. Usual page size's for our gridview is anywhere from 25 to 50 rows. So this didn't seem like a good approach.

Step 3: Add the HTML markup for the modal popup.

<div id="div" runat="server" align="center" class="confirm" style="display:none">
<img align="absmiddle" src="Img/warning.jpg" />Are you sure you want to delete this item?
<asp:Button ID="btnOk" runat="server" Text="Yes" Width="50px" />
<asp:Button ID="btnNo" runat="server" Text="No" Width="50px" />
</div>

Nothing fancy here, just a div with a couple of buttons and a warning image:

* I have explicitly set the style to none on my container elements when using the ModalPopupExtender to avoid the initial flicker that sometimes occurs. Has anyone else seen this?

Step 4: Add the ModalPopupExtender to the page.
<ajaxToolKit:ModalPopupExtender
runat="server" BehaviorID="mdlPopup"
TargetControlID="div" PopupControlID="div"
OkControlID="btnOk" CancelControlID="btnNo" BackgroundCssClass="modalBackground"
/>

Once the ModalPopupExtender has been added to the page, you can go ahead and configure its attributes. The PopupControlID is the id of the div we created in Step 3 that contains the markup we want displayed by the ModalPopup. The OkControlID refers to the ID of the OK button and the CancelControlID refers to the Cancel button (clicking either will dismiss the popup).

In most cases the TargetControlID would point to the button that causes the ModalPopup to be displayed. But for this example, we will always be hiding and showing the popup explicitly from javascript, we can just point this property to our div (this is a required property so we have to set it to something. Some people recommend putting a hidden button or some other element on the page to fake it out, but here I am just setting it to our div).

* I have noticed that the ModalPopup will not be automatically dismissed if it is explicitly displayed using the show method of the animation. Does anyone know if this is a bug or the desired behavior?

Step 5: Add an OnClientClick for the delete button
<asp:TemplateField ControlStyle-Width="50px" HeaderStyle-Width="60px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button
ID="btnDelete" runat="server" OnClientClick="showConfirm(this); return false;"
OnClick="BtnDelete_Click" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>

Next we go back to the markup for our delete button and add the OnClientClick attribute. For the value, we invoke the showConfirm javascript function (created in the next step) passing it a reference to the delete button element. The OnClientClick handler also returns false so the page won't postback after the client script is done running. If this isn't done the delete will happen before the user has a chance to confirm or disallow it!

Step 6: Add the supporting javascript
<script type="text/javascript">
// keeps track of the delete button for the row
// that is going to be removed
var _source;
// keep track of the popup div
var _popup;

function showConfirm(source){
this._source = source;
this._popup = $find('mdlPopup');

// find the confirm ModalPopup and show it
this._popup.show();
}

function okClick(){
// find the confirm ModalPopup and hide it
this._popup.hide();
// use the cached button as the postback source
__doPostBack(this._source.name, '');
}

function cancelClick(){
// find the confirm ModalPopup and hide it
this._popup.hide();
// clear the event source
this._source = null;
this._popup = null;
}
</script>
<ajaxToolKit:ModalPopupExtender BehaviorID="mdlPopup" runat="server"
TargetControlID="div" PopupControlID="div"
OkControlID="btnOk" OnOkScript="okClick();"
CancelControlID="btnNo" OnCancelScript="cancelClick();" BackgroundCssClass="modalBackground" />

Now we can implement the final piece. In the previous step, we wired the OnClientClick event of the delete button to the showConfirm javascript function. Now we can implement this function. First we store a reference to the delete button as well as display the modal popup by calling show() on the modal popups animation component (note: in ASP.NET AJAX, DOM elements are retrieved using $get('id') and components are retrieved using $find('id')). The reference to the delete button is stored so we can use it later to initiate the postback (if the user did indeed confirm the delete).

Finally, the ModalPopupExtender contains two properties that allow you to hook into the OK and Cancel buttons and run a little bit of code on the client when the dialog is dismissed. We will hook into both of these events to hide the dialog as well as start the postback causing the item to be deleted if the delete was confirmed.

Step 7: Put it all together.

Here is the complete listing for this page. Again, you can view this page in action here.

Enjoy!

<%@ Page Language="C#" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head" runat="server">
<title>Delete Confirm Example</title>
<script runat="server">
/// <summary>
///
/// </summary>
public class ToDo
{
private int _id;
private string _item;
private bool _isCompleted;

public ToDo(int id, string item, bool isCompleted)
{
this._id = id;
this._item = item;
this._isCompleted = isCompleted;
}

public int ID
{
get { return this._id; }
}

public string Item
{
get { return this._item; }
}

public bool IsCompleted
{
get { return this._isCompleted; }
}
}

/// <summary>
///
/// </summary>
private System.Collections.Generic.List<ToDo> ToDoList
{
get
{
System.Collections.Generic.List<ToDo> item = this.Session["ToDoList"] as System.Collections.Generic.List<ToDo>;

if (item == null)
{
item = new System.Collections.Generic.List<ToDo>();
item.Add(new ToDo(1, "Go to the store", false));
item.Add(new ToDo(2, "Go to work", true));
item.Add(new ToDo(3, "Feed the dog", false));
item.Add(new ToDo(4, "Take a nap", true));
item.Add(new ToDo(5, "Eat some lunch", false));

this.Session["ToDoList"] = item;
}

return item;
}
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.gvToDoList.DataSource = this.ToDoList;
this.gvToDoList.DataBind();
}
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void BtnDelete_Click(object sender, EventArgs e)
{
// get the gridviewrow from the sender so we can get the datakey we need
Button btnDelete = sender as Button;
GridViewRow row = (GridViewRow)btnDelete.NamingContainer;
// find the item and remove it
ToDo itemToRemove = this.ToDoList[row.RowIndex];
this.ToDoList.Remove(itemToRemove);
// rebind the datasource
this.gvToDoList.DataSource = this.ToDoList;
this.gvToDoList.DataBind();
}

</script>
<script type="text/javascript">
// keeps track of the delete button for the row
// that is going to be removed
var _source;
// keep track of the popup div
var _popup;

function showConfirm(source){
this._source = source;
this._popup = $find('mdlPopup');

// find the confirm ModalPopup and show it
this._popup.show();
}

function okClick(){
// find the confirm ModalPopup and hide it
this._popup.hide();
// use the cached button as the postback source
__doPostBack(this._source.name, '');
}

function cancelClick(){
// find the confirm ModalPopup and hide it
this._popup.hide();
// clear the event source
this._source = null;
this._popup = null;
}
</script>
<style>
.modalBackground {
background-color:Gray;
filter:alpha(opacity=70);
opacity:0.7;
}
.confirm{
background-color:White;
padding:10px;
width:370px;
}
</style>
</head>
<body>
<form id="form" runat="server" style="font-family:Trebuchet MS;">
<asp:ScriptManager ID="scriptManager" runat="server" />
<div>
<p style="background-color:AliceBlue; width:95%">
Example of using a ModalPopupExtender as a delete confirm button<br />
for the indivdual rows of a GridView. To test out the functionality,<br />
click the Delete button of any of the rows and watch what happens.<br />
</p>
<br />
<asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblTitle" runat="server" Text="ToDo List" BackColor="lightblue" Width="95%" />
<asp:GridView
ID="gvToDoList" runat="server" AutoGenerateColumns="false" Width="95%">
<AlternatingRowStyle BackColor="aliceBlue" />
<HeaderStyle HorizontalAlign="Left" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:BoundField DataField="Item" HeaderText="Description" />
<asp:BoundField DataField="IsCompleted" HeaderText="Complete?" />
<asp:TemplateField ControlStyle-Width="50px" HeaderStyle-Width="60px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button
ID="btnDelete" runat="server" OnClientClick="showConfirm(this); return false;"
OnClick="BtnDelete_Click" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<ajaxToolKit:ModalPopupExtender BehaviorID="mdlPopup" runat="server"
TargetControlID="div" PopupControlID="div"
OkControlID="btnOk" OnOkScript="okClick();"
CancelControlID="btnNo" OnCancelScript="cancelClick();" BackgroundCssClass="modalBackground" />
<div id="div" runat="server" align="center" class="confirm" style="display:none">
<img align="absmiddle" src="Img/warning.jpg" />Are you sure you want to delete this item?
<asp:Button ID="btnOk" runat="server" Text="Yes" Width="50px" />
<asp:Button ID="btnNo" runat="server" Text="No" Width="50px" />
</div>
</div>
</form>
</body>
</html>