简体   繁体   中英

Recover selected tab after postback with Bootstrap

I'm using tabs on Bootstrap: in this example I have 4 tabs and use some ASP.NET WebControls within them, like DropdownLists, Buttons and TextBoxes. When I select dropdownlist item or click a buttons, lost previous and actual selected tab state and cannot recover it.

<script src="/Scripts/bootstrap-tabs.js" type="text/javascript"></script>
<script>
   $(function(){
      $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
      // Get the name of active tab
      var activeTab = $(e.target).text(); 
      // Get the name of previous tab
      var previousTab = $(e.relatedTarget).text(); 
      $(".active-tab span").html(activeTab);
      $(".previous-tab span").html(previousTab);
   });
});
</script>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
        <asp:Panel ID="Panel1" runat="server" GroupingText="Selección Fecha">    
        <ul id="profileTabs2" class="nav nav-tabs">
                  <li><a href="#detallepagosactividad" data-toggle="tab">uno</a></li>
                  <li><a href="#detallefacturacion" data-toggle="tab">dos</a></li>
                  <li><a href="#detallefacturacion2" data-toggle="tab">tres</a></li>
                  <li><a href="#detallefacturacion3" data-toggle="tab">cuatro</a></li>
        </ul> 
        <div class="tab-content" id="myTabContent2">
              <div id="detallepagosactividad" class="tab-pane fade">
                  some text
              </div>
              <div id="detallefacturacion" class="tab-pane fade">
                  other text
              </div>
              <div id="detallefacturacion2" class="tab-pane fade">
                  <asp:Button ID="Button1" runat="server" Text="Button" />
              </div>
              <div id="detallefacturacion3" class="tab-pane fade">
                   <asp:Button ID="Button2" runat="server" Text="Button" />
              </div>
              </div>
              <hr>
                    <p class="active-tab"><strong>Active Tab</strong>: <span></span></p>
                     <p class="previous-tab"><strong>Previous Tab</strong>: <span></span></p>
              <hr>
        </asp:Panel>
        </ContentTemplate>
        </asp:UpdatePanel>

Bootstrap TabContainer is a html control and not a asp.net webcontrol. Thus no state is maintained for the tab container. But on a postback the the entire update panel content is replaced with the new content from server. This is what is resetting you tab settings (in fact, the css class "active" is removed from the previously selected tabs)

You have to rethink your update panel arrangement. Instead of wrapping your entire bootstrap tabcontainer into a updatepanel you should break up your update panel into multiple smaller ones. Like so:

    <asp:Panel ID="Panel1" runat="server" GroupingText="Selección Fecha">    
    <ul id="profileTabs2" class="nav nav-tabs">
              <li><a href="#detallepagosactividad" data-toggle="tab">uno</a></li>
              <li><a href="#detallefacturacion" data-toggle="tab">dos</a></li>
              <li><a href="#detallefacturacion2" data-toggle="tab">tres</a></li>
              <li><a href="#detallefacturacion3" data-toggle="tab">cuatro</a></li>
    </ul> 
    <div class="tab-content" id="myTabContent2">
          <div id="detallepagosactividad" class="tab-pane fade">
              <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                  some text
                </ContentTemplate>
              </asp:UpdatePanel>
          </div>
          <div id="detallefacturacion" class="tab-pane fade">
              <asp:UpdatePanel ID="UpdatePanel2" runat="server">
                <ContentTemplate>
                  some text
                </ContentTemplate>
              </asp:UpdatePanel>
          </div>
          <div id="detallefacturacion2" class="tab-pane fade">
              <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                  <asp:Button ID="Button1" runat="server" Text="Button" />
                </ContentTemplate>
              </asp:UpdatePanel>
          </div>
          <div id="detallefacturacion3" class="tab-pane fade">
               <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                  <asp:Button ID="Button2" runat="server" Text="Button" />
                </ContentTemplate>
              </asp:UpdatePanel>
            </div>
          </div>
          <hr>
                <p class="active-tab"><strong>Active Tab</strong>: <span></span></p>
                 <p class="previous-tab"><strong>Previous Tab</strong>: <span></span></p>
          <hr>
    </asp:Panel>

On this way you gain more control over what content you want to update. Additionally on postbacks your tabs and tabpanes won´t be reset to initial state

First use a hidden control to store the index of the selected tab: The initial value should be (1) which is the first tab:

User onclick or OnClientClick at the anchor or LinkButtons to set the hidden field value for example:

<li><a href="#detallepagosactividad" data-toggle="tab" onclick="SelectTab('1')">uno</a></li>
<li><a href="#detallefacturacion" data-toggle="tab" onclick="SelectTab('2')">dos</a></li>


<script type="text/javascript">
    function SelectTab(tab) {
        document.getElementById('<%=hdnTab.ClientID %>').value = tab;
    }
</script>

Put this javascript at the end of your html and before the < /body> tag

   <script type="text/javascript">
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_endRequest(function (s, e) {
            FixTabs();
        });
    </script>

Now place FixTabs javascript function at the begining and will run at every completed postback. In this function just simply get the selected tab and set its class to "active".

 <script type="text/javascript">
        function FixTabs() {
            var tabIndex = document.getElementById('<%=hdnTab.ClientID%>').value;
            var t1 = document.getElementById("detallepagosactividad");
            var t2 = document.getElementById("detallefacturacion");
            //do same for the rest of tabs
            t1.setAttribute('class', '');
            t2.setAttribute('class', '');
            if (tabIndex == "1")
                t1.setAttribute('class', 'active');
            else if (tabIndex == "2")
                t2.setAttribute('class', 'active');
        }
    </script>

Hope this helps..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM