I have a project that has an update timer that does some background stuff, mainly checking for activity. We need to add some text boxes that have an onChange event. However while typing, the timers event will trigger the textbox.
I thought isolating each in their own updatepanel would help with no success.
The timer event cannot be removed so that’s off the table…I need to take care of the issue on the textbox only. Any suggestions would be appreciated!
Here’s the complete code…basically made a new project as a simple sample since the real project is massive!
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="conditional" ChildrenAsTriggers="false">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="tick" />
</Triggers>
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="3000" />
<div>
<asp:Label ID="lblTimer" runat="server" Text="0" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="TextBox1" EventName="TextChanged" />
</Triggers>
<ContentTemplate>
<div>
<asp:TextBox ID="TextBox1" runat="server" />
<asp:Label ID="lblNewText" runat="server" Text="-" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
lblNewText.Text = TextBox1.Text
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
lblTimer.Text += 1
End Sub
End Class
2
Answers
I'm not sure if it's the best answer, but this is what I've come up with as a quick solution. Basically made up a user control that contains a text box and hidden button. There's a JS onchange event on the textbox that clicks the button, that then raises an event. I'm testing in a few spots now....still dealing with tab index issues but it's not critical.
front page:
code-behind:
You not likely to get this setup working with update panels
First up, the onchange event for the textbox ONLY triggers when you tab out. So trying to wire up and use the onchange not going to work all that well.
Next up, if the text box in question suffers a post back (inside a panel or not), then of course the page refresh, and the cursor position is re-set to the start. Thus trying to type into the text box when such post-backs occur not going to work well at all.
All in all this means that if you going to have a text box that allows typing , and NOT suffer the cursor reset, then the text box really can’t be part of ANY post back, can it?
Remember, a update panel DOES cause a page life cycle to trigger. And that includes EVERY TIME the code behind page load event runs. So, keep this in mind, since page load does trigger. So, while an update panel gives the illusion of a page post back not occurring, this is NOT THE CASE!
The correct term for a update panel is what we call a "partial post back". In other words, only the content in the update panel is posted back to the server. However, make no mistake here, it is a full valid page life cycle, and that as noted includes the page load event firing every time (and then say the button code stub runs after page load).
So, what you could do is say leave the text box outside of the update panel, and then trigger the update panel to run (to say update the label).
So, this works (I assume jQuery here).
So, for each keystroke in the text box, we used the onkey up (since onchange requires a tab out of the text box for contents of textbox to be seen, and MORE important no tab out of the text box is required).
Code behind:
So, above does work, and does allow typing. Since the text box is outside of the update panel, then the post back ONLY includes the content in the update panel, and thus the cursor position of the text box does not change or get messed up.
Keep in mind that since the text box was OUTSIDE of the update panel, then the control is read only (you can’t change the control in code behind for the udpate panel, but you CAN read the value(s) from controls outside).
You suggest that the timer is off the table (bad position here, you need some flexibility in your approach here).
You can have/enjoy the timer UP tick away at the incrementing label value.
However, for your text box?
I suggest you adopt JavaScript and client side code. The simple matter is at end of day, if you going to allow typing in the text box, it CAN NOT be posted back and suffer a page life cycle. If the text box does, then as noted, you might as well dump all update panels, since the behaver you see will not be ANY different had you not introduced any update panels in the first place!
So, the above proof of concept code does allow the label to be changed, and the text box being outside of the panel thus works.
You are FAR better off to introduce client side JavaScript here. So, while I think a update panel is one of the greatest features of webforms? They don’t really work if you going to try keystroke processing.
You also don’t mention/note/suggest/hint what your final goal here is?
For a search as you type text box?
Well, the internet has boatloads of examples. Many examples using jQuery.UI and "auto complete"
However, if you have a aversion to writing JavaScript, then you can adopt a nice auto complete utility from the ajaxtoolkit. Adopting the aj toolkit’s auto complate thus results in you not having to write ANY JavaScript (of course the aj toolkit behind the scenes will and does wire up things automatic, and does so doing JavaScript routines that you don’t see nor have to worry about).
As noted, in above, since the textbox is outside of the UP, then it does not post-back to the server and thus does not get messed up.
Introduction of say a 2nd update panel with a timer should thus again work fine with the above setup.
So, we have this:
And thus we see this effect:
So, at end of day, you are FAR FAR FAR better off to wire this up using client side JavaScript. The update panels will buy you some real cool abilities, and often eliminate the need for writing and adopting JavaScript and ajax calls to the server code, but as noted, for keystroke processing, they fall down rather hard.
I think you should outline your goal, and what you trying to accomplish here in place of stomping your feet and stating that you must use a Timer control and update panels. You don’t have to, and to be fair, the issue of a Timer control probably not really much of a issue here anyway.
The goal so far is the need for keystroke processing in a text box, and that’s something that update panels really can’t help you much with here.
Edit: User is NOT trying to do keystroke processing
Ok, so then this is a easy walk in the park in a sense.
Just remove all your trigger junk in the markup (you do NOT need those triggers).
So, this then works 100% just fine:
And code behind is:
And result when run looks like this:
Edit 3: textbox is to NOT post back
Ok, I can make a longer explain, but the post is 100% correct – the textbox is posting back due to the timer update panel (a seperate panel). Giving this some thought, this now makes sense.
So, I suggest this code for the text box update panel now:
And thus code behind for when the user tabs out of the text box now becomes some button code. Hence this: