1

I have a JSF page with a rich:dataTable where, in each row, I put h:commandLinks to lead to pages with the details of the row selected.

I wanted to make the whole row clickable, calling the action method when the user clicks anywhere in the row.

Is that possible without JavaScript? And if JavaScript is the only way out, what would be the best way do it? Search for a commandLink and "click" it?

Thanks in advance!

Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107

5 Answers5

2

I got the whole rows clickable with a bit of styling. I made the links inside the cells occupy the whole cell with display: block; for the links and padding:0 for the cell.

So, here is what you need to do. In the JSF page, set up rowClasses and the links in each cell:

<rich:dataTable value="#{myMB.listaElems}" var="elem" rowClasses="clickable">
    <rich:column>
        <h:commandLink action="#{myMB.preUpdate(elem)}" value="#{elem.item1}" />
    </rich:column>
    <rich:column>
        <h:commandLink action="#{myMB.preUpdate(elem)}" value="#{elem.item2}" />
    </rich:column>
</rich:datatable>

And in the CSS sheet:

tr.clickable td {
    padding: 0;
}
tr.clickable td a {
    display: block;
    padding: 4px;
}

And that's it!

The only downside is that you need to repeat the link in each cell, but the HTTP flow remains simple, you don't need to change any component, and it will work for h:links or good old <a> html links -- a pretty acceptable tradeoff, I'd say. :)

Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107
1

The basic problem is that JSF (core) is tied to the HTML table element for query-result rendering via the dataTable component. Since a JSF dataTable renders as an HTML table, the result is limited to what can be managed in columns (no out-of-the-box row control that I have seen). The HTML/CSS way to do this is quite elegant but in order to accomplish this in JSF, I believe the UIComponent renderer for dataTable would need to be overridden to output this:

<div class="table">
    <a href="#" class="row">
        <span class="cell">Column-1-Value</span>
        <span class="cell">Column-2-Value</span>
    </a>
    ...
</div>

With CSS styles table row and cell representing display:table, display:table-row and display:table-cell; respectively. This makes the row completely clickable but it behaves as a proper table. I have not embarked on re-writing the JSF renderers and solving the JSF commandLink and other component problems to accomplish the rendering as above but that is probably the ultimate answer. I am not a fan of JSF after fighting with it on a few projects now (as compared to lighter weight combinations of concepts from basic HTML/CSS, a sprinkling of JavaScript, clean Java/Servlets, etc).

Darrell Teague
  • 4,132
  • 1
  • 26
  • 38
  • Indeed, that would be how to generate the semantic HTML needed for the behavior I wanted. But, as for a JSF solution, I think the CSS styling I did was really the best option. I empathize with the frustration with JSF, I've actually moved on and am a happy Grails user now. :) – Elias Dorneles Jul 13 '13 at 15:28
0

For the new RichFaces 4.x, you can use the a4j:commandLink this instead, and make the complete row selectable in CSS. Notice that the 'rowClasses="clickable"' refers to the CSS class to select the whole row:

<rich:column id="fileName" sortable="false" width="618px">
  <a4j:commandLink action="#{controller.setSelectedFile(file)}"
    oncomplete="window.open('#{menuBar.PrintPage}?outputType=pdf', '_blank');"
    rendered="#{not controller.getButtonDisabled(file)}"
    execute="@this" limitRender="true">
  <h:outputText value="${file}" 
    style="text-align:left;width:100%;min-width:400px;"
    title="${file.name} is viewable.">
      <f:converter converterId="MVC.View.Converter_FilePath" />
  </h:outputText>
 </a4j:commandLink>
</rich:column>

Use this CSS class to select the whole row:

tr.clickable td {
    padding: 0;
}

tr.clickable td a {
    display: block;
    padding: 4px;
}
MAbraham1
  • 1,717
  • 4
  • 28
  • 45
0

in your datatable use this one:

<a4j:jsFunction name="selectRow" action="#{userBean.myListener" ...>
  <a4j:param name="currentRow" assignTo="#{userBean.selectedRowId}"/>
</a4j:jsFunction>

its called when you select a row, and you can do whatever you want and pass the selected row with the <a4j:param ...as an option you should also be able to call yourLink.click() or something similar, but that wont be the problem to find out...

reference : Richfaces Forum

jk2
  • 79
  • 7
  • hmm... but then it would be an AJAX request, that would reRender only some elements, right? I was looking for something that would work like a normal button... I guess it isn't possible, then. – Elias Dorneles Dec 08 '11 at 16:03
  • what are you planning to do with it? – jk2 Dec 08 '11 at 16:14
  • I just wanted the behaviour of the commandLink for the whole datatable row. Maybe making the link area occupy the whole cell with CSS... -- I'm using JBoss-EL, btw, so I can do action="#{userBean.doSomething(variable)}". – Elias Dorneles Dec 08 '11 at 16:46
  • so just give the link an id and call yourLink.click() or sth. – jk2 Dec 08 '11 at 16:47
  • hey, man! I ended up solving my problem (making the whole row clickable) just styling the links to occupy the whole space of the table cells. Thanks for your help! – Elias Dorneles Dec 08 '11 at 19:40
0

You may want to try rich:scrollableDataTable. it has attribute onRowClick which you can specify as an event attribute into a4j:support / a4j:ajax nested inside your table. This will make your row clickable.

-cheers :)

prageeth
  • 7,159
  • 7
  • 44
  • 72
Ellie Fabrero
  • 791
  • 2
  • 16
  • 41
  • 1
    actually, `rich:dataTable` also has `onRowClick`. but I wanted to do without AJAX, to simplify the flow. I solved my problem with some style for the links and the cell... thanks anyway! :) – Elias Dorneles Dec 09 '11 at 09:56