Adding element to datalist - jsf

Let's say, I have such .xhtml
<h:form id="form">
<p:dataList id="carList" value="#{myBean.cars}" var="car">
#{car.brand}, #{car.year}
</p:dataList>
<p:commandButton value="Add new car" actionListener="#{myBean.addCar}" update="#form"/>
</h:form>
After pressing Add new car button, a new car object is added to myBean.cars and dataList is fully rerendered. Ajax response with changes contains not only new car, but all existing cars and new one.
Since I have more complex model and large set of data, it's very time consuming to rerender all elements. Is it possible to add new element without rerendering all existing elements of list?

Related

PrimeFaces dataTable convert values for showing in a view

I have a question based in the following situation.
I have a backing bean that create a matrix with ints, in rows, columns and cells (tablaBean). I have no problem displaying it in a jsf view. Each one of those ints, it´s an ID of differents objects. How can I do, if I want to show in my JSF view, instead of ints, some attributes of the objects?
This is my dataTable:
<p:dataTable var="rowName" value="#{tablaBean.rowNames}" rowIndexVar="rowIdx">
<p:column headerText="Alumnos:">
<h:outputText value="#{rowName}"/>
</p:column>
<p:columns var="colName" value="#{tablaBean.colNames}"
headerText="#{colName}" columnIndexVar="colIdx">
<p:panel>
<h:outputText value="#{tablaBean.data2D[rowIdx][colIdx]}"/>
</p:panel>
</p:columns>
</p:dataTable>
So for example:
tablaBean.data2D[1][1]=3
But I don´t want to show the number "3" in my view.
I want to take that number and show the Person.name of my object Person.id=3;
Hope my question is clear enough.
Create in your backing bean method returning person name:
public String getPersonNameById(int idPerson) {
return myDao.findPersonById(idPerson).getName();
}
Use it in xhtml:
<h:outputText value="#{tableBean.getPersonNameById(tablaBean.data2D[rowIdx][colIdx])}"/>

Primefaces CommadButton not update DataTable

I have the next structure in my xhtml
<p:panel>
<p:acordeonPanel>
<p:tab>
<h:form>
<table>
<tr>td><commandButton action="#{myBean.searchAnimals}"update=":form:partidos" ></td></tr>
</table>
</h:form>
</p:tab>
</p:acordeonPanel>
</p:panel>
<p:panel>
<h:form id="form">
<p:dataTable id="partidos" value="#{myBean.foundAnimals}">
</h:form>
....
The method searchAnimals() it´s OK, it returns the Animal items, but the dataTable doesn't refresh, but in the java code (managedBean) the ArrayList contains the items.
What can i do? Thanks
EDIT:
I have de h: and the p: suffix correctly (i think so), the code is part of the complete code but is the fragment that doesn't work correctly. In the first panel i have a filter controls (by category, by date, etc.) and the function of the command button is call a function that execute a query on the database, this function is well because it's filling the ArrayList with the resultset (myBean.foundAnimals) but these items doens't refresh on the view (dataTable) :(
You should use an <h:form> for both and set the render value from your commandButton to rendered=":form" to achieve rerendering the form after clicking the commandButton.

p:selectOneMenu get just first value from list primefaces JSF

