hi, I want to create a datatable on click of button, as soon as I click on button a new datable will be added.
I know how to creat datatable and how to iterate but my requirement is that onclick of button I need to insert a blank datatable after that user will enter the data that will be saved to DB
I recommend that instead of presenting a naked List as the dataTable model that you create a ListDataModel and wrap the List in the ListDataModel. If you do that you will not need to parameterize the button click method because the ListDataModel's getRowData() method will automatically contain the model data for the row that was selected and its rowIndex method will indicate what the row number was.
You are not saving anything by avoiding the DataModel. It will be automatically constructed by JSF anyway, since it is needed to render the table. But an automatically-constructed model is anonymous, so you cannot access its action properties.
I don't recommend parameterizing anything on a View definition. It muddies the boundaries between Model and View and raises the cost of overall maintenance.
An IDE is no substitute for an Intelligent Developer.
Joined: Nov 14, 2011
Interesting.. most examples I see show the List<object> as the backing model. I'll look at using ListDataModel. I assume then I also need the DataTable component, and set the ListDataModel<MyType> on it as the backing model.
Out of curiosity, is there a problem with parameterizing the button click? Is it just bad form, or is it that because the ListDataModel is created already, no point in using a 2nd list and thus no need to specify the parameter in the call? You say it muddies the view.. but if I am iterating an object anyway with the <p:dataTable.. why does it make a difference if I set the var and pass that in a click?
Unfortunately there's a lot of junk out there. Books can be bad enough - if I see one more "login code example" in a J2EE or JEE text book, I'm going to scream. But samples on the Internet can help propagate all sorts of bad practices. Which is why I spend so much time telling people not to use actionListeners, for example.
In JSF1, the DataModel was mandatory, I think, and only became optional in JSF2. However, the DataModel is still built, whether you do it yourself or take the lazy way out and target a raw array or collection. The difference is that when the DataModel is created automatically, you cannot easily get access to it, and the DataModel enhances the underlying data with some very important and useful functionality. So it's generally better to create one yourself. The exception is when you do not intend to have server-side code reference selected rows in the table, since you use those functions (getRowData and getRowIndex) to determine what row the client selected to submit from. If the client isn't submitting rows, then there's no need for explicit access to a DataModel.
Joined: Nov 14, 2011
Makes sense. Where do you typically create the data model? In the @PostConstruct? I assume you use the FacesContext to find the data table component, then set the model with your created one?
john lazeraski wrote:Makes sense. Where do you typically create the data model? In the @PostConstruct? I assume you use the FacesContext to find the data table component, then set the model with your created one?
NO!!! I wouldn't be such a hypocrite as to tell others not to muck around with FacesContext and Component trees and then turn around and do it myself! I do it POJO-style.
I do it cached-on-demand. The first time the dataTable invokes the "get" method for its datamodel, I test to see if I have a copy stored in the backing bean (in other words, that it's not NULL). If I do not, then I invoke whatever persistent services are required to get the table data from wherever (or create it, if that's what it takes). Then I construct the DataModel object itself, wrapped around the table data and I store it in the backing bean. Then I return the stored copy. Next call to the "get" method finds the previously-stored copy, so the overhead is minimal.
There are 2 reasons I do it this way instead of in @PostConstruct. First, and most importantly, PostConstruct is a relatively recent development that I could never depend on. Secondly, if I need to refresh the data in the table, all I have to do is reset the model object to NULL. That will discard the old data and cause the "get" method to do a new model build on the next request. There's absolutely no need to go anywhere near JSF's internals. The only faces classes required are facesx.model classes.