views:

38

answers:

1

Basics:

  • I have a text box (txtDepositAmount) that people can enter a deposit amount into and a drop down (ddlSelectedTerm) that sets the terms.
  • Through these two values I calculate the APY (lblCurrentApy).

Rules:

  • If only one of the values is selected I still want to do an update on the current APY label and clear it.
  • If either value changes I want to update the current APY and recalculate.

The problem:

As soon as I click away from the textbox and onto the drop down to select my term the drop down flashes and closes because the textbox TextChanged event was just fired.

I have to click on the drop down a second time to be able to select anything!

Do I need to change what event I'm looking at or do I need to move some of the controls outside of the UpdatePanel? Can this only happen if some of the business rules change? Should I just give up and go to javascript?

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <table width="100%">
            <tr>
                <td align="left" style="width: 10%" class="LineAlign">
                    &nbsp;
                </td>
                <td align="left" style="width: 40%" class="LineAlign">
                    <asp:Label ID="lblDollarSymbol" runat="server" Text="$"/> 
                    &nbsp;
                    <asp:TextBox ID="txtDepositAmount" runat="server"
                     AutoPostBack="true" TabIndex="1" MaxLength="14" 
                     ontextchanged="txtDepositAmount_TextChanged"/>
                </td>
                <td align="left" style="width: 30%" class="LineAlign">
                    <asp:DropDownList ID="ddlSelectedTerm" runat="server" 
                     AutoPostBack="true" TabIndex="2"
                     onselectedindexchanged="ddlSelectedTerm_SelectedIndexChanged">
                    </asp:DropDownList>
                </td>
                <td align="center" style="width: 20%">
                    <asp:Label ID="lblCurrentApy" runat="server"/>
                    &nbsp;
                    <asp:Label ID="lblPercentSymbol" runat="server" Text="%"/>
                </td>
            </tr>
        </table>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="ddlSelectedTerm" />
        <asp:AsyncPostBackTrigger ControlID="txtDepositAmount" />
    </Triggers>
</asp:UpdatePanel>
A: 

autopostback="true" on your textbox is causing this, since both controls are reloaded after they leave the textbox. I doubt there is a way to avoid this as long as they are in the same UpdatePanel.

Maybe you could set focus to the dropdown list after the textbox-initiated postback, or you could probably make this work by putting the controls in separate UpdatePanels. But really it seems the wrong way to go about it. I would use javascript (and ajax if the logic is complicated) to update the APY. Or just add a "calculate" button...

(Edit) Here's a slightly ugly hack to avoid ajax, three update panels and still be able to do your logic server side. I do not approve of this method but it is quick and dirty.

Put the Label control that contains the calculation results in an UpdatePanel. The input controls do not need to be in an UpdatePanel.

In the update panel (with the results) have a hidden submit button:

    <asp:Button ID="DoCalculate" style="display:none;" UseSubmitBehavior="false"
 runat="server" OnClick="Recalculate()" />

This should be the trigger for the UpdatePanel. Then have your two input controls click that button using javascript to cause a partial postback to the "results" panel. Here is the code to add this javascript for the dropdown, for example, in Page_Load:

    ddSelectedTerm.Attributes.Add("onSelectedIndexChanged",
"document.getElementByID('" + DoCalculate.ClientID + "').Click()");

Then in put the C# code to do the calculation and update the label in the 2nd update panel in the "Recalculate()" method.

This should work, and give you better layout control and less code flow ugliness then using 3 update panels.

jamietre
I tried separate update panels and if the textbox is changed then it doesn't have knowledge of the drop down having a value despite me plainly seeing that it does have one.
hyprsleepy
I just tried putting the two controls in separate UpdatePanels and the result field in a third one (automatically updated), and doing the calculation for the result on page_load and it works as expected. You don't need any server-side events for ontextchanged and onselectedindexchanged. Still, though, this is a ton of overhead to do something that can be done with a few lines of javascript.
jamietre
So you are saying that 3 update panels works? Wow.
hyprsleepy
Yes, it did work. But I can only imagine the web of javascript that asp.net must produce to accomplish this...
jamietre
The JavaScript may be tricky because the calculation required uses things in the Session and ApplicationCache and most of it is done server side.
hyprsleepy
What events are you doing async postbacks on?
hyprsleepy
It was basically the same as your original. UpdatePanel1 with the textbox, which is the trigger, UpdatePanel2 with the DropDownList which is the trigger, then UpdatePanel3 which has the label with the result, and is updated automatically. Populate the label value in Page_Load. To do this with javascript, if you need to perform the log server-side then why not just set up your logic in a webservice and use JQuery to communicate with it through ajax?
jamietre
Can you show me some code? I haven't used jQuery before.
hyprsleepy
That would be beyond the scope of this response :) If I were in your shoes I would probably be leaning strongly towards the "calculate button" solution...
jamietre
I can't - it isn't my decision. Marketing peeps want it a certain way, period.
hyprsleepy
Silly marketing peeps. They never know what's good for them. I thought of YAUWTAA (Yet Another Ugly Way To Avoid Ajax) that is actually reasonably clean and can be done with one UpdatePanel. My response edited above. I haven't tried it but it's simple enough and should work.
jamietre