Postback works once than disappears

55 Views Asked by At

SCENARIO:

I have a website page that has the current order of actions:

  • A repeater list (LIST 1) has buttons with OnClick calls
  • Pressing those buttons calls a code behind method and updates an Update Panel
  • The Update Panel contains another list (LIST 2) with more buttons, now with OnClientClick calls
  • Pressing a button of LIST 2 adds a new row to LIST 2

PROBLEM:

Adding a row to LIST 2 is working, but only once! If I try to press a button of LIST 2 again, the whole div block containing the LIST 2 disappears.

CODES:

LIST 1

<asp:Repeater ID="rptProjetos" runat="server">
    <HeaderTemplate>
        <table class="table table-striped border dtInit">
            <thead>
                <tr>
                    <th>Projeto</th>
                    <th>Data Inicio</th>
                    <th>Data Término</th>
                    <th>Nº Alocados Atualmente</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
    </HeaderTemplate>
    <ItemTemplate>
                <tr>
                    <td><%# DataBinder.Eval(Container.DataItem, "Nome") %></td>
                    <td><%# DataBinder.Eval(Container.DataItem, "DataInicio", "{0: dd/MM/yyyy}") %></td>
                    <td><%# DataBinder.Eval(Container.DataItem, "DataTermino", "{0: dd/MM/yyyy}") %></td>
                    <td><%# DataBinder.Eval(Container.DataItem, "ContagemAlocados") %></td>
                    <td><asp:Button Text="Gerenciar" runat="server" ID="btnGerenciarProjeto" class="btn btn-dark"
                        CommandArgument='<%# DataBinder.Eval(Container.DataItem, "IdProjeto") %>'
                        OnClick="btnGerenciarProjeto_Click" UseSubmitBehavior="false"></asp:Button></td>
                </tr>
    </ItemTemplate>
    <FooterTemplate>
            </tbody>               
        </table>
    </FooterTemplate>
</asp:Repeater>

UPDATE PANEL

<asp:UpdatePanel runat="server" ID="updPanelTeste" UpdateMode="Conditional">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="rptProjetos" />
    </Triggers>
    <ContentTemplate>
      ...
    </ContentTemplate>
</asp:UpdatePanel>

LIST 2

<asp:Repeater runat="server" ID="parentRepeater" OnItemCommand="parentRepeater_ItemCommand">
    <ItemTemplate>
        <div class="customFlexBox">
            <div style="<%#Eval("MarginLeftText") %>">
                <div style="<%#Eval("LeftBorder") %>">
                    <div style="<%#Eval("LeftBorderLast") %>" class="divContentHorizontal">
                        <div class="divContent">
                            <div class="divContainerBotoes">
                                <div class="botaoTooltip">
                                    <asp:Button runat="server" CssClass="buttonAcoes" Text="+" ID="btnAddLiderado"
                                        OnClientClick=<%# string.Format("test({0}, {1}); return false;", Eval("IdProjeto"), Eval("IdAssociado")) %>
                                        />
                                </div>
                            </div>
                        </div>
                    </div>
                    <asp:Repeater runat="server" ID="ChildRepeater" OnItemDataBound="mainRepeater_ItemDataBound" Visible="false">
                    </asp:Repeater>
                    <asp:Repeater runat="server" ID="NovoAvaliadoRepeater" Visible="false">
                    </asp:Repeater>
                </div>
            </div>
        </div>
    </ItemTemplate>
</asp:Repeater>

JAVASCRIPT FOR BUTTONS ON LIST 2

function test(IdProjeto, IdAssociado) {
            document.getElementById('<%=txtLiderDummy.ClientID%>').value = -1;
            document.getElementById('<%=txtLiderDummy.ClientID%>').value = IdAssociado;
            document.getElementById('<%=txtDummy.ClientID%>').value = -1;
            document.getElementById('<%=txtDummy.ClientID%>').value = IdProjeto;
            document.getElementById('<%=txtDummy.ClientID%>').trigger('OnTextChanged');
            __doPostBack("<%=updPanelTeste.UniqueID %>", "");

I tried all postback configurations and all update modes, but still the same behaviour.

1

There are 1 best solutions below

4
Albert D. Kallal On

A repeater list (LIST 1) has buttons with OnClick calls Pressing those buttons calls a code behind method and updates an Update Panel

No, not really!!!!

You have a post-back, and at that point the full page is posted to the server. You are now free to update ANY and ALL controls, including ones inside of the update panel.

So, the term "updates an Update Panel" does NOT matter at this point in time, and is a 100% useless context.

You are updating some stuff on the page. A full post back does NOT care nor matter nor have ANY context of some update panel.

So, we have a button, page post back, and then you just oh so happen to update some controls inside of the update panel - but you are free to update any and all controls on the page, including those in the UP.

Ok, now that above is clear.

The Update Panel contains another list (LIST 2) with more buttons, now with OnClientClick calls Pressing a button of LIST 2 adds a new row to LIST 2

Ok, but did LIST 2 ALREADY have some data? How does LIST 2 start out? Does it start out with no values? or do you have some code in page load that sets up this list 2?

next up, why are you using a trigger here?

Any and ALL buttons in a UP will trigger and post-back that panel.

WHEN the post-back occurs, a FULL page life cycle STILL triggers, and the page load event will fire BEFORE any of your button code in that UP runs.

The button code in that UP can only modify controls and values and things inside of that UP. Code can't get/use/grab/enjoy values of other controls, and can't modify them (you can try, but yo not see the changes).

What this OFTEN suggests then is that the page load event has some code to setup, or load that LIST 2. However, since it runs EVERY time for any post back, and every time for ANY button click (including those in the UP), then if that code has the job to set up the LIST 2, then you always see your changes lost each time.

So, what will occur:

  page load event runs - set up LIST 2
  your button code in UP runs - adds one row, you see 1 row.

Now, if you click again, then :

  page load event runs - set up LIST 2
  your button code in UP runs - adds one row, you see 1 row.

Once again, that means you only ever going to see 1 row, since the page load event ALSO runs each time, and runs BEFORE your button code in the UP.

So, what this means/suggests is that you need to use the all SUPER DUPER important isPostBack test/check in your page load event.

Of the last 200+ web pages I have created, NONE will work correctly if you don't follow this advice: That advice is to place the setup code you have in page load to ONLY run the VERY first time.

Hence, you need this:

 if (!isPostBack) 
 {
     // your setup code here, load repeater code here
 }

Thus, now when you click a button in that UP panel, and add a row to the repeater, then you see that row.

However, you do NOT show how your adding a row to the repeater, and since it is databound, then you have to

a) Add the row to the data source, re-pull data source and re-bind the repeater.

b) Persist the LIST 2 data source in session, or viewstate, and add to that data table/object, and again re-bind to the repeater (or list 2)

Just keep in mind that the page load event and a post-back DOES occur when using a update panel (UP in this post).

it may look like and seem like the page was not posting back, but it DOES!!

This is what we call a partial page post-back, and make no mistake here, the page load event fires, and so does the WHOLE page life cycle process run. The ONLY difference is that only that UP is posted to the server, and thus buttons and code behind can only then modify controls inside of that UP.

Also, in place of an attempted __DoPostBack, if you only want to trigger that UP, then use js and a button inside of the UP with a click method.

eg:

  $('#MyButtonInUP').click()

or, if yo don't tag the buttons clientidmode, then this:

  $('#<%= MyButtonInUP.ClientID %>').click()