2
votes

I have an XPage that's using the Bootstrap4Xpages project.

I want to have tabs, and wasn't sure the best way to go so I did it manually using bootstrap code rather then the built in XPages tab control which historically has been "lacking". I'm using the basic example from the documentation: http://bootstrapdocs.com/v3.1.1/docs/javascript/#tabs

<!-- Nav tabs -->
<ul class="nav nav-tabs">
  <li class="active"><a href="#home" data-toggle="tab">Home</a></li>
  <li><a href="#profile" data-toggle="tab">Profile</a></li>
  <li><a href="#messages" data-toggle="tab">Messages</a></li>
  <li><a href="#settings" data-toggle="tab">Settings</a></li>
</ul>
<div class="tab-content">
  <div class="tab-pane fade in active" id="home">...</div>
  <div class="tab-pane fade" id="profile">...</div>
  <div class="tab-pane fade" id="messages">...</div>
  <div class="tab-pane fade" id="settings">...</div>
</div>

The problem is that when any type of partial refresh occurs above the tabs, the current tab always moves back to the first tab. So if someone is in a middle tab, hits an "Edit" button, it moves back to the first tab.

How can I get the Tabs to stick through a partial refresh?

Thanks!

1

1 Answers

2
votes

Remove the "active" class of the li-element and set it only after page load via Javascript, e.g.

$(".nav-tabs:first-child").addClass("active")

OR

make sure the tabs are not within the partial refreshed area

UPDATE

I fiddled around a bit and found a solution: Have a look at the two script blocks defined here. The one at the bottom just declares and sets the default tab value. The second is placed within the refreshable area and computes the active tab after the refresh:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">

    <xc:_layoutBS3 navbarTopInverse="true"
        navbarBottomInverse="true" hideHelpArea="false" fullWidth="false">

        <xp:this.facets>
            <xp:div xp:key="facetMiddle" id="refresh">
                <!-- Nav tabs -->
                <ul class="nav nav-tabs">
                    <li>
                        <a href="#home" data-toggle="tab">Home</a>
                    </li>
                    <li>
                        <a href="#profile" data-toggle="tab">Profile</a>
                    </li>
                    <li>
                        <a href="#messages" data-toggle="tab">Messages</a>
                    </li>
                    <li>
                        <a href="#settings" data-toggle="tab">
                            <xp:label value="#{javascript:@Now()}" id="label1">
                                <xp:this.converter>
                                    <xp:convertDateTime>
                                        <xp:this.pattern><![CDATA[${javascript:"dd.MM.yyyy hh:mm:ss"}]]></xp:this.pattern>
                                    </xp:convertDateTime>
                                </xp:this.converter>
                            </xp:label>
                        </a>
                    </li>
                </ul>
                <xp:scriptBlock id="scriptBlock2" type="text/javascript">
                    <xp:this.value><![CDATA[$(".nav-tabs a").on("click", function(){
        activeTab = $(this).attr("href");
}); 

if(activeTab){
    $(".nav-tabs a").each(function(){
        if($(this).attr("href") == activeTab){
            $(this).tab("show");
        }
    });
}]]></xp:this.value>
                </xp:scriptBlock>
                <div class="tab-content">
                    <div class="tab-pane fade in active" id="home">...</div>
                    <div class="tab-pane fade" id="profile">...</div>
                    <div class="tab-pane fade" id="messages">...</div>
                    <div class="tab-pane fade" id="settings">...</div>
                </div>
                <br />
                <xp:link escape="true" text="Refresh" id="link1" styleClass="btn btn-default">
                    <xp:eventHandler event="onclick" submit="true"
                        refreshMode="partial" refreshId="refresh">
                    </xp:eventHandler>
                </xp:link>
            </xp:div>

            <xp:scriptBlock id="scriptBlock1" xp:key="facetHelp"
                type="text/javascript">
                <xp:this.value><![CDATA[var activeTab = "#home";]]></xp:this.value>
            </xp:scriptBlock>
        </xp:this.facets>
    </xc:_layoutBS3>
</xp:view>

The label that displayes the timestamp is just to prove that the partial refresh occurred. One caveat: if you want the fade effect then the fading occurs also after every refresh. Would suggest you to not use the fade effect.

Live demo here: http://mardou.dyndns.org/bs3template.nsf/tabs.xsp

The source can be found here, too: https://github.com/zeromancer1972/Bootstrap-3-Template/blob/12a7f79cd53fe0923eb10986cfc7e581196379db/ODP/XPages/tabs.xsp