Asked by:
Asking the user to confirm that they want to continue with an action

Question
-
User-760709272 posted
This thread is going to cover the basics of prompting a user if they want to continue with a certain action. The process flow is as follows; the user kicks off a form submission that causes some code to run in code-behind, that code causes a confirmation warning to be shown to the client, if the user chooses to continue then your confirmation code is invoked and the process is completed.
Note this demo is really for when you want a two-step process where you run some server-side code before you ask for a confirmation, or if you want your confirmation warning to still run with javascript disabled. If you don't need server-side code to run first, then simply attaching a "confirm" box, or a jQuery dialog box to your button or link is a good enough solution (I'll supply the code for that just for completeness, I'm also supplying ajax-only solutions).
Here is a run-down of the code examples I'm going to give
Basic.aspx - button kicks off a submit which runs your code, which generates a confirm box. After the user has confirmed or rejected it will then run the confirm or cancel code on your page. This solely uses the postback mechanism and works with javascript disabled.
BasicDialog.aspx - exactly the same as Basic.aspx however it uses a jQuery UI Dialog rather than a confirm box. All the other examples use an alert, but you can use any message box plug-in you want, simply refer to this example to see how.
BasicWithPageMethod.aspx - this uses a postback to kick off the initial process, however if the user selects to continue then the work is completed via an ajax call to a Page Method. As with all examples that involve Page Methods, you could use a web service instead if you want. This example works with javascript disabled.
PureAjax.aspx - this doesn't use any postbacks. It simply asks if you want to proceed and if you do, it does the work via an ajax call to a Page Method. I'm including this example just for completeness, it's really just an example of how you call a Page Method or web service via ajax. This example doesn't work with javascript disabled, but if you wanted to you could incorporate the above techniques to make it work without javascript.
PureAjaxTwoStage.aspx - again this is included for completeness. This is a two-stage process where it calls a Page Method to see if the item can be actioned. If it can then another method is called to complete the process, or if it can't then the user is shown a reason why. I'm using alert boxes for the feedback but you would probably inject some divs into your html to make the thing a lot prettier, or you'd use a nice javascript modal box. This example doesn't work with javascript disabled.
NoServerCode.aspx - again this is included for completeness. The most basic of confirmation systems, it simply attaches a confirm box to the click event of your action. This is not capable of being a two-step process like the ones above. If javascrpt is disabled you just don't get the confirm, it goes straight into your action.
Basic.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Basic.aspx.cs" Inherits="WebTest.Confirm.Basic" %> <!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 runat="server"> <title></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <p> Press button to delete product <asp:Literal ID="LiteralID" runat="server" />. </p> <asp:Button ID="ButtonDelete" Text="Delete" OnClick="ButtonDelete_Click" runat="server" /> <asp:PlaceHolder ID="PlaceWarning" Visible="false" EnableViewState="false" runat="server"> <div id="warning"> <p> Are you sure? </p> <p> <asp:Button ID="ButtonYes" Text="Continue" OnClick="ButtonYes_Click" runat="server" /> <asp:Button ID="ButtonNo" Text="Cancel" OnClick="ButtonNo_Click" runat="server" /> </p> </div> <script type="text/javascript"> // If you don't want any kind of javascript conformation, just the html confirmation above then you // can leave out this entire script block. // We want the form above to be there still because it houses our buttons, but it also means our // code still works without js. With js disabled the "hide" never runs so the form stays visible // and functioning $("#warning").hide(); if (confirm("Are you sure?")) { $("#<%=ButtonYes.ClientID %>").click(); } else { // If your server-side code isn't doing anything on ButtonNo then you can leave this "else" out $("#<%=ButtonNo.ClientID %>").click(); } </script> </asp:PlaceHolder> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebTest.Confirm { public partial class Basic : System.Web.UI.Page { private string id; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { this.id = Request.QueryString["ID"]; // Just for demo purposes if you don't supply an ID in the querystring it will default to 123 if (string.IsNullOrWhiteSpace(id)) { this.id = "123"; } LiteralID.Text = this.id; ViewState["ID"] = this.id; } else { this.id = (string)ViewState["ID"]; } } protected void ButtonDelete_Click(object sender, EventArgs e) { // Here we might want to do some pre-checks on product with an ID of this.id // to make sure it can be deleted, that the person has the rights or whatever. // Show the placeholder that contains our warning features PlaceWarning.Visible = true; } protected void ButtonYes_Click(object sender, EventArgs e) { // Complete the action System.Diagnostics.Debug.WriteLine("Delete product " + this.id); // I'm returning to the same page, but you might redirect somewhere else, or not // bother redirecting at all Response.Redirect(System.IO.Path.GetFileName(Request.Path) + "?id=" + this.id); } protected void ButtonNo_Click(object sender, EventArgs e) { // We can implement some "undo" logic here if needed // I'm returning to the same page, but you might redirect somewhere else, or not // bother redirecting at all Response.Redirect(System.IO.Path.GetFileName(Request.Path) + "?id=" + this.id); } } }
BasicDialog.aspx (the code-behind is the same as Basic.aspx above so I won't bother posting it)
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BasicDialog.aspx.cs" Inherits="WebTest.Confirm.BasicDialog" %> <!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 runat="server"> <title></title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"/> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script> </head> <body> <form id="form1" runat="server"> <p> Press button to delete product <asp:Literal ID="LiteralID" runat="server" />. </p> <asp:Button ID="ButtonDelete" Text="Delete" OnClick="ButtonDelete_Click" runat="server" /> <asp:PlaceHolder ID="PlaceWarning" Visible="false" EnableViewState="false" runat="server"> <div id="warning"> <p> Are you sure? </p> <p> <asp:Button ID="ButtonYes" Text="Continue" OnClick="ButtonYes_Click" runat="server" /> <asp:Button ID="ButtonNo" Text="Cancel" OnClick="ButtonNo_Click" runat="server" /> </p> </div> <div id="jqWarning" title="Delete Product" style="display:none;"> Are you sure? </div> <script type="text/javascript"> $("#warning").hide(); $("#jqWarning").dialog({ resizable: false, modal: true, buttons: { "Yes": function () { $(this).dialog("close"); $("#<%=ButtonYes.ClientID %>").click(); }, Cancel: function () { $(this).dialog("close"); // If your server-side code isn't doing anything on ButtonNo then you can leave this call out $("#<%=ButtonNo.ClientID %>").click(); } } }); </script> </asp:PlaceHolder> </form> </body> </html>
BasicWithPageMethod.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BasicWithPageMethod.aspx.cs" Inherits="WebTest.Confirm.BasicWithPageMethod" %> <!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 runat="server"> <title></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <p> Press button to delete product <asp:Literal ID="LiteralID" runat="server" />. </p> <asp:Button ID="ButtonDelete" Text="Delete" OnClick="ButtonDelete_Click" runat="server" /> <asp:PlaceHolder ID="PlaceWarning" Visible="false" EnableViewState="false" runat="server"> <div id="warning"> <p> Are you sure? </p> <p> <asp:Button ID="ButtonYes" Text="Continue" OnClick="ButtonYes_Click" runat="server" /> <asp:Button ID="ButtonNo" Text="Cancel" OnClick="ButtonNo_Click" runat="server" /> </p> </div> <script type="text/javascript"> // We want the form above to be there still because it houses our buttons, but it also means our // code still works without js. With js disabled the "hide" never runs so the form stays visible // and functioning $("#warning").hide(); var id = '<%=this.id %>'; if (confirm("Are you sure?")) { $.ajax({ type: "POST", url: "BasicWithPageMethod.aspx/DeleteProduct", data: "{id:'" + id + "'}", contentType: "application/json; charset=utf-8", success: function () { // if you want something to happen after the ajax call then // code it here alert("Product deleted"); } }); } else { // If you want to run a server-function when the user cancels then just // do an ajax call here as above, likewise you can put general js here too } </script> </asp:PlaceHolder> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebTest.Confirm { public partial class BasicWithPageMethod : System.Web.UI.Page { protected string id; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { this.id = Request.QueryString["ID"]; // Just for demo purposes if you don't supply an ID in the querystring it will default to 123 if (string.IsNullOrWhiteSpace(id)) { this.id = "123"; } LiteralID.Text = this.id; ViewState["ID"] = this.id; } else { this.id = (string)ViewState["ID"]; } } protected void ButtonDelete_Click(object sender, EventArgs e) { // Show the placeholder that contains our warning features PlaceWarning.Visible = true; } protected void ButtonYes_Click(object sender, EventArgs e) { // If we get here then the user has js disabled. Just pass the id to the WebMethod // in order to action the task DeleteProduct(this.id); // I'm returning to the same page, but you might redirect somewhere else, or not // bother redirecting at all Response.Redirect(System.IO.Path.GetFileName(Request.Path) + "?id=" + this.id); } protected void ButtonNo_Click(object sender, EventArgs e) { // We can implement some "undo" logic here if needed // I'm returning to the same page, but you might redirect somewhere else, or not // bother redirecting at all Response.Redirect(System.IO.Path.GetFileName(Request.Path) + "?id=" + this.id); } [System.Web.Services.WebMethod] public static void DeleteProduct(string id) { // Complete the action System.Diagnostics.Debug.WriteLine("Delete product " + id); } } }
PureAjax.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PureAjax.aspx.cs" Inherits="WebTest.Confirm.PureAjax" %> <!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 runat="server"> <title></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <p> Press button to delete product <asp:Literal ID="LiteralID" runat="server" />, or <a href="#" onclick="return doWarning();">click this link</a> </p> <input type="button" value="Delete" onclick="doWarning();" /> <script type="text/javascript"> function doWarning() { var id = '<%=this.id %>'; if (confirm("Are you sure?")) { $.ajax({ type: "POST", url: "PureAjax.aspx/DeleteProduct", data: "{id:'" + id + "'}", contentType: "application/json; charset=utf-8", success: function () { // if you want something to happen after the ajax call then // code it here alert("Product deleted"); } }); } else { // If you want to run a server-function when the user cancels then just // do an ajax call here as above, likewise you can put general js here too } } </script> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebTest.Confirm { public partial class PureAjax : System.Web.UI.Page { protected string id; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { this.id = Request.QueryString["ID"]; // Just for demo purposes if you don't supply an ID in the querystring it will default to 123 if (string.IsNullOrWhiteSpace(id)) { this.id = "123"; } LiteralID.Text = this.id; ViewState["ID"] = this.id; } else { this.id = (string)ViewState["ID"]; } } [System.Web.Services.WebMethod] public static void DeleteProduct(string id) { // Complete the action System.Diagnostics.Debug.WriteLine("Delete product " + id); } } }
PureAjaxTwoStage.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PureAjaxTwoStage.aspx.cs" Inherits="WebTest.Confirm.PureAjaxTwoStage" %> <!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 runat="server"> <title></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <p> Press button to delete product <asp:Literal ID="LiteralID" runat="server" />, or <a href="#" onclick="return doWarning();">click this link</a> </p> <input type="button" value="Delete" onclick="doWarning();" /> <script type="text/javascript"> function doWarning() { var id = '<%=this.id %>'; $.ajax({ type: "POST", url: "PureAjaxTwoStage.aspx/CheckDelete", data: "{id:'" + id + "'}", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { if (data.d.canDelete == true) { doDelete(id); } else { alert(data.d.message); } } }); return false; } function doDelete(id) { if (confirm("Are you sure?")) { $.ajax({ type: "POST", url: "PureAjaxTwoStage.aspx/DeleteProduct", data: "{id:'" + id + "'}", contentType: "application/json; charset=utf-8", success: function () { // if you want something to happen after the ajax call then // code it here alert("Product deleted"); } }); } else { // If you want to run a server-function when the user cancels then just // do an ajax call here as above, likewise you can put general js here too } } </script> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebTest.Confirm { public partial class PureAjaxTwoStage : System.Web.UI.Page { protected string id; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { this.id = Request.QueryString["ID"]; // Just for demo purposes if you don't supply an ID in the querystring it will default to 123 if (string.IsNullOrWhiteSpace(id)) { this.id = "123"; } LiteralID.Text = this.id; ViewState["ID"] = this.id; } else { this.id = (string)ViewState["ID"]; } } [System.Web.Services.WebMethod] public static object CheckDelete(string id) { // Here we can do some checks to see if the product can be deleted // For this example we'll say that even product IDs can be deleted // but odd ones can't. To test this, put diffeent IDs in the querystring int x = 0; int.TryParse(id, out x); if (x % 2 == 0) { return new { canDelete = true }; } else { return new { canDelete = false, message = "Only even products can be deleted" }; } } [System.Web.Services.WebMethod] public static void DeleteProduct(string id) {
// note you should re-do your check that the item
// can be deleted as people can accesses this method directly
// Complete the action System.Diagnostics.Debug.WriteLine("Delete product " + id); } } }NoServerCode.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NoServerCode.aspx.cs" Inherits="WebTest.Confirm.NoServerCode" %> <!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 runat="server"> <title></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <p> Press button to delete product <asp:Literal ID="LiteralID" runat="server" /> </p> <asp:Button ID="ButtonDelete" Text="Delete" OnClick="ButtonDelete_Click" runat="server" /> <script type="text/javascript"> $("#<%=ButtonDelete.ClientID%>").click(function () { return confirm("Are you sure?"); }); </script> </form> </body> </html>
Monday, March 17, 2014 4:37 PM
All replies
-
User1208776063 posted
Very well written article Andy!
Monday, March 17, 2014 4:53 PM -
User281315223 posted
Solid article as always AidyF :)
Monday, March 17, 2014 5:13 PM