I have the follwing datatable structure:
<p:dataTable editable="true" editMode="cell"..>
<p:column headerText="value_1">
<p:cellEditor>
<f:facet name="output">
<h:outputText ...
</f:facet>
<f:facet name="input">
<p:inputText ....
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="value_2">
<p:cellEditor>
<f:facet name="output">
<h:outputText ...
</f:facet>
<f:facet name="input">
<p:inputText ....
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="action">
<p:commandButton tabindex="-1"...
</p:column>
The problem is that the last column breaks the tab-navigation. I can tab from column1 to column2 but cannot reach the next row. When I remove the last column everything works as expected. I want a tab-behaviour like this:
row1_column1 -> row1_column2 -> row2_column1 -> row2_column2 -> ....
I also tried to remove tabindex="-1"
and use a p:cellEditor
in the third column, but the behaviour stays the same, I can only tab in row1.
What am I missing?
I'm using Primefaces version 6.0
The PrimeFaces data table cell editor tab behavior is implemented here:
2243 tabCell: function(cell, forward) {
2244 var targetCell = forward ? cell.next() : cell.prev();
2245 if(targetCell.length == 0) {
2246 var tabRow = forward ? cell.parent().next() : cell.parent().prev();
2247 targetCell = forward ? tabRow.children('td.ui-editable-column:first') : tabRow.children('td.ui-editable-column:last');
2248 }
2249
2250 this.showCellEditor(targetCell);
2251 },
Check line 2244. The next()
and prev()
calls do not check whether it's a .ui-editable-column
. So it basically blindly tabs into any column even if it doesn't contain a <p:cellEditor>
.
We thus want to fix exactly that part to check for .ui-editable-column
. Put the below code in a JS file.
if (PrimeFaces.widget.DataTable) {
PrimeFaces.widget.DataTable = PrimeFaces.widget.DataTable.extend({
tabCell: function(cell, forward) {
var targetCell = forward ? cell.next('td.ui-editable-column') : cell.prev('td.ui-editable-column');
if(targetCell.length == 0) {
var tabRow = forward ? cell.parent().next() : cell.parent().prev();
targetCell = forward ? tabRow.children('td.ui-editable-column:first') : tabRow.children('td.ui-editable-column:last');
}
this.showCellEditor(targetCell);
}
});
}
Make sure that this JS file is loaded after PrimeFaces own JS. The best place for that is shown below:
<h:head>
...
</h:head>
<h:body>
<h:outputScript name="primefaces-patches.js" target="head" />
...
</h:body>