How to fill a JSF/Primefaces DataTable from a ManagedBean? - jsf

I'm realizing my first application using JSF2 and Primefaces 5 .
I want that when the user press a button my managed bean creates a new DataTable and fill it with some data. How can I do that from my managed bean?
This is a part of code of my managed bean.
...
//This is the managed bean's method executed when the user presses the button.
public void execute() {
...
//Get the data from database and put the entries in a list of java beans called myList.
//Here I create a ListDataModel to convert myList in a DataModel to pass to the datatable
ListDataModel<myJavaBean> tableData = new ListDataModel<myJavaBean>(myList);
//Then I create a new datatable..
DataTable dataTable = new DataTable();
//.. and I set the data
dataTable.setValue(tableData);
//I define the columns
Column idColumn = new Column();
idColumn.setHeaderText("id");
Column dateColumn = new Column();
dateColumn.setHeaderText("date");
Column timeColumn = new Column();
timeColumn.setHeaderText("time");
Column stateColumn = new Column();
stateColumn.setHeaderText("state");
//Here I add the columns to the table
dataTable.getChildren().add(idColumn);
dataTable.getChildren().add(dateColumn);
dataTable.getChildren().add(timeColumn);
dataTable.getChildren().add(stateColumn);
...
When I press the button this part of code create a new DataTable with the correct number of columns and the correct header.
Also the number of row is correct but the row are completely empty, I suppose this is due to the fact that I have not bound the Columns with the respective java bean properties of the list. How can I do that?

So you want to create a UI component from a managed bean ???
Maybe I'm missing something here, but a proper and simpler way to acheive this is that the Datatable must be declared in facelet (your_page.hxtml) using <p:datatable> and link it to a backing bean containing the data (i.e. value="#{yourbean.yourlist}").
On startup, your backing bean can be empty. You just have to render UI differently, whether your data is loaded or not (see the "rendered" tag on the datatable component).
Just fill data into the bean when you have to do it (button/execute).
And do not forget to update UI parts (see "update" tag on your action button) in order to refresh altered page regions (datatable at least).
example:
<p:datatable id="mytable" var="child" value="#{mybean.children}" rendered="#{not empty mybean.children}">
...
</p:datatable>
...
<p:button update="mytable">
...

Related

PrimeFaces datatable default sortBy from backing bean

I have a data table with a POJO object:
<p:dataTable id="table" var="object" sortBy="#{object.name}" sortOrder="DESCENDING">
object has fields id, name, date, size for example. I am able to set default sort field using xhtml, but I want set it from backing bean.
I am able to parse column id when user creates sort request for example name.
public void sortEventListener(AjaxBehaviorEvent actionEvent) {
String id = ((SortEvent) actionEvent).getSortColumn().getColumnKey();
String[] idPath = id.split(":");
sortBy = idPath[idPath.length - 1];
sortOrder = ((SortEvent) actionEvent).isAscending();
}
My task detects which column user wants to sort and persists it to db. After reload the data table should be sorted by this column.
When I set
sortBy="#{bean.sortBy}" // sortBy = name
it's not working and data table is not sorted after rendering the page.
Please help.
If you bind your data table to a org.primefaces.component.datatable.DataTable object in your bean or find the table component in your bean, you can use the table object to set the sortBy value expression programmatically.
To get an idea how PrimeFaces is handling sorting, you can have a look at the source code at GitHub.
When you have the sort column, you can easily get the sort value expression. So, in your listener you could use something like:
UIColumn sortColumn = sortEvent.getSortColumn();
ValueExpression sortByVE = sortColumn.getValueExpression("sortBy");
By the way, you can replace the parameter type AjaxBehaviorEvent with SortEvent in your sort listener method.
Now, store the sortByVE expression, and set it as the sortBy value expression of the bound table when needed:
dataTable.setValueExpression("sortBy", sortByVE);
If you want to create the value expression from scratch, use something like:
FacesContext context = FacesContext.getCurrentInstance();
ExpressionFactory ef = context.getApplication().getExpressionFactory();
ValueExpression ve = ef.createValueExpression(context.getELContext(),
"#{object.name}",
Object.class);
dataTable.setValueExpression("sortBy", ve);
In this example "#{object.name}" is fixed. You should construct it based on the value you get from your sort listener.
If you want to find your table in your bean, OmniFaces Components might be helpful. It also offers a shortcut method to create value expressions.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
Programmatically getting UIComponents of a JSF view in bean's constructor
How do I set the value of HtmlOutputTag in JSF?

IceFaces selectInputDate value changes after getting data

I have an ice:selectInputDate but the value of the component is not the same as in the backing bean. I have to select two different dates to successfully update the variable value of the backing bean.
What am I missing?
What I want to do is to populate a table after getting some data from the DB with the date as a filter.
You should post some code to get a better idea. Are you using a valueChangeListener and partialSubmit? If so, if you set the variable in the listener it would be the same in the bean as soon as you select the inputDate.
You can populate the table from the listener
for example:
public void dateListener(ValueChangeEvent evt){
yourDate = (Date) evt.getNewValue();
//get your data for the table
}

How do I bind a inputbox values to a map value in a backing bean property when using a wizard

I am using the Primefaces wizard component. On one tab I am dynamically creating input boxes based on previous tabs input(user type). The inputbox text labels are derived from a list. In my backing bean, I have a map that contains input labels as keys and inputbox inputs as values.
Clicking on next, I would like the map(values) to be updated with the user input (corresponding to the key)
<c:forEach items="#{gdsiGeodataBean.actionCommand.fields}" var="reqs">
<h:outputLabel for="#{reqs.name}" value="#{reqs.name}:* " />
<pou:inputText value="#{gdsiGeodataBean.actionCommand.values['reqs.name']}" required="true" requiredMessage="Input is required."/>
</c:forEach>
My backing bean :
private List<RequiredParam> fields; // +getter (no setter required)
private Map<String, String> values; // +getter (no setter required)
public CommandAction(String actionName, String actionParams, String context) {
this.actionName = actionName;
this.actionParams = actionParams;
this.contextName = context;
//Set up parameters
getRequiredParams();
getOptionalParams();
fields = getFields();
values = new HashMap<String, String>();
}
Essentially what I would like is for the map values to be updated with user inputs from the textinput boxes.
Your approach to bind the input value to a map is not entirely correct.
<pou:inputText value="#{gdsiGeodataBean.actionCommand.values['reqs.name']}" required="true" requiredMessage="Input is required."/>
You're specifying a fixed map key instead of a dynamic map key based on the currently iterated #{reqs}. This way all submitted values will end up in one and same fixed map key "reqs.name", whereby each one overrides each other so that you only get the value of the last field in the map.
You need to remove those singlequotes to make it a really dynamic key.
<pou:inputText value="#{gdsiGeodataBean.actionCommand.values[reqs.name]}" required="true" requiredMessage="Input is required."/>
Unrelated to the concrete question, even though this approach will work when used as-is in your question, the <c:forEach> will fail in certain circumstances. E.g. when used inside a composite component or an iterating JSF component. Rather use <ui:repeat> instead. See also JSTL in JSF2 Facelets... makes sense?

How to implement adjusting dynamicly dataTable's row number equal to user inputted/selected value in JSF page?

How to implement adjusting dynamicly dataTable's row number equal to user inputted/selected value in a JSF page?
The context is like this. There is a inputText component NumOfCars and a dataTable named CarInfoList for inputting information of cars. The row number of CarInfoList depends on the value of NumOfCars. For example, if the user input 5 in the NumOfCars, we want the row number of CarInfoList adjust to 5 right away.
Anybody knows how to implement this with a JSF page?
If you mean that you want to show a list of 5 cars max after the user enters 5, just bind the inputText field to a backing bean and for simplicity add a button that you bind to an action method. In this action method, create a sublist of your main list. Your view should then bind to this sublist.
Basically something like this:
#ManagedBean
#ViewScoped
public class SomeBacking {
private int numberOfCars;
private List<Car> allCars;
private List<Car> displayedCars;
#PostConstruct
public void init() {
allCards = ... // get from some service
displayedCars = allCars;
}
public void adjustDisplayedCars() {
displayedCars = allCars.subList(0, numberOfCars);
}
// Getters/setters
}
(Don't forget to add a range validator to your inputText component.)
If with 'right away' you mean without pressing any button, you can do this with AJAX. If you're using JSF 2.0, AJAX is build-in, otherwise you need an external component library such as RichFaces.
I suggest to use primefaces component or jquery datatable plugin available at
http://www.datatables.net/release-datatables/examples/basic_init/zero_config.html
Also primefaces datatable component has great features and ajax compatibility...
Check out it here

How to create commandlink programmatically

We have a system built on seam/richfaces.
There's this webpage where the tables are rendered from dynamic context (from multiple different datasources, and each of them uses a different layout to represent essentially the same real world concept). As a result, this table is binded to a bean, and it's columns/layout are generated from this bean.
Now I need to add a command link on a specific column, equivalent to
<a4j:commandLink value="#{actBean.Ids}" action="#{actBean.genDetails}">
<f:setPropertyActionListener target="#{actBean.Ref}" value="#{cont}"/>
</a4j:commandLink>
in a JSF page.
The table is binded to a managed bean with
HtmlDataTable dataTable = new HtmlDataTable();
HtmlColumn column = new Column();
//some code to setup column name, value etcs
dataTable.getChildren().add(column);
//What do I do here to bind a commandlink with a property action
//listener to column?
My question is, how do I do this programmatically?
Thanks!
HtmlAjaxCommandLink commandLink = new HtmlAjaxCommandLink();
commandLink.addActionListener(new SetPropertyActionListener(target, value));
column.getChildren().add(commandLink);
where target and value are ValueExpression's. These can be created with:
ExpressionFactory.getInstance().createValueExpression(ctx, expression, expectedType)
And the required ELContext can be obained via FacesContext.getCurrentContext().getELContext()

Resources