Friday, April 09, 2010

Client-Side Validation: How to Validate Controls in Each Pane of an AjaxControlToolkit Accordion

I'm using the AjaxControlToolKit Accordion, and I needed to validate the controls in each pane before allowing one to navigate to the other panes. I wanted everything to be client-side, because I don't want any post-backs until the whole form is validated. Since I didn't have any luck finding any good examples, here's one I put together. It uses the RequiredFieldValidator control as well as the ValidatorCalloutExtender. If you don't like the fly-out validation, just remove the ValidatorCalloutExtender controls as well as the Display="Hidden" attribute in the RequiredFieldValidators.

Sorry about the funky formatting. A copy/paste into a new aspx file should work with no modifications. I also have a downloadable self-contained aspx file. Enjoy.


<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Accordion</title>
<style type="text/css">
.accordionHeader
{
border: 1px solid #2F4F4F;
color: white;
background-color: #2E4d7B;
font-family: Arial, Sans-Serif;
font-size: 12px;
font-weight: bold;
padding: 5px;
margin-top: 5px;
cursor: pointer;
}

.accordionHeader button
{
cursor: pointer;
}

.accordionContent
{
background-color: #D3DEEF;
border: 1px dashed #2F4F4F;
border-top: none;
padding: 5px;
padding-top: 10px;
}

.accordionLink
{
background-color: #D3DEEF;
color: #ffffff:
}

.invalidField
{
background-color:#fffacd; /* same color as the background of the validation popup */
}
</style>
</head>
<body>
<script type="text/javascript" language="javascript">
var acc;
var header;

function pageLoad() {
// get a reference to the accordion
acc = $find("MyAccordion_AccordionExtender");

/* for each of the panes, remove its click handler, and add our own;
using different methods for each pane would be unnecessary in our example
if we could include parameters in the method name, for example:
$addHandler(header, "click", navigateToPane(0));

we can't do that, so we set up a method name for each one; */
var index = 0;
header = acc.get_Pane(index).header;
$removeHandler(header, "click", acc._headerClickHandler);
$addHandler(header, "click", navigateToNamePane);

index = 1;
header = acc.get_Pane(index).header;
$removeHandler(header, "click", acc._headerClickHandler);
$addHandler(header, "click", navigateToContactPane);

index = 2;
header = acc.get_Pane(index).header;
$removeHandler(header, "click", acc._headerClickHandler);
$addHandler(header, "click", navigateToDemographicsPane);
}

// this function has to be here or there will be an error when leaving the page
function pageUnload() {
$addHandler(header, "click", acc._headerClickHandler);
}

function navigateToPane(paneIndex) {
// get a reference to the accordion
var pane = $find('MyAccordion_AccordionExtender');

// validate the controls in the current pane, using the ValidationGroup
// of the pane, e.g. "grp0" or "grp1", etc; if it's valid, navigate to
// the pane that corresponds to the index passed in
if (Page_ClientValidate('grp' + pane.get_SelectedIndex()))
pane.set_SelectedIndex(paneIndex);
}

function navigateToNamePane() {
navigateToPane(0);
}

function navigateToContactPane() {
navigateToPane(1);
}

function navigateToDemographicsPane() {
navigateToPane(2);
}
</script>

<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager runat="server" ID="ScriptManager1" />

<ajaxToolkit:Accordion ID="MyAccordion" runat="server" HeaderCssClass="accordionHeader"
ContentCssClass="accordionContent" FramesPerSecond="40" TransitionDuration="250"
AutoSize="None" SelectedIndex="0" RequireOpenedPane="false" SuppressHeaderPostbacks="false">
<Panes>
<ajaxToolkit:AccordionPane ID="AccordionPane0" runat="server">
<Header>Name</Header>
<Content>
Last Name: <asp:TextBox ID="txtLastName" runat="server" />
<asp:RequiredFieldValidator ID="reqLastname" runat="server" ValidationGroup="grp0" ControlToValidate="txtLastName" Text="" ErrorMessage="Last Name is required" Display="None" />
<ajaxToolkit:ValidatorCalloutExtender runat="Server" id="vceLastName" TargetControlID="reqLastName" HighlightCssClass="invalidField" />
<br />
First Name: <asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="reqFirstName" runat="server" ValidationGroup="grp0" ControlToValidate="txtFirstName" Text="" ErrorMessage="First Name is required" Display="None" />
<ajaxToolkit:ValidatorCalloutExtender runat="Server" id="vceFirstName" TargetControlID="reqFirstName" HighlightCssClass="invalidField" />
<br />

<!-- the "Continue" button isn't necessary; it's just an added item to make navigation a bit more intuitive -->
<button onclick="navigateToPane(1);" style="float:right;" title="Continue to Contact Info">Continue</button>
</Content>
</ajaxToolkit:AccordionPane>
<ajaxToolkit:AccordionPane ID="AccordionPane2" runat="server">
<Header>Contact Info</Header>
<Content>
Phone: <asp:TextBox ID="txtPhone" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqPhone" runat="server" ValidationGroup="grp1" ControlToValidate="txtPhone" Text="" ErrorMessage="Phone is required" Display="None" />
<ajaxToolkit:ValidatorCalloutExtender runat="Server" id="vcePhone" TargetControlID="reqPhone" HighlightCssClass="invalidField" />
<br />
Email: <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqEmail" runat="server" ValidationGroup="grp1" ControlToValidate="txtEmail" Text="" ErrorMessage="Eamil is required" Display="None" />
<ajaxToolkit:ValidatorCalloutExtender runat="Server" id="vceEmail" TargetControlID="reqEmail" HighlightCssClass="invalidField" />
<br />

<!-- the "Continue" button isn't necessary; it's just an added item to make navigation a bit more intuitive -->
<button onclick="navigateToPane(2);" style="float:right;" title="Continue to Demographics">Continue</button>
</Content>
</ajaxToolkit:AccordionPane>
<ajaxToolkit:AccordionPane ID="AccordionPane3" runat="server">
<Header>Demographics</Header>
<Content>
Age: <asp:TextBox ID="txtAge" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqAge" runat="server" ValidationGroup="grp2" ControlToValidate="txtAge" Text="" ErrorMessage="Age is required" Display="None" />
<ajaxToolkit:ValidatorCalloutExtender runat="Server" id="vce" TargetControlID="reqAge" HighlightCssClass="invalidField" />
<br />
Salary: <asp:TextBox ID="txtSalary" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="reqSalary" runat="server" ValidationGroup="grp2" ControlToValidate="txtSalary" Text="" ErrorMessage="Salary is required" Display="None" />
<ajaxToolkit:ValidatorCalloutExtender runat="Server" id="vceSalary" TargetControlID="reqSalary" HighlightCssClass="invalidField" />
</Content>
</ajaxToolkit:AccordionPane>
</Panes>
</ajaxToolkit:Accordion>
</form>
</body>
</html>

1 comments:

w3c said...

Nice information, I really appreciate the way you presented.Thanks for sharing..

http://www.w3cvalidation.net/

Post a Comment