Solved

Can we fix an AJAX Enabled ASP.NET 2.0 Web Form with UpdatePanels controlling Validation controls?

Posted on 2008-06-10
21
1,333 Views
Last Modified: 2013-11-07
What I need to happen is to have 3 controls (2 dropdownlists and one date User Control) only be required if any of the 3 have values.

The code I've attached is complete and will run with the exception of the Date User Control.  It is simply a textbox (with the OnTextChanged event exposed), a MaskedEditExtender, a CalendarExtender, and a RequiredFieldValidator.  The IsRequired property simply sets the RequiredFieldValidator.Enabled (this of course is on the Date's textbox).

My problem is that the code when clearing the Date's Textbox, it doesn't fire the OnTextChanged event.  Also, the two DropDownLists do fire, but the validation controls aren't always set (I can't make this happen consistently).

Thank you!
<table width="948" id="tblMain" runat="server">

    

    <tr align="left">

        <td></td>

        <td></td>

        <td></td>

        <td>Test Text (never required):</td>

        <td>

            <asp:TextBox runat="server" ID="txtTest" />

        </td>

    </tr> 

    

        <tr align="left">

            <td></td>

            <td></td>

            <td></td>

            <td>DropDownList1 (if selected DropDownList2 and Date1 are required):</td>

            <td>

                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="CheckValidation_TextChanged">

                    <asp:ListItem Text="[Select]" value="0"></asp:ListItem>

                    <asp:ListItem Text="something1" value="1"></asp:ListItem>

                    <asp:ListItem Text="something2" value="2"></asp:ListItem>

                </asp:DropDownList>

                <asp:UpdatePanel ID="UpdatePanel1" runat="server" RenderMode="Inline" UpdateMode="conditional">

                    <ContentTemplate>

                        <asp:CompareValidator ID="cvDropDownList1" runat="server" ControlToValidate="DropDownList1" 

                        ErrorMessage="DDL 1 must be selected." Operator="NotEqual" ValueToCompare="0" 

                        SetFocusOnError="True" Enabled="false" >*</asp:CompareValidator>

                    </ContentTemplate>

                    <Triggers>

                        <asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="SelectedIndexChanged" />

                    </Triggers>

                </asp:UpdatePanel>

            </td>

        </tr>

        <tr align="left">

            <td></td>

            <td></td>

            <td></td>

            <td>DropDownList2 (if selected DropDownList1 and Date1 are required):</td>

            <td>

                <asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true" OnSelectedIndexChanged="CheckValidation_TextChanged" >

                    <asp:ListItem Text="[Select]" value="0"></asp:ListItem>

                    <asp:ListItem Text="something else 1" value="1"></asp:ListItem>

                    <asp:ListItem Text="something else 2" value="2"></asp:ListItem>

                </asp:DropDownList>

                <asp:UpdatePanel ID="UpdatePanel2" runat="server" RenderMode="Inline" UpdateMode="conditional">

                    <ContentTemplate>

                        <asp:CompareValidator ID="cvDropDownList2" runat="server" ControlToValidate="DropDownList2" 

                        ErrorMessage="DropDownList2 must be selected." Operator="NotEqual" ValueToCompare="0" 

                        SetFocusOnError="True" Enabled="false" >*</asp:CompareValidator>

                </ContentTemplate>

                <Triggers>

                    <asp:AsyncPostBackTrigger ControlID="DropDownList2" EventName="SelectedIndexChanged" />

                </Triggers>

            </asp:UpdatePanel>

            </td>

        </tr>

        <tr align="left">

            <td></td>

            <td></td>

            <td></td>

            <td>Date 1 (if entered DropDownList1 and DropDownList2 are required):</td>

            <td><user:DateEntry id="usrDate" runat="server" IsRequired="false" RequiredErrorMessage="Date is required." OnTextChanged="CheckValidation_TextChanged" ></user:DateEntry></td>

        </tr>

        <tr>

            <td align="right" colspan="5">

                <asp:Button ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click" />

            </td>

        </tr> 

    </table>

 
 

--CODE BEHIND--

protected void btnSave_Click(object sender, EventArgs e)

    {

        if (Page.IsValid)

        {

            Response.Write("WHAT??");

        }

    }
 

    protected void CheckValidation_TextChanged(object sender, EventArgs e)

    {

        AssessValidate(DropDownList1.SelectedIndex != 0 || DropDownList2.SelectedIndex != 0 ||

           !string.IsNullOrEmpty(usrDate.Value));

    }
 

    private void AssessValidate(bool isRequired)

    {

        cvDropDownList1.Enabled = isRequired;

        cvDropDownList1.EnableClientScript = isRequired;

        cvDropDownList2.Enabled = isRequired;

        cvDropDownList2.EnableClientScript = isRequired;

        usrDate.IsRequired = isRequired;

    }

Open in new window

0
Comment
Question by:sjd01032
  • 11
  • 9
21 Comments
 
LVL 33

Expert Comment

by:raterus
Comment Utility
What's this <user:DateEntry> control and how can I know the events you have attached to it actually function as expected and are compatible with asp.net ajax?
0
 

