Dynamically style one tab of all tabs of a tabSheet

I’m trying to pimp a CUBA application and I have to admit I’m struggling with very basic tasks. So here is my next question:
I’m trying to highlight a tab on a certain condition and leave it blunt when condition is not met.

Here is what I have so far

           <tabSheet id="allTabs" css="margin-bottom: 15px;">
                <tab id="tabInfo" caption="Info" margin="true,false,true,false">
                 .....
                </tab>
               <tab id="tabLegalEntities" caption="Legal Entities">
               ........

In my screen controller I have the following:

    private void setTabCaption(){
        logger.info("setting tab caption");
        if(getEditedEntity().getLegalEntities().size() > 0){
            allTabs.getTab("tabLegalEntities").setIcon("font-icon:EXCLAMATION_CIRCLE");
            allTabs.getTab("tabLegalEntities").setCaption("Legal Entities (" + getEditedEntity().getLegalEntities().size() + ")");
        } else {
            allTabs.getTab("tabLegalEntities").setIcon(null);
            allTabs.getTab("tabLegalEntities").setCaption("Legal Entities");
        }
    }
// btw this doesn't refresh when I inject the tab itself:
// tabLegalEntities.setCaption("Legal Entities (" + getEditedEntity().getLegalEntities().size() + ")");

Which works and looks like this:

image

But I want a bit more, some additional styling like changing the font color or font weight or background even… Assigning styles doesn’t work as it seems…

image

Hi,
In order to style your components, you need to:

  • assign a stylename to the component
  • create theme extension
  • figure out what CSS rules can set the necessary style
  • add CSS rules to the theme file

Detailed instruction with example similar to your screenshot:
Tabsheet in the screen:

        <tabSheet id="tabsheet">
            <tab id="tab1" caption="Tab1"/>
            <tab id="tab2" caption="Tab2"/>
        </tabSheet>

Assign tab stylename in the screen controller:

    @Inject
    private TabSheet tabsheet;

    @Subscribe
    public void onBeforeShow(BeforeShowEvent event) {
        tabsheet.getTab("tab1").setStyleName("alert");
    }
}

Create theme extension, action available in the “Generic UI” element of the project tree:
image

Open the screen in the Chrome browser (or any other browser that has debugging tools).
Press F12 to open Developer Console. Navigate to the HTML element that corresponds to the styled tab header:

In the DOM tree we see that styled tab header has many CSS classes. One of them is “v-tabsheet-tabitemcell-alert” - it has a custom “alert” postfix added in the screen controller.

Inside of this styled DIV, there is another DIV containing header caption. It has CSS class “v-captiontext”.

Here you need some CSS knowledge to create a styling rule that will override any other rules (displayed for the selected element in the bottom part of the developer console).

The working code is:

  .v-tabsheet-tabitemcell-alert .v-captiontext {
    font-weight: bold;
    color: red;
  }

Then we place this rule to the styles.css file of the extended theme (hover in my case).
image

Then restart the application.

Open the page. Expect to see changed style, but it doesn’t work…
image

It’s because Chrome agressively caches style files.
Press Ctrl + F5 to force update the browser cache.
Then the styling appears:
image

Voilà.

See also
https://doc.cuba-platform.com/manual-7.2/web_theme_extension.html
https://doc.cuba-platform.com/studio/#generic_ui_themes

2 Likes

Hello!

To make more complex styling, you should extend the application theme. How to do this you can find in the documentation: 3.5.9.2. Extending an Existing Theme.

When your condition is met, you can add a custom style name to the tab:

if (getEditedEntity().getLegalEntities().size() > 0){
    //...
    allTabs.getTab("tabLegalEntities").setStyleName("custom-tab-stylename")
}

In the extended theme create styles for this tab:

.v-tabsheet-tabitemcell.v-tabsheet-tabitemcell-custom-tab-stylename {
   background-color: #fceb96;
}
.v-tabsheet-tabitemcell.v-tabsheet-tabitemcell-custom-tab-stylename .v-tabsheet-tabitem .v-caption {
   color: #ad442d;
}
.v-tabsheet-tabitemcell.v-tabsheet-tabitemcell-custom-tab-stylename .v-tabsheet-tabitem.v-tabsheet-tabitem-selected .v-caption {
   color: #ff0000;
}

Note, that instead of Tab instance is injected a tab’s layout, e.g.:

@Named("tabSheet.tab1")
private VBoxLayout tab1;
2 Likes

Thanks for the great detailed answers, that helps a lot.
The story of Java Frameworks: Easy things are really complicated and complicated things are really easy :slight_smile: