Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

multiply command buttons in data table row which one clicked?  RSS feed

 
Tim Resh
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a datatable which has multiply command buttons in a single column for each row and I need to determine which button was clicked? Both buttons need to select the selectedProject so the target is the same for each button. How do you determine which button was clicked in order to select the project and then perform either an "Edit" or "Drill Down"?


 
Partheban Udayakumar
Ranch Hand
Posts: 499
AngularJS Java Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Resh,

If you are using JSF 2.0 and above, you can do this


and get that in the backing bean



You can see this link for different ways to pass parameters
 
Tim Holloway
Bartender
Posts: 18531
61
Android Eclipse IDE Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When you are using an h:dataTable control or one its descendants, the UI control is paired with a DataModel object.

It's common these days for people to set their value= property on a datatable to point directly to a List or array, but that tends to result in horrible code. You're not really saving anything by doing that, since a DataModel is going to be constructed anyway, but you won't be able to take advantage of its properties, since it will be an anonymous DataModel automatically construced by JSF.

The DataModel contains metadata used by JSF to help render and track what's going on in the dataTable. In particular, when an action method (and that includes AJAX action listeners) is fired, the DataModel contains 2 very useful methods that can not only tell you which row was clicked on, but what the data in that row is. These metheds are "getRowData()", which returns the underlying model row object and "getRowIndex()", which returns the (0-origin) row index number for the row whose button you clicked in.

It's very easy to construct and use a DataModel. DataModel is the base class, but there are pre-supplied subclasses for particular types of model data. The most common DataModel classes used are ListDataModel and ArrayDataModel. To use them, either construct an object of the desired class and use its "setWrappedData()" method to use it to wrap your actual (POJO) List or array, or use the convenient all-in-one constructor that takes the model data as a constructor argument.

You can also subclass DataModel or its subclasses. I often do that in order to give them a convenient place to accumulate and hold stuff like column total values, which can then be accessed in the usual property way (via get/set methods).\

It's really bad practice to put parameters, calls, or other logic on a JSF View Template - it violates the Separation of Concerns, reduces re-usability, and can be a real to debug. Plus, you open up potential security holes if you go transferring data back and forth between client and server needlessly.

JSF was designed to work with method references, not method calls. (e.g., action="#{bean.method}", not action="#{bean.method()}") The method is supposed to be called by JSF itself, not by logic on the View.
 
Partheban Udayakumar
Ranch Hand
Posts: 499
AngularJS Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nice explanation I wasn't aware of ListDataModel and ArrayDataModel.
Tim Holloway wrote:JSF was designed to work with method references, not method calls. (e.g., action="#{bean.method}", not action="#{bean.method()}") The method is supposed to be called by JSF itself, not by logic on the View.


So why does JSF allow passing variables using methods?
 
Tim Holloway
Bartender
Posts: 18531
61
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Partheban Udayakumar wrote:
So why does JSF allow passing variables using methods?


Actually, in JSF version 1, it didn't. But JSF2 uses Universal Expression Language (UEL), and UEL was designed to work in many different contexts, not just JSF. Not all of those contexts have the capabilities of JSF.

There are times and places when having the ability to invoke methods with parameters in an EL expression can be useful, but for simple cases like this one, I don't recommend it. A DataModel is going to be constructed anyway, so you don't gain any runtime efficiency, it takes very little effort to add the extra code and the rewards are substantial. And then there's security.

JSF is a Model/View/Controller system. In ordinary operation, the Models remain on the server, and the Views (via Controllers) are synchronized with it. Thus, very little model data actually goes back and forth to the client. You gain 2 benefits from that: 1) less overall network loading and 2) anything that goes to the client can be hacked by an unscrupulous person before sending it back to the server. Data that never leaves the server is therefore more protected - you'd have to hack the server itself.

Note that there is a configuration option for JSF that essentially transfers everything back and forth between client server, but it's not commonly used. Because of the above constraints, that option is best used when you have lots of users (so keeping lots of server-side data is a problem), lots of bandwidth, and the data is either being used in a totally trustworthy environment or it has no value to hackers.

One last thing on the subject of DataModels. You might be wondering why it's optional to use an explicit DataModel on a dataTable. There is one case where having an explicit DataModel isn't necessary. That's the case where the dataTable is strictly display-only and has no updateable controls and/or action controls in it. As I said, a DataModel still gets created, but since you won't be using its powers, you don't need to have a user-addressable DataModel.
 
Tim Resh
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried the ListDataModel but I get the following error

javax.faces.FacesException: DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.

I will change my ListDataModel to SelectableDataModel and see what happens.
 
Tim Resh
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
SelectableDataModel is an interface only.


I changed everything back to ListDataModel and I get the following error. My datatable setup is included below. Some guidance would be appreciated.

Nov 18, 2015 3:23:01 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/rem40/projectListEdit.xhtml]
java.lang.ClassCastException: javax.faces.model.ListDataModel cannot be cast to java.util.List
at org.primefaces.component.datatable.DataTable.findSelectedRowKeys(DataTable.java:1254)
at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:801)
at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:788)
at org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:281)
at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:243)
at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:85)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:924)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863)




 
Tim Holloway
Bartender
Posts: 18531
61
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are using a PrimeFaces datatable control. That control is a subclass of the JSF core h:dataTable and one of its additional features is the ability to "select" (visually highlight) one or more rows for bulk processing. The core dataTable control doesn't have that ability.

The DataModel control reflects that lack by only having methods that assume that a single row is being processed and thus only has the API methods getRowData and getRowIndex to return the values and index of that row. To be able to track multiple row selection, you'd need an extended DataModel that could return ALL the selected rows. PrimeFaces does provide such a class, but you'd have to use it instead of the core single-selection DataModel.

You don't need all that fancy stuff if you simply want to be able to click on a commandButton or commandLink in a table and work with the data in the row that that button or link is on. The basic h:dataTable/DataModel pair can do that without the PrimeFaces "selection" attribute.

To use the extra features of the PrimeFaces control, you need to read the PrimeFaces documentation on how to use its DataModel classes. You may even be able to use core JSF DataModels if you aren't using the multi-row selection feature, but check the docs.
 
Tim Resh
Ranch Hand
Posts: 43
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Tim, as usual your replies are of great help to me.


Tim Resh
 
david ivankamart ivankamart
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thank for share tutorial
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!