views:

381

answers:

5

I have a couple of textboxes that will contain dates only. If one textbox has a date and the user tries to submit without entering a date in the other date textbox they will be stopped before submit. The way I want to do this is with the following javascript function:

function ClientValidate(sender, args) {
       // Get Both form fields
       var txtdate1 = document.getElementById('<%=txtdate1.ClientID%>');
       var txtdate2 = document.getElementById('<%=txtdate2.ClientID %>');

    // do you client side check to make sure they have something
       if (txtdate1.value != '' && txtdate2.value == '') {

        args.IsValid = false;
    }
    else
    {
        args.IsValid = true;
    }
    if (txtdate2.value != '' && txtdate1.value == '') {

        args.IsValid = false;

    }
    else {
        args.IsValid = true;
    }
}

The creation of the textboxes and date stuff is as follows.

Dim bttndate1 As New ImageButton
    bttndate1.ID = "bttndate1"

    Dim txtdate1 As New TextBox
    txtdate1.ID = "txtdate1"
    txtdate1.Width = 65

    Dim calex1 As New AjaxControlToolkit.CalendarExtender
    calex1.TargetControlID = "txtdate1"
    calex1.Format = "MM/dd/yyyy"
    calex1.PopupButtonID = "bttndate1"

    '**************** date box2 ***************

    Dim bttndate2 As New ImageButton
    bttndate2.ID = "bttndate2"
    bttndate2.Style.Add("cursor", "pointer")

    Dim txtdate2 As New TextBox
    txtdate2.ID = "txtdate2"
    txtdate2.Width = 65


    Dim calex2 As New AjaxControlToolkit.CalendarExtender
    calex2.TargetControlID = "txtdate2"
    calex2.Format = "MM/dd/yyyy"
    calex2.PopupButtonID = "bttndate2"

Here is the Validator

    Dim custval As New CustomValidator
    custval.ID = "ValidPage"
    custval.ClientValidationFunction = "ClientValidate"
    custval.ErrorMessage = "You Must Enter a 'From' Date and a 'To' Date"
    custval.ErrorMessage = "You Must Select a Vendor"
    custval.SetFocusOnError = True
    custval.ControlToValidate = "txtdate1"
    custval.EnableClientScript = True

MY problem is that the javascript isn't finding the two textboxes because i create them in code any ideas?

A: 

Try this in your validator code...

custval.ControlToValidate = txtdate1.ClientID
Chalkey
my error is still the same. Name 'txtdate1' is not declared.
Eric
A: 

I think that besides tying the validator to the control as Chalkey recommended, you need to generate script in the code-behind to get the references to your controls.

The problem is that you are trying to add a reference to a control that doesn't exist until the site runs. In other words, you are trying to create the javascript to reference date text boxes before the date text boxes exist (they don't exist until the page is generated). So the lines:

`var txtdate1 = document.getElementById('<%=txtdate1.ClientID%>');       
`var txtdate2 = document.getElementById('<%=txtdate2.ClientID %>');

will not work as you expect (they might not even compile).

I'd add these two lines in the method creating the date text boxes so that you have your jscript references:

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "var txtdate1 = document.getElementById('" + txtdate1.ClientID + "');", true);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "var txtdate2 = document.getElementById('" + txtdate2.ClientID + "');", true);

This will create the two javascript variables, txtdate1 and txtdate2, that can be used to reference the date elements.

The difference is that the script to find the controls is generated in the code behind at the same time the controls are being created.

Jeff Siver
can you give me more details? I'm not sure I understand fully but it seems legit.
Eric
Changed the explanation to something that is (hopefully) clearer.
Jeff Siver
A: 

Use the ClientScript manager to register your javascript at the same time you create the calendar controls.

Joel Coehoorn
A: 

I dont know exactly where you define your controls but they should be defined in the page class as protected properties something like this:

Protected txtdate1 As New TextBox
Protected txtdate2 As New TextBox

Protected bttndate1 As New ImageButton
Protected bttndate2 As New ImageButton

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

    bttndate1.ID = "bttndate1"
    Page.Form.Controls.Add(bttndate1)

    txtdate1.ID = "txtdate1"
    txtdate1.Width = 65
    Page.Form.Controls.Add(txtdate1)

    Dim calex1 As New AjaxControlToolkit.CalendarExtender
    calex1.TargetControlID = "txtdate1"
    calex1.Format = "MM/dd/yyyy"
    calex1.PopupButtonID = "bttndate1"

    '**************** date box2 ***************

    bttndate2.ID = "bttndate2"
    bttndate2.Style.Add("cursor", "pointer")
    Page.Form.Controls.Add(bttndate2)

    txtdate2.ID = "txtdate2"
    txtdate2.Width = 65
    Page.Form.Controls.Add(txtdate2)

    Dim calex2 As New AjaxControlToolkit.CalendarExtender
    calex2.TargetControlID = "txtdate2"
    calex2.Format = "MM/dd/yyyy"
    calex2.PopupButtonID = "bttndate2"


    MyBase.OnLoad(e)
End Sub
Jamal
A: 

I'm an opponent of the ClientScriptManager. The solutions above will probably work, but an alternate method would be to declare a couple of variables in JavaScript outside of your ClientValidate() method.

var textdate1;
var textdate2;

Put a literal in your page somewhere (you can really put it anywhere as long as it has the runat="server" attribute).

<asp:Literal ID="litJSVars" runat="server" />

Then in event where you're creating the textboxes and stuff, add the following code:

this.litJSVars.Text = "textdate1 = document.getElementById('" + txtdate1.ClientID + "');\\n";
this.litJSVars.Text += "textdate2 = document.getElementById('" + txtdate2.ClientID + "');";

It isn't better or worse than the ideas above, it's just a different way of going about it.

Joel Etherton