9

I would like to add a tooltip for each element in a p:selectManyCheckBox. However I can't come up with a solution.

I've got a class Role that has 3 properties, "id" (Long), "name" (String) and "description" (String). The name is displayed and I would like to have the description as a tooltip.

This is a working piece of code:

<p:selectManyCheckbox layout="pageDirection" value="#{roleBean.selectedRoles}" converter="roleConverter">
    <f:selectItems value="#{roleBean.roles}" var="role" itemLabel="#{role.name}" itemValue="#{role}"/>
</p:selectManyCheckbox>

The roleConverter is a FacesConverter that converts the Role to an id and visa versa.

I came up with this:

<p:selectManyCheckbox layout="pageDirection" value="#{roleBean.selectedRoles}" converter="roleConverter">
    <c:forEach var="role" items="#{roleBean.roles}">
        <f:selectItem id="role#{role.id}" itemLabel="#{role.name}" itemValue="#{role}" />
        <p:tooltip for="role#{role.id}" value="#{role.description}"/>
    </c:forEach>
</p:selectManyCheckbox>

But unfortunately it doesn't work.

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
siebz0r
  • 18,867
  • 14
  • 64
  • 107

3 Answers3

16

You can achieve this by using the SelectItem#getDescription() property as below:

<p:selectManyCheckbox layout="pageDirection"
    value="#{roleBean.selectedRoles}" converter="roleConverter">
    <f:selectItems value="#{roleBean.roles}" var="role" 
        itemValue="#{role}" itemLabel="#{role.name}" 
        itemDescription="#{role.description}" />
</p:selectManyCheckbox>

This is supported since PrimeFaces 6.2 (actually because of this very answer you're reading now).

In case you're not on PrimeFaces 6.2 yet and cannot upgrade for some reason, then you need to manually override the PrimeFaces SelectManyCheckboxRenderer#encodeOptionLabel() as below in order to recognize and render it:

public class YourSelectManyCheckboxRenderer extends SelectManyCheckboxRenderer {

    @Override
    protected void encodeOptionLabel(FacesContext context, SelectManyCheckbox checkbox, String containerClientId, SelectItem option, boolean disabled) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("label", null);
        writer.writeAttribute("for", containerClientId, null);

        if (option.getDescription() != null) {
            writer.writeAttribute("title", option.getDescription(), null);
        }

        if (disabled) {
            writer.writeAttribute("class", "ui-state-disabled", null);
        }

        if (option.isEscape()) {
            writer.writeText(option.getLabel(), null);
        } else {
            writer.write(option.getLabel());
        }

        writer.endElement("label");
    }

}

Which is registered as follows in faces-config.xml:

<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.SelectManyCheckboxRenderer</renderer-type>
        <renderer-class>com.example.YourSelectManyCheckboxRenderer</renderer-class>
    </renderer>
</render-kit>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

Tooltip support for selectManyCheckbox was added since Primefaces v6.2 version. Other components support this too.

XHTML code is the same BalusC reported

<p:selectManyCheckbox layout="pageDirection" value="#{roleBean.selectedRoles}" converter="roleConverter">
    <f:selectItems value="#{roleBean.roles}" var="role" 
        itemValue="#{role}" itemLabel="#{role.name}" itemDescription="#{role.description}" />
</p:selectManyCheckbox>

but is not anymore required override the PrimeFaces SelectManyCheckboxRenderer

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
Alexcat
  • 87
  • 4
0

I had to modify BalusC's solution to make it work in my case. That is beacause I had to build the List of SelectItems on the Bean-side.

public List<SelectItem> getMyItems(){
  List<SelectItem> mySelectItems = new ArrayList<>();
  [loop or ohter code to collect items]
  // create SelectItem with description
  mySelectItems.add(new SelectItem([value], [label], [description]));
  ...
  return mySelectItems;
}

Then these SelectItems can be used with:

<f:selectItems value="#{myBean.myItems}"/>
brianH
  • 33
  • 2
  • 5
  • Mandator/client and access rights specific SelectItems. Better code doing that at the Bean-side than in xhtml. – brianH Apr 06 '18 at 12:31