A column can be marked as a row header, rendering its body cells as <th scope="row"> instead of <td> so assistive technologies can associate each row with its header, per the WAI tables with two headers tutorial.
<div class="card">
<h5>Table with header cells in the top row and first column</h5>
<h:form>
<p:dataTable var="slot" value="#{dtRowHeaderView.slots}" rowKey="#{slot.time}"
selection="#{dtRowHeaderView.selectedSlot}" selectionMode="single">
<f:facet name="header">
Delivery slots:
</f:facet>
<p:column headerText="Time" rowHeader="true">
<h:outputText value="#{slot.time}" />
</p:column>
<p:column headerText="Monday">
<h:outputText value="#{slot.monday}" />
</p:column>
<p:column headerText="Tuesday">
<h:outputText value="#{slot.tuesday}" />
</p:column>
<p:column headerText="Wednesday">
<h:outputText value="#{slot.wednesday}" />
</p:column>
<p:column headerText="Thursday">
<h:outputText value="#{slot.thursday}" />
</p:column>
<p:column headerText="Friday">
<h:outputText value="#{slot.friday}" />
</p:column>
</p:dataTable>
</h:form>
</div>
<div class="card">
<h5>Table with an offset column of header cells</h5>
<h:form>
<p:dataTable var="holiday" value="#{dtRowHeaderView.holidays}" reflow="true">
<f:facet name="header">
Holidays taken in the last six months
</f:facet>
<p:column headerText="ID">
<h:outputText value="#{holiday.id}" />
</p:column>
<p:column headerText="Name" rowHeader="true">
<h:outputText value="#{holiday.name}" />
</p:column>
<p:column headerText="July">
<h:outputText value="#{holiday.july}" />
</p:column>
<p:column headerText="August">
<h:outputText value="#{holiday.august}" />
</p:column>
<p:column headerText="September">
<h:outputText value="#{holiday.september}" />
</p:column>
<p:column headerText="October">
<h:outputText value="#{holiday.october}" />
</p:column>
<p:column headerText="November">
<h:outputText value="#{holiday.november}" />
</p:column>
<p:column headerText="December">
<h:outputText value="#{holiday.december}" />
</p:column>
</p:dataTable>
</h:form>
</div>
package org.primefaces.showcase.view.data.datatable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
/**
* Examples from https://www.w3.org/WAI/tutorials/tables/two-headers/
* Demonstrates DataTable's rowHeader column attribute: Example 1 uses it on the first column
* (time slots), Example 2 uses it on an offset column (Name, after ID) to show that any column
* can act as the row header.
*/
@Named("dtRowHeaderView")
@ViewScoped
public class RowHeaderView implements Serializable {
private List<DeliverySlot> slots;
private List<HolidayRecord> holidays;
private DeliverySlot selectedSlot;
@PostConstruct
public void init() {
slots = new ArrayList<>();
slots.add(new DeliverySlot("09:00 – 11:00", "Closed", "Open", "Open", "Closed", "Closed"));
slots.add(new DeliverySlot("11:00 – 13:00", "Open", "Open", "Closed", "Closed", "Closed"));
slots.add(new DeliverySlot("13:00 – 15:00", "Open", "Open", "Open", "Closed", "Closed"));
slots.add(new DeliverySlot("15:00 – 17:00", "Closed", "Closed", "Closed", "Open", "Open"));
holidays = new ArrayList<>();
holidays.add(new HolidayRecord(215, "Abel", 5, 2, 0, 0, 0, 3));
holidays.add(new HolidayRecord(231, "Annette", 0, 5, 3, 0, 0, 6));
holidays.add(new HolidayRecord(173, "Bernard", 2, 0, 0, 5, 0, 0));
holidays.add(new HolidayRecord(141, "Gerald", 0, 10, 0, 0, 0, 8));
holidays.add(new HolidayRecord(99, "Michael", 8, 8, 8, 8, 0, 4));
}
public List<DeliverySlot> getSlots() {
return slots;
}
public List<HolidayRecord> getHolidays() {
return holidays;
}
public DeliverySlot getSelectedSlot() {
return selectedSlot;
}
public void setSelectedSlot(DeliverySlot selectedSlot) {
this.selectedSlot = selectedSlot;
}
public static class DeliverySlot implements Serializable {
private String time;
private String monday;
private String tuesday;
private String wednesday;
private String thursday;
private String friday;
public DeliverySlot() {
}
public DeliverySlot(String time, String monday, String tuesday, String wednesday, String thursday, String friday) {
this.time = time;
this.monday = monday;
this.tuesday = tuesday;
this.wednesday = wednesday;
this.thursday = thursday;
this.friday = friday;
}
public String getTime() {
return time;
}
public String getMonday() {
return monday;
}
public String getTuesday() {
return tuesday;
}
public String getWednesday() {
return wednesday;
}
public String getThursday() {
return thursday;
}
public String getFriday() {
return friday;
}
}
public static class HolidayRecord implements Serializable {
private int id;
private String name;
private int july;
private int august;
private int september;
private int october;
private int november;
private int december;
public HolidayRecord() {
}
public HolidayRecord(int id, String name, int july, int august, int september, int october, int november, int december) {
this.id = id;
this.name = name;
this.july = july;
this.august = august;
this.september = september;
this.october = october;
this.november = november;
this.december = december;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getJuly() {
return july;
}
public int getAugust() {
return august;
}
public int getSeptember() {
return september;
}
public int getOctober() {
return october;
}
public int getNovember() {
return november;
}
public int getDecember() {
return december;
}
}
}