Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1344
  • Last Modified:

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

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
sjd01032
Asked:
sjd01032
  • 11
  • 9
1 Solution
 
raterusCommented:
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
 
sjd01032Author Commented:
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
 
raterusCommented:
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
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
sjd01032Author Commented:
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
 
sjd01032Author Commented:
Bumped the points - why no interest?  Should I include something else?
0
 
raterusCommented:
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
 
sjd01032Author Commented:
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
 
sjd01032Author Commented:
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
 
sjd01032Author Commented:
Info:  I'm using AjaxControlToolKit.dll version 1.0.20229.20675
0
 
raterusCommented:
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
 
sjd01032Author Commented:
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
 
raterusCommented:
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
 
sjd01032Author Commented:
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
 
raterusCommented:
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
 
sjd01032Author Commented:
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
 
raterusCommented:
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
 
sjd01032Author Commented:
Hey - sorry about the delay on testing this.  I'll get on it this weekend and have results for Monday.
0
 
raterusCommented:
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
 
sjd01032Author Commented:
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
 
raterusCommented:
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

Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

  • 11
  • 9
Tackle projects and never again get stuck behind a technical roadblock.
Join Now