views:

31

answers:

1

Hello! I have an ASP .NET page with both asp .net validators and some javascript checking too. I am advancing into the button code behind:

protected void Button2_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            /// ...

Even when the validation fails! The Page.IsValid check solves it, but it also resets all the JavaScript variables… May there be a way not to advance into the button code? I have an ajax update panel and some image buttons on the page too… Anything I may look out for? Thanks in advance!

Here is my aspx:

<%@ Page Language="C#" AutoEventWireup="true" 
CodeBehind="WebForm2.aspx.cs" 
Inherits="WebForm2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="width: 500px;">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>

        <script type="text/javascript">
            var nrOptions = 0;
            alert(nrOptions + " - variable initialized");
            function IncrementQuantity() {
                nrOptions++;
                alert(nrOptions);
            }
            function DecrementQuantity() {
                nrOptions--;
                alert(nrOptions);
            }
            function MoreThanTwo() {
                alert(nrOptions);
                if (nrOptions > 1) {
                    alert('okay - you have: ' + nrOptions);
                    return true;
                }
                else {
                    alert('error - must have at least two options, you only have: ' + nrOptions);
                    return false;
                }
            }            
        </script>

        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
                    <HeaderTemplate>
                        Fill in with two or more options:<br />
                        <table border="1" width="100%">
                    </HeaderTemplate>
                    <ItemTemplate>
                        <tr>
                            <td valign="middle">
                            </td>
                            <td valign="middle">
                                Description:
                                <asp:TextBox ID="TBox1" runat="server" Width="120px" Text='<%# Eval("Desc")%>'></asp:TextBox>
                                <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TBox1"
                                    ValidationGroup="InsertVal" ErrorMessage="*"></asp:RequiredFieldValidator>
                                Points:
                                <asp:TextBox ID="TBox2" runat="server" Width="20px" Text='<%# Eval("Pont")%>'></asp:TextBox>
                                <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="TBox2"
                                    ValidationGroup="InsertVal" ErrorMessage="*"></asp:RequiredFieldValidator>
                                <asp:Button ID="ImageButton1" runat="server" Text="x" CommandName="DeleteRow" OnClientClick="DecrementQuantity();" />
                                <asp:RegularExpressionValidator ID="RegularExpressionValidator1" ControlToValidate="TBox2"
                                    ValidationExpression="\d+" ValidationGroup="InsertVal" runat="server"
                                    ErrorMessage="Number >= 0."></asp:RegularExpressionValidator>
                            </td>
                        </tr>
                    </ItemTemplate>
                    <FooterTemplate>
                        <tr>
                            <td colspan="2" align="right">
                                <asp:Button ID="lnkAddRow" runat="server" Text="Add option" OnClientClick="IncrementQuantity();"
                                    CommandName="AddRow" OnClick="lnkAddRow_Click" />
                            </td>
                        </tr>
                        </table>
                    </FooterTemplate>
                </asp:Repeater>
                <br />
                <p style="text-align: right;">
                    <asp:Button ID="Button2" runat="server" Text="Save" OnClick="Button2_Click" OnClientClick="return MoreThanTwo();"
                        ValidationGroup="InsertVal" />
                </p>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

And my code-behind:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data;

public partial class WebForm2 : System.Web.UI.Page
{        

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            DTable = EmptyDTOptions();
            Repeater1.DataSource = DTable;
            Repeater1.DataBind();
        }
    }

    protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
    {

        if (e.CommandName == "AddRow")
        {
            DTable.Rows.Add(0, "", "");
            Repeater1.DataSource = DTable;
            Repeater1.DataBind();
            return;
        }

        if (e.CommandName == "DeleteRow")
        {

            int idx = e.Item.ItemIndex;
            DTable.Rows.RemoveAt(idx);
            Repeater1.DataSource = DTable;
            Repeater1.DataBind();
            return;
        }

    }

    protected void lnkAddRow_Click(object sender, EventArgs e)
    {
        foreach (RepeaterItem item in Repeater1.Items)
        {
            int idx = item.ItemIndex;

            TextBox tb1 = (TextBox)item.FindControl("TBox1");
            TextBox tb2 = (TextBox)item.FindControl("TBox2");

            DTable.Rows[idx]["Desc"] = tb1.Text;
            DTable.Rows[idx]["Pont"] = tb2.Text;
        }
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {                
            // save!             
        }
    }

    private DataTable DTable
    {
        get
        {
            DataTable _dt = (DataTable)Session["DTable"];
            if (Object.Equals(_dt, null))
            {
                _dt = EmptyDTOptions();
                Session.Add("DTable", _dt);
            }
            return _dt;
        }
        set
        {
            Session["DTable"] = value;
        }
    }

    DataTable EmptyDTOptions()
    {
        DataTable dt = new DataTable();
        DataColumn dc;

        dc = new DataColumn("OptionNr", System.Type.GetType("System.Int32"));
        dt.Columns.Add(dc);
        dc = new DataColumn("Desc");
        dt.Columns.Add(dc);
        dc = new DataColumn("Pont");
        dt.Columns.Add(dc);

        return dt;
    }
}

I think it shows what I'm trying to avoid... Advancing to the button2_click with the failed validation (and resetting the javascript variable)... In order to get a list of two or more pairs of items, one of them being a number.

+1  A: 

Rather than calling your function from the OnClientClick on the button, you can add a CustomValidator that calls your JavaScript function.

<asp:CustomValidator ID="CheckMoreThanTwo" runat="server"                       
                     ValidationGroup="InsertVal"
                     ClientValidationFunction="MoreThanTwo" />

Then, modify your JavaScript function as follows:

function MoreThanTwo(source, arguments) {      
    alert(nrOptions);      
    if (nrOptions > 1) {      
        alert('okay - you have: ' + nrOptions);      
        arguments.IsValid=true;
    } else {      
        alert('error - must have at least two options, you only have: '
                  + nrOptions);      
        arguments.IsValid=false;
    }      
}                  

Doing this allows your custom JavaScript validation to work with all the validation code that ASP.NET uses. For instance, if you change to a validation summary, or change validation groups, this custom validator will continue to work the way the rest of the validators work.

Jason Berkan
Thanks Jason! Works as I wanted it to :) Now the javascript variable "nrOptions" is always correct. I'm still curious about, how, in my original code, the body of the Button2_Click is executed with the failed validation... With the OnClientClick="return MoreThanTwo();", when the result is false, I wouldn't expect that... Well, I definitely must start using my javascript with the CustomValidator, whenever it's applicable! :)
naruu