0

I'm having a little trouble getting the Bootstrap tabs to persist during a postback which occurs when sorting gridviews.

I have tried the solutions listed in Remain bootstrap tab after postback c# and http://www.aspsnippets.com/Articles/Bootstrap-Tabs-Maintain-Selected-Active-Tab-on-PostBack-in-ASPNet.aspx to no avail.

My current code is:

<div role="tabpanel" id="Tabs">
            <!-- Nav tabs -->
            <ul class="nav nav-tabs" role="tablist" id="pageTabs">
                <li role="presentation" class="active"><a href="#EvidenceBase" aria-controls="home" role="tab" data-toggle="tab">Evidence Base</a></li>
                <li role="presentation"><a href="#Trials" aria-controls="profile" role="tab" data-toggle="tab">Trials</a></li>
                <li role="presentation"><a href="#Resources" aria-controls="messages" role="tab" data-toggle="tab">Resources</a></li>
            </ul>

            <!-- Tab panes -->
            <div class="tab-content">
                <div role="tabpanel" class="tab-pane active" id="EvidenceBase">
                    <div class="col-md-12">
                        <asp:GridView ID="EvidenceBaseGridView" runat="server" AllowPaging="true" AllowSorting="true" OnSorting="EvidenceBaseGridView_Sorting" OnPageIndexChanging="EvidenceBaseGridView_PageIndexChanging">
                        </asp:GridView>
                    </div>
                </div>

                <div role="tabpanel" class="tab-pane" id="Trials">
                    <div class="col-md-12">
                        <asp:GridView ID="TrialsGridView" runat="server" AllowPaging="true" AllowSorting="true" OnSorting="TrialsGridView_Sorting" OnPageIndexChanging="TrialsGridView_PageIndexChanging">
                        </asp:GridView>
                    </div>
                </div>

                <div role="tabpanel" class="tab-pane" id="Resources">
                    <div class="col-md-12">
                        <asp:GridView ID="ResourcesGridView" runat="server" AllowPaging="true" AllowSorting="true" OnSorting="ResourcesGridView_Sorting" OnPageIndexChanging="ResourcesGridView_PageIndexChanging">
                        </asp:GridView>
                    </div>
                </div>
            </div>
        </div>
<asp:HiddenField ID="TabName" runat="server" ClientIDMode="Static" />

And the jQuery I have used to try to set the correct tab on postback is:

<script type="text/javascript">
    $('#pageTabs').on('click', 'li a', function (e) {
        var addressValue = $(this).attr('href').replace("#", "");
        $('#TabName').val(addressValue);
    });

    $(document).ready(function () {
        var tab = $('#TabName').val() != "" ? $('#TabName').val() : "EvidenceBase";
        $('#pageTabs a[href="' + tab + '"]').tab('show');
    });
</script>

I have inspected the value of the hidden field on postback and it seems to only set to the Trials tab and the page always defaults back to the Evidence Base tab. I have also tried removing the "active" class but that makes no difference other than not displaying a tab on initial page load.

Any help on this would be greatly appreciated as my jQuery knowledge is pretty limited.

Thanks.

Community
  • 1
  • 1
bowfinger
  • 45
  • 2
  • 9

3 Answers3

1

Do not use UpdatePanels unless its absolutely necessary. You just have to set the value of asp:HiddenField at server-side, the maintain its state after postback. Setting it clientside wont work as it will be lost on postback.

You could set it on PageIndexChanging event itself like this.

protected void EvidenceBaseGridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    //page index changing logic here
    TabName.Value = "EvidenceBaseGridView";
}

You can do the same for each GridView. Also, as you re-bind the GridView after firing each event, you could set the tab name after Databind.

naveen
  • 53,448
  • 46
  • 161
  • 251
0

ASP Answer
My immediate suggestion would be to use updatepanels.

<asp:ScriptManager runat="server></asp:ScriptManager>


        <!-- Tab panes -->
        <div class="tab-content">
            <div role="tabpanel" class="tab-pane active" id="EvidenceBase">
                <asp:UpdatePanel runat="server">
                    <ContentTemplate>
                         <div class="col-md-12">
                              <asp:GridView ID="EvidenceBaseGridView" runat="server" AllowPaging="true" AllowSorting="true" OnSorting="EvidenceBaseGridView_Sorting" OnPageIndexChanging="EvidenceBaseGridView_PageIndexChanging">
                            </asp:GridView>
                        </div>
                    </ContentTemplate>
               </asp:UpdatePanel>
            </div>

            ...

This will allow the Gridviews to post back without refreshing the entire page. This means that the active class will not be re-set to the initial panel.

Note, any postbacks caused by a control outside of an UpdatePanel will refresh the entire page and thus re-set the active class on your panels.

Also note, don't forget to include your scriptmanager somewhere before your first UpdatePanel.


jQuery Answer ASP.NET will have probably changed the ID of the hiddenfield to something like: ctl00_TabName., you may want to try $('[id*=TabName]') instead of $('#TabName') as your selector.
Pudd
  • 449
  • 3
  • 13
  • thanks @Ben why didn't I think of update panels! The one problem I have is that I have a master page that has an update panel around the main content placeholder, this is to stop a twitter feed script refreshing on every postback event, is there any way around this with the nested update panels or would I be best having a separate master page to inherit from for this page? – bowfinger Apr 21 '15 at 11:12
  • So far as I am aware, there shouldn't be any issue with nested UpdatePanels, the control that triggers a postback will use it's nearest parent. For added control, you can also use the UpdatePanel's Triggers. Is there any reason the twitter feed isn't in it's own UpdatePanel rather than having the whole Content in an update panel? – Pudd Apr 21 '15 at 11:26
  • The twitter feed is on the master page so it is available on all pages that inherit from it, I've tried having it in its own update panel but because it is generated by Twitter's widget JS it refreshes on any event on the page. Wrapping my content placeholder (which is limited to a gridview and some filtering controls on each page) in an update panel solved this refresh problem. What I may do is put the update panels on each page that require them instead as the site is only around 10 pages. I do now have the gridviews working in the bootstrap tabs though using update panels. – bowfinger Apr 21 '15 at 11:37
0

I find UpdatePanels useful for a backend system I've written, and use one for each bootstrap 3 tab and using the method I describe on the linked post below it works great for my website. Hopefully can help some other people too.

I have added my solution to the OP's question (not including my Updatepanels for simplicity) on the Remain bootstrap tab after postback c# link above, which was after the OP said they tried the other answers in that post.

Community
  • 1
  • 1
FlashTrev
  • 507
  • 6
  • 16