December 2010 - Posts

Resetting Form Field Values in an ASP.NET WebForm
23 December 10 02:14 AM | Scott Mitchell | 3 comment(s)

A recent question on Stackoverflow.com asked if there was a general method to clear a form in ASP.NET. The person asking the question had a form with many TextBox and DropDownList controls and wanted some way to be able to “reset” all of those values; specifically, the TextBoxes would be cleared out and the DropDownLists would have their first item selected.

At first blush, this seems like a job for the reset button. HTML has long supported the ability to reset a form by clicking a reset button, which is a button of type reset.

<input type="reset" value="Reset Form!" />

The reset button’s functionality can also be invoked from JavaScript by calling the form object’s reset function. The following snippet of script checks to see if there is at least one form in the document and, if so, calls its reset function:

if (document.forms && document.forms[0])
    document.forms[0].reset();

The Problem with Reset…

However, there is a potential issue when resetting form values in an ASP.NET WebForms application using this approach. The issue arises because the reset button (or reset function) does not clear out textboxes and return drop-down lists to their first value, but instead returns the forms fields to their initial values. That is, if you have a page with a textbox whose markup contains a value attribute, like:

<input type="text" value="Hello, World!" ... />

And then a user changes the textbox’s text to “Goodbye!” and then clicks the reset button, the textbox does not go blank – rather, it reverts to “Hello, World!” In an ASP.NET WebForm application anytime there is a postback on the page – such as if there is a DropDownList whose AutoPostBack property is set to True – the page’s markup is re-rendered and the text values and DropDownList selections made by the user are remembered because the re-rendered markup includes the user-entered values. Long story short, if you use the reset button approach described above and have a form where there are postbacks going on, if a user enters values into textboxes (or drop-downs), then does a postback, then clicks the reset button, the form fields will be reset to their values immediately after the postback and not to empty textboxes.

jQuery to the Rescue!

The good news is that with just a couple of lines of jQuery code we can implement the reset functionality we desire, regardless of postbacks. The following two lines of script set the value of all textboxes on the page to an empty string and set the selectedIndex of all drop-down lists on the page to be 0, which selects the first item:

$("input[type=text]").val("");
$("select").attr('selectedIndex', 0);

That’s all there is to it! You could tinker with the selector syntax to limit the affected textboxes and drop-downs to those in a specific <div> or form or whatnot; likewise, you could add additional lines of code if you need to reset checkboxes, radio buttons, or other input fields.

A Server-Side Approach…

If the client-side approach doesn’t cut it for you, you can opt to reset form fields using server-side logic. You could, of course, set the Text property of each TextBox control to an empty string and clear the selections of all DropDownLists, but a more general approach is possible using recursion. Each ASP.NET control has a Controls  property that contains its children controls. Put together, the controls in an ASP.NET page form a control hierarchy. We can recurse through this control hierarchy, examining each control and modifying any TextBoxes and DropDownLists we come across.

The following code snippet illustrates such a recursive method, ClearInputs. Note that ClearInputs is passed in a ControlCollection object. This collection is enumerated and checked for TextBoxes and DropDownLists. If a TextBox is found, its Text property is set to string.Empty; if a DropDownList is found its ClearSelection method is invoked. Finally, the ClearInputs method is called again and passed the current control’s Controls collection for it to be examined.

void ClearInputs(ControlCollection ctrls)
{
    foreach (Control ctrl in ctrls)
    {
        if (ctrl is TextBox)
            ((TextBox)ctrl).Text = string.Empty;
        else if (ctrl is DropDownList)
            ((DropDownList)ctrl).ClearSelection();

        ClearInputs(ctrl.Controls);
    }
}

To reset all TextBox and DropDownList values you’d call this method like so:

ClearInputs(Page.Controls);

To reset the TextBoxes and DropDownLists in a particular control (such as a Panel), you’d call ClearInputs passing in that control’s Controls collection.

Happy Programming!

Filed under: ,
Checking All CheckBoxes in a GridView Using jQuery
04 December 10 02:41 AM | Scott Mitchell | 3 comment(s)

How do I love thee, jQuery? Let me count the ways.

In May 2006 I wrote an article on 4GuysFromRolla.com titled Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox, in which I showed how to add a column of checkboxes to a GridView along with a checkbox in that column’s header that enabled the user to check/uncheck all checkboxes in one fell swoop. This check/uncheck all functionality was accomplished using JavaScript.