i have p:selectOneMenu, all values are viewed correctly but just first on my list can be chosen for example, on my list i have e-mail addresses, i can choose everyone but mail is sending just on first of them on list. My JSF code:
<p:dataTable value="#{additionalOrdersBean.additionalOrdersList}"
var="additionalOrders" rowIndexVar="lp" id="myTable" editable="true>
<p:column>
<p:selectOneMenu id="recipient" value="#{additionalOrdersBean.mailTo}" converter="#{mailConverter}" required="true" requiredMessage="#{loc['fieldRequired']}">
<f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail1}" itemValue="#{mail.mail1}" />
<f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail2}" itemValue="#{mail.mail2}" />
<f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail3}" itemValue="#{mail.mail3}" />
</p:selectOneMenu>
<h:message for="recipient" style="color:red"/>
<h:commandButton value="#{loc['send']}" action="#{additionalOrdersBean.sendProtocol()}" onclick="sendProtocolDialog.hide()"/>
</p:column>
</p:dataTable>
My bean:
private String mail1;
private String mail2;
private String mail3;
public List<Building> getBuildingList2() {
buildingList2 = getBldRepo().findByLocationId(lid);
return buildingList2;
}
Can anyone know how to fix it? I wont to send e-mail on choosen address not just on first on my list. Thanks
You seem to expect that only the current row is submitted when you press the command button in the row. This is untrue. The command button submits the entire form. In your particular case, the form is wrapping the whole table and thus the dropdown in every single row is submitted.
However, the value attribute of all those dropdowns are bound to one and same bean property instead of to the currently iterated row.
The consequence is, for every single row, the currently selected value is set on the bean property, hereby everytime overriding the value set by the previous row until you end up with the selected value of the last row.
You've here basically a design mistake and a fundamental misunderstanding of how basic HTML forms work. You basically need to move the form to inside the table cell in order to submit only the data contained in the same cell to the server.
<p:dataTable ...>
<p:column>
<h:form>
...
</h:form>
</p:column>
</p:dataTable>
If that is design technically not an option (for example, because you've inputs in another cells of the same row, or outside the table which also need to be sent), then you'd need to bind the value attribute to the currently iterated row instead and pass exactly that row to the command button's action method:
<p:dataTable value="#{additionalOrdersBean.additionalOrdersList}" var="additionalOrders" ...>
<p:column>
<p:selectOneMenu value="#{additionalOrders.mailTo}" ...>
...
</p:selectOneMenu>
...
<h:commandButton value="#{loc['send']}" action="#{additionalOrdersBean.sendProtocol(additionalOrders)}" ... />
</p:column>
</p:dataTable>
It's by the way not self-documenting and quite confusing to have a plural in the var name. Wouldn't you rather call it additionalOrder? Or is the javabean/entity class representing a single additional order really named AdditionalOrders?
Unrelated to the concrete problem: doing business logic in getter methods is killing your application. Just don't do that. See also Why JSF calls getters multiple times.

Primefaces dataTable multiple selection same object

I'm having a problem with the dataTable multiple selection with checkbox (like the second one: http://primefaces.org/showcase/ui/datatableRowSelectionRadioCheckbox.jsf).
When I try to execute a method in my backingBean, the selected items always comes with the right size, but, with the same object.
Example: I select in my dataTable three Messages: Message 1, Message 2 and Message 3. When I execute my method in the JSF page my selected items comes like this:
Messages[0] = Message 1
Messages[1] = Message 1
Messages[2] = Message 1
Here is my JSF Page:
<p:dataTable id="mensagensLidas" var="msg" value="#{mensagensBean.msgGrupoModel}"
paginator="true" rows="10" selection="#{mensagensBean.selectedMsgsGrupo}">
<p:column selectionMode="multiple" style="width:2%"/>
<p:column headerText="Titulo:" style="width:49%">
#{msg.titulo}
</p:column>
<f:facet name="footer">
<p:commandButton id="multiViewButton" value="#{msgs.delete}" icon="ui-icon-trash" actionListener="#{mensagensBean.excluirMsgsGrupo}" update=":tabMain" ajax="true"/>
</f:facet>
</p:dataTable>
Your above code is working fine for me except that I'm using a rowKey.
Try using rowKey attribute in p:dataTable
<p:dataTable id="mensagensLidas" var="msg" value="#{mensagensBean.msgGrupoModel}"
paginator="true" rows="10" selection="#{mensagensBean.selectedMsgsGrupo}"
rowKey="#{msg.titulo}">
....
</p:dataTable>
Using rowKey is must and best practice when you have selection in Datables, it helps to map the selected <tr> to the POJOs that you're filling up with.
Usually its even better if your rowKey is unique propety, you can even put an integer variable in your #{msg} POJO as best practice.
I discovered the problem. My DataModel was with the getRowData returning always the same object. I was doing a wrong comparison. Thank you all!

How to get row index in p:orderList?

I have a simple implementation of p:orderList in which I display array list of task objects, namely task name and commandButton which displays more details about task:
<p:orderList value="#{taskBean.tasks}" var="t" controlsLocation="none"
itemValue="#{t}" id="tasks"/>
<p:column>
<h:outputLabel value="#{t.name}"/>
</p:column>
<p:column><h:form>
<p:commandButton title="Details" oncomplete="#{taskBean.details(t.id)}"
icon="ui-icon-document-b"/>
</h:form></p:column>
</p:orderList>
The button calls bean method which finds task in array list whit task id and displays it.
Now for some reason, in all rows in orderList I end up whit last (t.id) as attribute for all buttons, so they all display the last task.
Any idea what should I do?
And my second question is how to add button which saves current order of the array list of tasks?

Resources