BlueLemonCode.Com

Yet Another Tech Blog

Passing values to custom validator client function

Introduction

The client function of CusomValidator has specific signature. It has source and argument

Moreover, while setting ClientValidationFunction, you should only specify name of function. No parentheses or parameters.

So, you cannot pass own parameters to this function directly as we normally do. But, many times scenario demands to pass values to ClientValidation function

In this article, we will see such scenario and how to pass the parameters. 

Background

You can create reference to control in JavaScript code so, effectively; values from different control can be read directly inside ClientValidation function

however, at times, it becomes necessary to pass the values as parameter to ClientValidation function.

Consider, GridView data control having three textboxes in every row created using template field columns.

We want to use Customvalidator on textboxes in last column. The values of other two textboxes in same row is required in the ClientValidation function

In such scenario, we need to pass values to ClientValidation function. We will elaborate same example in this article.

Article Body

Consider following scenario, Database table contains EmployeeDetail contains following columns

EmployeeNumber, EmployeeName, Grade, Designation and Contact. Grade of employees could be Junior or senior and designation could be developer, manager etc.

We are using gridview to display all records from table and let user update it at the same time. We have a condition that for every employee

Whose grade is senior and designation is manager, Contact information is mandatory. For all other employees it could be kept blank.

To handle this condition we want to add Customvalidator for Contact field. Our basic html markup for this scenario looks like this

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default18.aspx.vb" Inherits="Default18" %>

<!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">
<script type="text/javascript">
    function ValidateFunction(source, args) {
        var txtGrade = document.getElementById(source.txtGrade);
        var txtDesignation = document.getElementById(source.txtDesignation);
        var txtContact = document.getElementById(source.txtContact);

        if (txtGrade.value == "senior" && txtDesignation.value == "Manager") {
            if (txtContact.value == "")
                    args.IsValid = false;
                else
                    args.IsValid = true;
            }
            else
                args.IsValid = true;
    }
</script>
    <title></title>
</head>
<body>
<form id="form1" runat="server">
    <div>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        CellPadding="4" ForeColor="#333333" GridLines="None">
        <RowStyle BackColor="#EFF3FB" />
       <Columns>
          <asp:BoundField HeaderText="Employee Number" DataField="Employeenumber"/>
          <asp:BoundField HeaderText="Employee Name" DataField="Employeename"/>          
          <asp:TemplateField HeaderText="Grade">
             <ItemTemplate>
                <asp:TextBox ID="txtGrade" runat="server" Text='<%#Bind("Grade") %>'></asp:TextBox>
             </ItemTemplate>
          </asp:TemplateField>
          <asp:TemplateField HeaderText="Designation">
             <ItemTemplate>
                <asp:TextBox ID="txtDesignation" runat="server" Text='<%#Bind("Designation") %>'></asp:TextBox>
             </ItemTemplate>
          </asp:TemplateField>
          <asp:TemplateField HeaderText="Contact">
             <ItemTemplate>
                <asp:TextBox ID="txtContact" runat="server" Text='<%#Bind("Contact") %>'></asp:TextBox><br />
                <asp:CustomValidator ID="custValidate" runat="server" ErrorMessage="Please enter contact" 
Display="Dynamic"ClientValidationFunction="ValidateFunction"> </asp:CustomValidator>
             </ItemTemplate>
          </asp:TemplateField>                    
       </Columns>
        <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
        <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
        <EditRowStyle BackColor="#2461BF" />
        <AlternatingRowStyle BackColor="White" />
    </asp:GridView>
    <br />
    <div style="width=100%;background-color:Gray">
      <asp:Button id="btnsubmit" runat="server" Text="Validate"/>
    </div>    
    
    </div>
    </form>
</body>
</html>

Now, In the ClientValidation function, we need to get value of grade and designation of same row.

We can use Page.ClientScript.RegisterExpandoAttribute method register different values which we want to use in validation function

We will now create a separate function which will iterate through all rows of gridview and register values for custom validator on every row.

The function is created as below

 

VB.Net

Private Sub setCusomValidator()
        For Each row As GridViewRow In GridView1.Rows
            If row.RowType = DataControlRowType.DataRow Then
                Dim txtGrade As TextBox = DirectCast(row.FindControl("txtGrade"), TextBox)
                Dim txtDesignation As TextBox = DirectCast(row.FindControl("txtDesignation"), TextBox)
                Dim txtContact As TextBox = DirectCast(row.FindControl("txtContact"), TextBox)
                Dim custValidator As CustomValidator = DirectCast(row.FindControl("custValidate"), CustomValidator)

                Page.ClientScript.RegisterExpandoAttribute(custValidator.ClientID, "txtGrade", txtGrade.ClientID, False)

                Page.ClientScript.RegisterExpandoAttribute(custValidator.ClientID, "txtDesignation", txtDesignation.ClientID, False)

                Page.ClientScript.RegisterExpandoAttribute(custValidator.ClientID, "txtContact", txtContact.ClientID, False)
            End If
        Next
End Sub
 
C#

private void setCusomValidator()
{
    foreach (GridViewRow row in GridView1.Rows) {
        if (row.RowType == DataControlRowType.DataRow) {
            TextBox txtGrade = (TextBox)row.FindControl("txtGrade");
            TextBox txtDesignation = (TextBox)row.FindControl("txtDesignation");
            TextBox txtContact = (TextBox)row.FindControl("txtContact");
            CustomValidator custValidator = (CustomValidator)row.FindControl("custValidate");

            Page.ClientScript.RegisterExpandoAttribute(custValidator.ClientID, "txtGrade", txtGrade.ClientID, false);

            Page.ClientScript.RegisterExpandoAttribute(custValidator.ClientID, "txtDesignation", txtDesignation.ClientID, false);

            Page.ClientScript.RegisterExpandoAttribute(custValidator.ClientID, "txtContact", txtContact.ClientID, false);
        }
    }
}

We can now call this function when datasource is set for gridview as well as in Page_load event

The reason for calling this method on Page_Load is because after post back registered values cannot be accessed again in the ClientValidation function

After values are registered, we can access these values in the Javascript ClientValidation function. Our ClientValidation finally looks like this

<script type="text/javascript">
    function ValidateFunction(source, args) {
        var txtGrade = document.getElementById(source.txtGrade);
        var txtDesignation = document.getElementById(source.txtDesignation);
        var txtContact = document.getElementById(source.txtContact);

        if (txtGrade.value == "senior" && txtDesignation.value == "Manager") {
            if (txtContact.value == "")
                    args.IsValid = false;
                else
                    args.IsValid = true;
            }
            else
                args.IsValid = true;
    }
</script>

Note in above code, source.txtGrade, source.txtDesignation and source.txtContact are name of values registered using RegisterExpandoAttribute.

The CustomValidator is implemented as per our original requirement and it looks like this

 

Although, direct arguments cannot be passed to ClientValidation function of CustomValidator. But, it can be easily done by Page.ClientScript.RegisterExpandoAttribute method.

Hope this helps someone :)