TheCoder4eu / BootsFaces-OSP

BootsFaces - Open Source Project
Apache License 2.0
247 stars 102 forks source link

TabView shows content of all tabs if all tabs are dynamic #1186

Closed de-graeuler closed 1 week ago

de-graeuler commented 2 years ago

Starting with version 1.4.2, tabview initially shows the content of all tabs, if all tabs are created dynamically. This is caused the "active" style being set for all of them: grafik I discovered this in 1.5.0. Using 1.4.1 it works. The issue reproducible with these files:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:b="http://bootsfaces.net/ui"
    xmlns:h="http://java.sun.com/jsf/html">
<h:head />
<h:body>
  <b:container>
    <b:column>
      <b:tabView>
<!-- 
        <b:tab title="Static Tab">Static Tab</b:tab>
 -->
        <b:tab title="#{tab.title}"  value="#{tabView.tabs}" var="tab">
          #{tab.text}
        </b:tab>
      </b:tabView>
    </b:column>
  </b:container>
</h:body>
</html>

As soon as the static tab is not commented, the tab view works as expected.

Tab and tabView are just very simple pojos, where TabViewBean builds a tabs List adding TabBeans constructed with title and string parameter.

TabViewBean:

package tabview;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;

@ManagedBean(name = "tabView")
public class TabViewBean {

  List<TabBean> _tabs = new ArrayList<>();

  @PostConstruct
  public void createTabs() {
    _tabs.add(new TabBean("Dynamic Tab 1", "Content 1"));
    _tabs.add(new TabBean("Dynamic Tab 2", "Content 2"));
    _tabs.add(new TabBean("Dynamic Tab 3", "Content 3"));
  }

  public List<TabBean> getTabs() {
    return _tabs;
  }
}

TabBean:

package tabview;

import javax.faces.bean.ManagedBean;

@ManagedBean(name="tab")
public class TabBean {

  private String _title;
  private String _text;

  public TabBean(String title, String text) {
    _title = title;
    _text = text;
  }

  public String getTitle() {
    return _title;
  }

  public String getText() {
    return _text;
  }
}
de-graeuler commented 2 years ago

I dug into the history of Tab rendering a little bit, and I think i found the cause for the issue: Since ccabe133a603fe15104d17d2f7155033e2f0301a, integrated as a bugfix for issue #1054, the offset value is not incremented within the runnable.

TabViewRenderer

private static void encodeTabContentPanes(FacesContext, ResponseWriter, TabView, int, List<UIComponent>)
[...]
     Runnable r = new Runnable() {
      public void run() {
       try {
        encodeTabPane(context, writer, tab,
          (currentIndex+currentOffset == currentlyActiveIndex) && (!tabView.isDisabled()));
       } catch (IOException ex) {
        // exotic case, suffice it to log it
        LOGGER.log(Level.SEVERE, "An exception occurred while rendering a tab.", ex);
       }
      }
     };

So if the view's first tab is a TabRepeat instance, all contained tabs are rendered with the same isActive state.

stephanrauh commented 1 week ago

I'm afraid development of BootsFaces has slowed down considerably. We'll never manage to address this issue. Let's close it.