While the JavaScript presented in the article worked then (and still works today, of course), it is a less than ideal approach for a couple of reasons.

  • First, each checkbox in the grid is programmatically assigned a client-side onclick event handler in the GridView’s DataBound event handler that calls a function that determines whether to check or uncheck the checkbox in the head – having a client-side event handler defined directly in an HTML element violates the design goal of unobstrusive JavaScript.
  • Second, because programmatically assigned client-side attributes are not remembered across postbacks and because these client-side attributes are only assigned when data is bound to the grid, the script is lost when there is a postback that doesn’t cause the grid to have its data re-bound to it. Long story short, the check/uncheck all functionality stops working after such postbacks. I provide a workaround for this, but it’s extra steps, extra script, and another thing that you have to remember to do.
  • Third, the solution entails quite a bit of script, much more than is necessary using modern JavaScript libraries.

When I authored the article jQuery had not yet been released. Fortunately, today we have jQuery (and other JavaScript libraries) at our fingertips. jQuery is a free, open-source JavaScript library created by John Resig. In a nutshell, jQuery allows us to accomplish common client-side tasks with terse, readable script. With jQuery, I can rewrite the entire GridView check/uncheck all functionality with zero lines of server-side code and a scant 25 or so lines of JavaScript.

To demonstrate jQuery’s power, consider a GridView with the following markup:

<asp:GridView ID="gvProducts" runat="server" ...>
    <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:CheckBox runat="server" ID="chkAll" />
            </HeaderTemplate>
            <ItemTemplate>
                <asp:CheckBox runat="server" ID="chkSelected" />
            </ItemTemplate>
        </asp:TemplateField> 
        ...
    </Columns>
</asp:GridView>

Note the TemplateField – this is where the two CheckBox controls live. The CheckBox control in the HeaderTemplate (chkAll) is the check/uncheck all checkbox, while the CheckBox control in the ItemTemplate (chkSelected) is the checkbox that appears in each of the grid’s data rows.

Now, I need script that does the following:

  1. When one of the chkSelected checkboxes is checked or unchecked, I need to determine whether the all option needs to be checked or unchecked. In the case where all chkSelected checkboxes are checked, I want to check chkAll. Likewise, in the case when any chkSelected checkbox is unchecked, I want to uncheck chkAll.
  2. When chkAll is checked or unchecked, I need to check or uncheck all chkSelected checkboxes.

To address the first concern I created a function named CheckUncheckAllCheckBoxAsNeeded. This function determines the total number of chkSelected checkboxes in the grid and the number of checked chkSelected checkboxes. If the two numbers match then chkAll is checked, otherwise it’s unchecked.

function CheckUncheckAllCheckBoxAsNeeded() {
    var totalCheckboxes = $("#<%=gvProducts.ClientID%> input[id*='chkSelected']:checkbox").size();
    var checkedCheckboxes = $("#<%=gvProducts.ClientID%> input[id*='chkSelected']:checkbox:checked").size();

    if (totalCheckboxes == checkedCheckboxes) {
        $("#<%=gvProducts.ClientID%> input[id*='chkAll']:checkbox").attr('checked', true);
    }
    else {
        $("#<%=gvProducts.ClientID%> input[id*='chkAll']:checkbox").attr('checked', false);
    }
}

This function is executed whenever one of the chkSelected checkboxes is checked or unchecked. This event wiring is handled in the $(document).ready event handler. Also, the CheckUncheckAllCheckBoxAsNeeded function is called right off the bat in case the grid’s checkboxes are already all checked when the page loads.

$(document).ready(function () {
    $("#<%=gvProducts.ClientID%> input[id*='chkSelected']:checkbox").click(CheckUncheckAllCheckBoxAsNeeded);

    ...

    CheckUncheckAllCheckBoxAsNeeded();
});

Finally, we need to check/uncheck all chkSelected checkboxes when chkAll is checked or unchecked. This logic is also in the $(document).ready event handler (where the ellipsis is positioned in the above snippet).

$("#<%=gvProducts.ClientID%> input[id*='chkAll']:checkbox").click(function () {
    if ($(this).is(':checked'))
        $("#<%=gvProducts.ClientID%> input[id*='chkSelected']:checkbox").attr('checked', true);
    else
        $("#<%=gvProducts.ClientID%> input[id*='chkSelected']:checkbox").attr('checked', false);
});

Pretty neat and a whole heck of a lot simpler than the technique I initially showcased in Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox. A more detailed look at this code, along with a downloadable working example, will be on 4Guys within the next couple of weeks.

UPDATE [2010-12-07]: A 4Guys article that provides much more detail and screen shots and a downloadable demo is now available: Checking All Checkboxes in a GridView Using jQuery. Also, special thanks to Elijah Manor, who offered a number of suggestions on how to improve and tighten up my jQuery script.

Happy Programming!

Filed under: ,
More Posts

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.