Author Comment

by:sjd01032
Comment Utility
As I stated (and I'll attach the code tomorrow):

<user:DateEntry> is simply a textbox (with the OnTextChanged event exposed), a MaskedEditExtender, a CalendarExtender, and a RequiredFieldValidator.  The IsRequired property simply sets the RequiredFieldValidator.Enabled (this of course is on the Date's textbox).

None of the controls are other than ASP and AJAX.
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Yes, please send the code.  I'd also look at the browser's source to make sure you actually see an "onchange" event listed for the textbox.
0
 

Author Comment

by:sjd01032
Comment Utility
The OnTextChanged event does fire when populating the textbox, but not always when clearing it.  I've attached the code for the user control.

I've attached the source code and what was rendered in the table for the DropDownList2 and Date 1

I don't see an onchange JS for the textbox like I do for DropDownList2 - evidently this is where I need the help?
<%@ Control Language="C#" AutoEventWireUp="false" CodeFile="DateEntry.ascx.cs" Inherits="DateEntry" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<table border="0" cellpadding="0" cellspacing="0">

    <tr>

        <td nowrap>

            <asp:TextBox ID="txtDate" runat="server" OnTextChanged="txtDate_TextChanged" Columns="10"></asp:TextBox><asp:Image ID="imgDate" SkinId="ImageCalendar" runat="server" />

            <ajaxToolkit:MaskedEditExtender ID="meeDate" runat="server" Century="2000" ClearMaskOnLostFocus="True" Mask="99/99/9999" MaskType="Date" TargetControlID="txtDate" />

            <ajaxToolkit:CalendarExtender ID="ceDate" runat="server" TargetControlID="txtDate" PopupButtonID="imgDate" />

        </td>

        <td class="RequiredIndicator">

            <asp:RequiredFieldValidator ID="rfvDate" runat="server" ControlToValidate="txtDate"

                ErrorMessage="Field is required." Display="Dynamic" Enabled="False">*</asp:RequiredFieldValidator>

            <asp:CompareValidator id="cvDate" runat="server" ControlToValidate="txtDate"

                    Display="dynamic" Enabled="false">*</asp:CompareValidator>

        </td>

    </tr> 

</table>
 

----------------code behind begin:

public partial class DateEntry : System.Web.UI.UserControl

{

    public event EventHandler TextChanged;
 

    protected virtual void OnTextChanged()

    {

        if (TextChanged != null)

            TextChanged(this, new EventArgs());

    }
 

    protected void txtDate_TextChanged(object sender, System.EventArgs e)

    {

        OnTextChanged(); // raise the trlTextChanged event

    }
 

/// <summary>

    /// Determines whether or not entry is required for the control.

    /// </summary>

    /// <value>trus/false</value>

    public bool IsRequired

    {

        get { return rfvDate.Enabled; }

        set { rfvDate.Enabled = value; }

    }
 

    /// <summary>

    /// Sets/gets the message that is displayed when the required field validation fails.

    /// </summary>

    /// <value>String</value>

    public string RequiredErrorMessage

    {

        get { return rfvDate.ErrorMessage; }

        set { rfvDate.ErrorMessage = value; }

    }

}
 
 

----------------code behind end-----segment of source begin:
 
 

<tr align="left">

		<td></td>

		<td></td>

		<td></td>

		<td>DropDownList2 (if selected DropDownList1 and Date1 are required):</td>

		<td>

                <select name="ctl00$MainContentPlaceHolder$DropDownList2" onchange="javascript:setTimeout('__doPostBack(\'ctl00$MainContentPlaceHolder$DropDownList2\',\'\')', 0)" id="ctl00_MainContentPlaceHolder_DropDownList2">

			<option selected="selected" value="0">[Select]</option>

			<option value="1">something else 1</option>

			<option value="2">something else 2</option>
 

		</select>

                <span id="ctl00_MainContentPlaceHolder_UpdatePanel2">

                        <span id="ctl00_MainContentPlaceHolder_cvDropDownList2" style="color:Red;visibility:hidden;">*</span>

                </span>

            </td>

	</tr>

	<tr align="left">

		<td></td>

		<td></td>

		<td></td>

		<td>Date 1 (if entered DropDownList1 and DropDownList2 are required):</td>

		<td>

<table border="0" cellpadding="0" cellspacing="0">

    <tr>

        <td nowrap>

            <input name="ctl00$MainContentPlaceHolder$usrDate$txtDate" type="text" size="10" id="ctl00_MainContentPlaceHolder_usrDate_txtDate" /><img id="ctl00_MainContentPlaceHolder_usrDate_imgDate" src="../images/calendar.png" style="border-width:0px;" />

            <input type="hidden" name="ctl00$MainContentPlaceHolder$usrDate$meeDate_ClientState" id="ctl00_MainContentPlaceHolder_usrDate_meeDate_ClientState" />

            

        </td>

        <td class="RequiredIndicator">

            <span id="ctl00_MainContentPlaceHolder_usrDate_rfvDate" style="color:Red;display:none;">*</span>

            <span id="ctl00_MainContentPlaceHolder_usrDate_cvDate" style="color:Red;display:none;">*</span>

        </td>
 

----------------end of source segment

Open in new window

0
 

Author Comment

by:sjd01032
Comment Utility
Bumped the points - why no interest?  Should I include something else?
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Sorry, I was away from my computer for a day.  Have you tried adding autopostback="true" to the textbox in the UserControl?  This is the only way you can raise server events when they happen.
0
 

Author Comment

by:sjd01032
Comment Utility
raterus - this caused a nice little infinite loop.  Below is the code I added.  I've rolled back so no one else gets stuck in the same loop.  What am I doing wrong?

Thanks for not giving up on me!
Infinite loop with AutoPostBack="true":
 

ASPX:

<user:DateEntry id="usrDate" runat="server" AutoPostBack="true" IsRequired="false" RequiredErrorMessage="Date is required." OnTextChanged="CheckValidation_TextChanged" ></user:DateEntry>
 

ASCX Code Behind:

/// <summary>

    /// Gets or sets the AutoPostBack property of the date textbox

    /// </summary>

    public bool AutoPostBack

    {

        get { return txtDate.AutoPostBack; }

        set { txtDate.AutoPostBack = value; }

    }

Open in new window

0
 

Author Comment

by:sjd01032
Comment Utility
I think this post "explains" the infinite loop issue:  http://www.codeplex.com/AjaxControlToolkit/WorkItem/View.aspx?WorkItemId=13013

What I don't understand is the comment, "Problem was resolved with manually setting loaded control ID. "
0
 

Author Comment

by:sjd01032
Comment Utility
Info:  I'm using AjaxControlToolKit.dll version 1.0.20229.20675
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
As I think you've already suspected, I don't think the AutoPostBack=True is to blame here, I think it just enabled what you were hoping would work, to actually work, and now you need to work out the bugs with the OnTextChanged event.

I couldn't make much sense of that article you just posted either.  That would make sense if you are dynamically loading controls, but I don't see you doing that.

I think right now, you just need to isolate the issue.  Forget right now raising the event in the UserControl so the base page can use it.  Just get the textchanged event of the textbox working, and then we'll work in the other part.  I don't know about you, but I'm getting lost in all these eventhandlers!
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:sjd01032
Comment Utility
Actually, I just read, "The problem is an infinate loop of postbacks occures when using the MaskedEditExtender on a textbox that has autopostback enabled" from this page:  

http://www.codeplex.com/AjaxControlToolkit/WorkItem/View.aspx?WorkItemId=15445

So, I disabled the MaskedEditExtender and it's working.  Now I have to get the MaskedEditExtender to work and I'll be in good shape!  Any thoughts on that one?
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Sorry, that's over my head!  Sounds like it's a bug that needs to be fixed, and until then you'll have to just disable the MaskedEditExtender and find another way.
0
 

Author Comment

by:sjd01032
Comment Utility
Well, I still have half the original problem.  

"My problem is that the code when clearing the Date's Textbox, it doesn't fire the OnTextChanged event..." - OK - THIS WORKS NOW

"...Also, the two DropDownLists do fire, but the validation controls aren't always set (I can't make this happen consistently)." - THIS STILL DOESN'T work consistently.
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Ok, lets go back to the beginning.  Looks like you only want the DropDownLists to be validated when certain conditions are met in the page.  Can you tell me more about these conditions?  It's hard to determine it from your example.

e.g.

"if they enter text, then dropdownlist1 & 2 are required",
or
"if no text is entered, only date is required", stuff like that, etc.
0
 

Author Comment

by:sjd01032
Comment Utility
There are 3 controls: 2 dropdownlists and the Date user control we worked with earler.

If any of the controls have a value (selectedindex != 0 for either dropdown - and the date has a value), then all 3 of those controls need to have their validation enabled.  By default the validation controls are disabled since on page load none of the 3 controls have values.

I think I've supplied all the code you'd need to make it run - you can see that it works kind of randomly and I can't figure out why.

Any help?
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
When an UpdatePanel "refreshes", it is only going to change the state of the controls within it.  I think you have two options.  Create one large UpdatePanel that holds all the controls and their validators.  Or enabled/disable the validators from javascript (I think this can be done, but I can't provide you an example)
0
 

Author Comment

by:sjd01032
Comment Utility
Hey - sorry about the delay on testing this.  I'll get on it this weekend and have results for Monday.
0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
I don't think that's your solution here.  You said yourself in the next comment "I still have my original problem..", which we dialoged about for a few more days and then you disappeared?
0
 

Author Comment

by:sjd01032
Comment Utility
You know how Monday  turns into Friday so quickly.  Actually I went back and tested and it's working.  So, I do believe that was the culprit.  Thank you for your attention on this matter.  I don't know the etiquette here - should I give you the points for being a sounding board (which is normally what helps the most)?  I don't have a problem with that...Let me know.
0
 
LVL 33

Accepted Solution

by:
raterus earned 425 total points
Comment Utility
It's really up to you, if I've helped you anyway, any how, then you should give the points where it helped most.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now