Confirming Before Postback

Published 18 June 04 02:35 PM | Scott Mitchell

There are a number of articles out there about building a DataGrid with a ButtonColumn of Delete buttons, and using a bit of client-side JavaScript in the Button's client-side onclick event handler in order to present the user with a confirm popup asking them if they're sure they really want to delete the record. For example, such an article can be found in An Extensive Examination of the DataGrid Web Control: Part 8. Essentially you add the onclick event handler to the Button's Attributes collection:

button.Attributes[“onclick“] = “javascript:return confirm(...);“;

I was working on a project recently where a client wanted similar functionality, but with a bit of a twist. He had a DropDownList populated with some “parent” values, with the parent's details displayed in the Web page. Changing the DropDownList item would cause the page to be posted back and the page loaded with the newly selected DropDownList's details records. Simple enough to implement: just add a DropDownList with the AutoPostback property set to True, and write an event handler for the SelectedIndexChanged event.

However, under certain conditions, when the user changed the DropDownList item, this client wanted the user to be prompted with a client-side confirm box, asking them if they were sure they wanted to leave the current details information. (Imagine, for instance, that the details for a particular master record had some “critical” tasks that needed to be done, and if these had not been checked off, a warning would need to be displayed saying something like, “Are you sure you want to leave, you still have critical tasks left unchecked.”)

To accomplish this, I needed to add an onchange client-side event handler for the DropDownList. However, the DropDownList already emits some client-side script in the onchange event - namely the code to initiate a postback. That is, the DropDownList, with AutoPostback set to True, renders like:

<select onchange=”__doPostBack(...)”>
...
</select>

Adding an onchange event to the DropDownList's Attributes collection prepends whatever you add to the __doPostBack(...) script emitted. So, we want to add script that calls __doPostBack(...) only if the user hits OK in the confirm popup. The following will accomplish this:

ddl.Attributes[”onchange”] = “if (confirm(...)) “;

With this client-side script, the DropDownList will be rendered as:

<select onchange=”if (confirm(...)) __doPostBack(...)”>
...
</select>

And that's what we want! Now, if the user changes the DropDownList value, it will popup a client-side confirm box, saying, “Are you sure you want to change the master record?” (or whatever). If the user clicks OK, it will postback and update the detail view. If they click cancel, the postback will not occur, and the user will remain on the same page.

This approach, though, is not complete, I'm afraid. If the user clicks cancel it's true that the page won't be posted back, but the DropDownList will display the value of the selected list item. That is, if the user is viewing the master record X, and then change to Y, they'll see that confirm box. If they click cancel, a postback won't occur, but the DropDownList will show Y (not X).

One approach to fix this is to add a bit of client-side code to the page that records the DropDownList's selected index on the body's onload event. Then, a client-side function can be created that resets the DropDownList's selected index back to the original one. This function would be called if the user clicked cancel. To get everything to work, the onchange script needs to be changed to:

ddl.Attributes[”onchange”] = “if (!confirm(...)) resetIndexes(); else “;

With this client-side script, the DropDownList will be rendered as:

<select onchange=”if (!confirm(...)) resetIndexes(); else __doPostBack(...)”>
...
</select>

So if the user clicks Cancel on the confirm, the client-side resetIndexes() function will be called, which will reset the DropDownList index. Otherwise, if they clicked OK, the postback will occur. The final piece of the puzzle is the code for the resetIndexes() function and the function that records the original selected index values in the onload event. Assuming your DropDownList's client ID is foo, this could be accomplished with the following client-side code:

var fooIndex;

function saveIndexes()
{
fooIndex = document.frmName.foo.selectedIndex;
}

function resetIndexes()
{
document.frmName.foo.selectedIndex = fooIndex;
}

This assumes that you have named your Web Form frmName. (<form runat=”server” id=”frmName”>). Also, you'll need to call saveIndexes() in the body onload event - <body onload=”saveIndexes();”>.

Hope this helps someone... :-)

Filed under:

Comments

No Comments

Archives

My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.