2

I'm using both JSF 2.0 and jQuery/javaScript, where needed.

I'm trying to add and remove column from a datatable in a dynamic manner. Problem is - As far as I know I have to re-render the entire table to add or remove columns and that entails a fetch for all the data in the table when in fact, in most cases it isn't neccessary.

For example (typing this for the purpose of problem illustration, syntax errors might exist but assume they don't):

<h:dataTable id="table">
 <h:column id="cul1" rendered="#{mrBean.isCul1_rendered} >
  ...
 </h:column>

 <h:column id="cul2" rendered="#{mrBean.isCul2_rendered} >
  ...
 </h:column>
</h:dataTable>

<f:ajax render="table" />
  <h:commandButton action="#{mrBean.switchIsCul1}" >Switch Cul1</h:commandButton>
  <h:commandButton action="#{mrBean.switchIsCul2}" >Switch Cul2</h:commandButton>
</f:ajax>

As illustrated, when rendering and un-rendering a column, the whole table gets re-rendered. Is there a way to only render the changing column? (As far As i know, render="cul1, won't work)

Thanks!

Ben
  • 10,020
  • 21
  • 94
  • 157

2 Answers2

2

Unfortunately no, that's not possible. A table column can't be represented by a single HTML element. It's actually a collection of loose <td> elements. Technically, you'd need to reference every single <td> individually in order to be able to ajax-render it with JSF. As you can't give each <td> a client ID with JSF, it stops here. You can give them each a common class name, but the JSF ajax render attribtue doesn't work with class names.

Your best bet is to show/hide them with pure CSS/JS. Set a display: none; on the <td> elements of one column and then use JS to toggle it to display: block; and set display: none; on the <td> elements of the other column. You can give the <td>s of an individual column a specific classname using columnClasses attribute.

Kickoff example:

<h:dataTable id="table" binding="#{table}" columnClasses="col1,col2">
  <h:column>...</h:column>
  <h:column>...</h:column>
</h:dataTable>
<f:ajax>
  <h:commandButton ... onclick="switchToCol1('#{table.clientId}')" />
  <h:commandButton ... onclick="switchToCol2('#{table.clientId}')" />
</f:ajax>

(actually, if no bean action needs to be invoked, then a plain <button> is also sufficient)

with this CSS

.col1 {
    display: none;
}

and this JS/jQuery:

function switchToCol1(tableId) {
    var $table = $("[id='" + tableId + "']");
    $('.col1', $table).show();
    $('.col2', $table).hide();
}

function switchToCol2(tableId) {
    var $table = $("[id='" + tableId + "']");
    $('.col1', $table).hide();
    $('.col2', $table).show();
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • TnX. I was kinda hoping to save on browser-server bandwidth with this feature, but I guess it's impossible in this manner... – Ben Nov 02 '11 at 16:12
0

primefaces seems to achieve this though i haven't looked at the underlying code.

primefaces datatable

sgl
  • 199
  • 3