Search code examples
jsfxhtmlmojarra

Dynamic color on every row in h:datatable


Context

I'm working on a very old system which is literally falling apart and my actual task is to fix it.

This old system uses old libraries which I can't really modify cause maybe it would fix a small part of the system but it would just make the rest of it much more broken. Though, I can probably add new libraries which won't interfere with the old ones.

My Problem

What I'd like to do is to add a class on certain rows of the table based on a server-side condition like rowStyleClass="#{searchTask.hasLinkedDecision(task) ? 'info' : ''}" but I can't find any solution since apparently there is several libraries named JSF but none of them is the same and the one my system depends on seems to be the only one that doesn't support dynamic rows style classes.

JSF Dependencies

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.2.4</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.2.4</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>

Problematic Code

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
.....
<h:dataTable id="dttask"
             binding="#{searchTask.taskTable.dataTable}"
             value="#{searchTask.taskTable.dataList}" var="task"
             styleClass="table table-striped table-hover">
         <!--rowStyleClass="#{searchTask.hasLinkedDecision(task) ? 'info' : ''}"-->

    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                .....
            </h:panelGroup>
        </f:facet>
        <a href="${facesContext.externalContext.requestContextPath}/faces/pages/tasks/editing/add-tasks.xhtml?id=#{task.noTask}">
            <h:outputText value="#{task.noTask}"/>
        </a>
    </h:column>

    <h:column sortBy="">
        <f:facet name="header">
            <h:panelGroup>
                <h:outputText value="No CT"/>
            </h:panelGroup>
        </f:facet>

        <h:panelGroup rendered="#{not empty searchTask.getNoCT(task)}">
            <div class="tooltipobjet" tabindex="0"
                 style="border-bottom: 1px dotted black;">
                .....
            </div>
        </h:panelGroup>
    </h:column>

    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                <h:commandLink actionListener="#{searchTask.sortDataListTask}">
                    .....
                </h:commandLink>
            </h:panelGroup>
        </f:facet>
        <abbr title="#{searchTask.getTaskLabel(task.principal)}">
            .....
        </abbr>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                <h:commandLink actionListener="#{searchTask.sortDataListTask}">
                    .....
                </h:commandLink>
            </h:panelGroup>
        </f:facet>
        <h:outputText value="#{searchTask.getLabelValueDomainSearch('domain.type.task', task.type)}"/>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                <h:commandLink actionListener="#{searchTask.sortDataListTask}">
                    .....
                </h:commandLink>
            </h:panelGroup>
        </f:facet>
        <div class="tooltipobject" tabindex="0"
             style="border-bottom: 1px dotted black;">
            .....
        </div>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                <h:commandLink actionListener="#{searchTask.sortDataListTask}">
                    .....
                </h:commandLink>
            </h:panelGroup>
        </f:facet>
        <h:outputText value="#{task.dateConform}">
            <f:convertDateTime pattern="#{constants.DATE_TIME_FORMAT_CREATE_JOUR_HH_MM}"/>
        </h:outputText>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                <h:commandLink
                        actionListener="#{searchTask.sortDataListTask}">
                    .....
                </h:commandLink>
            </h:panelGroup>
        </f:facet>
        <h:outputText value="#{searchTask.getAdminUnitAbbr(task.treatingAdminUnit)}"/>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:panelGroup>
                <h:commandLink actionListener="#{searchTask.sortDataListTask}">
                    .....
                </h:commandLink>
            </h:panelGroup>
        </f:facet>
        <h:outputText value="#{searchTask.getLabelValueDomainStatusByUser(task.status, task.statusEditDate)}"/>
    </h:column>
</h:dataTable>
.....
</html>

Solution

  • 9 Things... the one but last is your answer

    1. This question does not seem related to 'stabelizing' an application that almost breaks down but an improvement.
    2. JSF (Mojarra in your case) 2.2.4 is not that old.
    3. Does not look like you are using jsp but facelets
    4. You cannot reproduce in plain java-se sdk with class with a main method and no additional libraries and so the java tag on the question is not correct.
    5. There are not several libraries called JSF, there is an api called JSF which is implemented by two implementations. Mojarra and MyFaces, both implementing the same api.
    6. Where did you see rowStyleClass on the h:datatable https://docs.oracle.com/javaee/7/javaserver-faces-2-2/vdldocs-facelets/h/dataTable.html
    7. If you get deprecation warnings compile time it most often means you do use some newer versions of libraries (less old ones) but you still use old methods from previous versions.
    8. Answer is in Changing h:datatable cell color or style dynamically in JSF or with a little more code conditionally set class values for h:datatable cells
    9. This is the answer for your version of libraries. If you do not want to use this and don't want to 'duplicate' code IN columns (not ON colums) you could create a small composite component