Server-side Form Dirty Flag
The programmer utilizes form dirty flags to warn the application user that the user has changed the contents of a control on the web page, and usually a message box alerts the user to save the changes before leaving the page. There are two types of form dirty flags covered by this website: server-side and client-side. Below are instructions on how to implement a server-side dirty flag, and one client-side dirty flag is under the jQuery section of this website.
A sample web form to illustrate the server-side dirty flag could look like:

Declare an event handler to set the dirty flag when a form control contents change:
//---------------------------------------------------------------------------
/// <summary>
/// Method Name: Control_Changed
/// Description: Handler for all control content changes
/// </summary>
///
//---------------------------------------------------------------------------
protected void Control_Changed(object sender, EventArgs e) {
Session["bDirty"] = true; }
The Control_Changed event handler now needs to be tied to each form control change event to set the bDirty flag to true if a change is made to the control contents:
//---------------------------------------------------------------------------
/// <summary>
/// Method Name: AddChangeEventHandlers
/// Description: Add handlers for all control content changes
/// </summary>
///
//---------------------------------------------------------------------------
protected void AddChangeEventHandlers() {
this.lblWarningMessage.Text = String.Empty; this.txtLastName.TextChanged += Control_Changed; this.txtFirstName.TextChanged += Control_Changed; this.txtMiddleInitial.TextChanged += Control_Changed; this.ddlProgram.SelectedIndexChanged += Control_Changed; this.txtDateOfApplication.TextChanged += Control_Changed; this.optYes.CheckedChanged += Control_Changed; this.optNo.CheckedChanged += Control_Changed; this.chkSupervisorReviewed.CheckedChanged += Control_Changed; this.txtEmail.TextChanged += Control_Changed; }
Load the event handlers in the Page_Load event:
protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
//Populate the page if appropriate to simulate database access.
this.PopulateForm(); }
//Add the control event handlers
this.AddChangeEventHandlers(); }
In a button save click event, the programmer can then check the dirty flag to see if some information in a control has changed. If the bDirty flag is true, data on the form has changed, and the information should be validated through the Business Logic Layer, and sent to the Data Access Layer to a database stored procedure.
if (Session["bDirty"] != null) {
if (Convert.ToBoolean(Session["bDirty"]) == true) {
string message = String.Empty; DefaultBLL bll = new DefaultBLL(); //validate last name
if (this.txtLastName.Text.Trim() == String.Empty) {
message = "The Last Name is a required field. " + "<br />"; }
else if (bll.ValidateName(this.txtLastName.Text.Trim()) == false) {
message = "The Last Name contains some invalid characters. " + "<br />"; }
//validate First Name
if (this.txtLastName.Text.Trim() == String.Empty) {
message = message + "The First Name is a required field. " + "<br />"; }
else if (bll.ValidateName(this.txtFirstName.Text.Trim()) == false) {
message = message + "The First Name contains some invalid characters. " + "<br />"; }
//validate Middle Initial
if (this.txtMiddleInitial.Text.Trim() != String.Empty) {
if (bll.ValidateMiddleInitial(this.txtMiddleInitial.Text.Trim()) == false) {
message = message + "The Middle Initial contains an invalid character. " + "<br />"; }
}
//validate Drop Down
if (this.ddlProgram.SelectedIndex == 0) {
message = message + "The Program is a required selection. " + "<br />"; }
//Validate Date Text Box
if (this.txtDateOfApplication.Text.Trim() == String.Empty) {
message = message + "The Date of Application is a required selection. " + "<br />"; }
else if (bll.ValidateDate(this.txtDateOfApplication.Text.Trim()) == false) {
message = message + "The Date of Application is not a valid date. " + "<br />"; }
//Validate Yes or No (Radio buttons) Option Controls
if (this.optYes.Checked != true && this.optNo.Checked != true) {
message = message + "The Approved Y or N option is a required selection. " + "<br />"; }
//validate email
if (this.txtEmail.Text.Trim() != String.Empty && bll.ValidateEmailAddress(this.txtEmail.Text.Trim()) != true) {
message = message + "The email is not in the correct format (e.g., yourname@email.com). " + "<br />"; }
//Check to see if message variable is empty, if is, then send data to BLL (simulated save - no DAL)
if (message == String.Empty) {
try
{
bll.SimulatedSave();
}
catch (Exception ex) {
//Send message to Error Handler Service
ex.Message.ToString();
}
finally
{
bll = null; this.lblWarningMessage.Text = "Data Saved."; message = null; }
//Since saved, reset dirty flag
Session["bDirty"] = null; return; }
//If message not empty string, then display message
else if (message != String.Empty) {
this.lblWarningMessage.Text = message; bll = null; message = null; //reset dirty flag since changes not processable
Session["bDirty"] = null; return; }
}
else
{
this.lblWarningMessage.Text = "Data Not Saved Since Nothing Changed."; }
}
The user is then informed that the data has been saved:
If a form control contents have changed, then the dirty flag will be true, and the application can then validate the data through the Business Logic Layer before passing the from information to the Data Access Layer. If none of the page control contents has changed, then the bDirty flag will be false, and a BLL validation and a DAL save is an unnecessary processing of data and a waste of server memory and network bandwidth. The user is informed that the save was unnecessary.
else
{
this.lblWarningMessage.Text = "Data Not Saved Since Nothing Changed."; }
The user will be informed that the save was unnecessary:
When closing the form, check to see if dirty flag set. If set, then warn user, and if not, redirect:
protected void btnClose_Click(object sender, EventArgs e) {
if (Session["bDirty"] != null) {
if (Convert.ToBoolean(Session["bDirty"]) == true) {
ShowMessageBox(this, "The information on this page has been changed. Before leaving, SAVE the information or CANCEL the changes."); }
}
else
{
Response.Redirect("Default1.aspx"); }
}
The cancel button click event to reset the dirty flag:
protected void btnCancel_Click(object sender, EventArgs e) {
if (Session["bDirty"] != null) {
Session["bDirty"] = null; }
}