populate primefaces datatable from a nativeQuery - datatable

im learning jsf enviroment, sry if this is kind of easy case for you ,
Im trying to populate a primefaces datatable from a native query , this is what i got at the moment
//My native query is defined in my entity
#NamedNativeQueries({#NamedNativeQuery(name="Tallt089.bandejaCitas",
query ="select bandeja.ep_id_tallt089 idBandeja ...)})
...
...
I call this nativeQuery this way
public List**<TablaBandejaCitas>** bandejaCitas(String cia, String agencia, String division) {
Query query = em.createNamedQuery("Tallt089.bandejaCitas");
query.setParameter(1,cia);
query.setParameter(2,agencia);
query.setParameter(3,division);
return query.getResultList();
//this works fine retrieves correctly my query
}
And use it on my managedBean
public List**<TablaBandejaCitas>** bandejaCitas(String compania,
String agencia,String division){
return agendamientoSession.bandejaCitas(compania,agencia,division);
}
then referenced this on my jsf page like this
<p:dataTable id="bandeja_citas"
value="#{AgendamientoMBean.bandejaCitas(UsuarioMBean.compania,UsuarioMBean.agencia,
UsuarioMBean.divisionPK.diDivision)}"
var="bandeja"
paginator="true" rows="15" >
<f:facet name="header">
Bandeja Citas por confirmar/Llamadas por realizar
</f:facet>
<p:column headerText="Id Bandeja" >
<h:outputText value ="#{bandeja.idBandeja}"/>
</p:column>
<p:column headerText="Cliente" sortBy="#{bandeja.cliente}"
filterBy="#{bandeja.cliente}">
<h:outputText value ="#{bandeja.cliente}"/>
</p:column>
...
...
...
</p:dataTable>
I realized that the var property needs something like mapped of the fields of the query because the warnings on the jsf page tell me that this is an unkwon property
<h:outputText value ="#{bandeja.**cliente**}"/>
I dont know how to store the query in that variable so the data can be displayed
right now i got a for input string exception like the component its reading raw data instead of formmatted list with the correct variable filled with the query fields ..
hope you can understandme
apreciatte your comments in advance :D

Ok, I solved this little problem. I did it by creating an entity class (even is not a table in the DB) with the columns that I select in the nativeQuery and then using this class as the resultClass option in the native:
resultClass=com.talleresZeusWeb.entidades.BandejaCitas.class
I was trying to make that sqlresultsetmapping annotation but don't know to use it in this case.
Hope someone finds this useful at some point, thank you for your responses #Rich

Related

Primefaces dataTable single selection validation

I can validate a p:selectOneMenu like this:
<p:selectOneMenu id="eventTimezoneDropdown"
value="#{myBean.eventTimeZone}"
required="true"
requiredMessage="The TimeZone must be specified."
effect="none">
<f:selectItems value="#{myBean.timeZoneItems}"/>
</p:selectOneMenu>
Conceptually speaking, using a p:dataTable with single row selection will achieve the same goal - it allows you to select one row using a selection attribute instead of value attribute and using value attribute instead of <f:selectItems>.
<p:dataTable id="ActivitiesTable" var="row"
value="#{myBean.rows}"
selection="#{myBean.selectedRow}"
rowKey="#{row.activityId}">
<p:column selectionMode="single"/>
...
</p:dataTable>
However I don't see any validation options (e.g. a required attribute) on the p:dataTable.
Is there a way or workaround to have a required selection validation on a p:dataTable similar to the required attribute on p:selectOneMenu?
Environment: Primefaces 5.3, JSF 2.2.8-14, Tomcat 7.0.68.
what i know in primefaces there are not this functionality in datatable, but you can play with your code,
i suggest that you can do the same event in your ManagedBean, so you can check if a row is selected or not, if yes then ok else you can create a simple message, that notifie the user that the selection of a row is required like that:
public void requiredSelect() {
if (myObject == null) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_ERROR, "Error", "My object is required!"));
}
}
Another way to work around this issue is by using a hidden input field, bound to the same value which gets updated on row select.
<p:dataTable id="ActivitiesTable" var="row"
value="#{myBean.rows}"
selection="#{myBean.selectedRow}"
rowKey="#{row.activityId}">
<p:ajax event="rowSelectRadio" update="#parent:hiddenTimezoneInput"
<p:column selectionMode="single"/>
...
</p:dataTable>
<h:inputHidden id="hiddenTimezoneInput" value="#{myBean.selectedRow}"
required="true" requiredMessage="The TimeZone must be specified."/>
This way, you can add regular validators on the inputHidden (such as required) and have it processed on form submit.

issue with ajax in primefaces "selectOneMenu"

index.xhtml
<p:selectOneMenu id="d2" value="#{mainManageBean.areaSelected}" >
<f:selectItem itemValue="" itemLabel="Select one" />
<f:selectItems value="#{mainManageBean.areaList}" var="area"
itemValue="#{area.id}" itemLabel="#{area.name}"/>
<p:ajax event="valueChange" listener="#{mainManageBean.changeAreaSelect()}" update="hi" />
</p:selectOneMenu>
When i have value set like this "mainManageBean.areaSelected" where areaSelected is entity from database
private Area areaSelected;
the ajax event dont work,
but when i change it to something like this "mainManageBean.s1menu" where this "s1menu" is just a normal String ajax event work fine.
What is the reason of that and how to fix it?
Edit
this is my buged converter:
#FacesConverter
public class areaConverter implements Converter{
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// here i have problem value is id of entity and have no idea how to get this entity form this id
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
// works fine value = Area entity
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Area) value).getId());
}
}
}
Have problem with getAsObject, i have this value as id but cant get entity from it. Normaly i would use AreaFacade.find(id) but i cant use there #EJB to get it.
First of all, your <f:selectItem itemValue> is wrong. It should represent exactly the same type as <p:selectOneMenu value>, which is thus Area. Replace itemValue="#{area.id}" by itemValue="#{area}". You indeed need a Converter for this.
As to your problem with the converter,
Have problem with getAsObject, i have this value as id but cant get entity from it. Normaly i would use AreaFacade.find(id) but i cant use there #EJB to get it.
you have 2 options:
Make it a #ManagedBean #RequestScoped instead of #FacesConverter and reference it as converter="#{areaConverter}" instead of converter="areaConverter".
Install OmniFaces >= 1.6. It adds full transparent support for #EJB inside #FacesConverter without any additional configuration or annotations.
If you go the OmniFaces path anyway, then you could also just throw away your custom converter altogether and go for its builtin SelectItems(Index)Converter without the need to create any custom converter for itemValue="#{area}".
<p:selectOneMenu ... converter="omnifaces.SelectItemsConverter">
See also:
CDI Injection into a FacesConverter
You are trying to set an Entity with value of ID, I assume Integer or String? The reason why ajax does not fire is because event="valueChange" does not occur. If you tried to submit this form without ajax you would get a sweet ClassCastException. As I mentioned in my comment and Makky in his answer, change itemValue to:
<p:selectOneMenu id="d2" value="#{mainManageBean.areaSelected}" >
<f:selectItem itemValue="#{null}" itemLabel="Select one" />
<f:selectItems value="#{mainManageBean.areaList}" var="area"
itemValue="#{area}" itemLabel="#{area.name}"/>
<p:ajax listener="#{mainManageBean.changeAreaSelect()}" update="hi" process="#this />
</p:selectOneMenu>
As per comment from Kuba
<f:selectItems value="#{mainManageBean.areaList}" var="area"
itemValue="#{area.id}" itemLabel="#{area.name}"/>
change itemValue as
<f:selectItems value="#{mainManageBean.areaList}" var="area"
itemValue="#{area}" itemLabel="#{area.name}"/>
Update:
The other thing it could be the converter. My suggestion is to use the SelectItemsConverter from Onmnifaces.
Omnifaces select item converter

In <p:dataTable> pagination not working with dynamicColumns+lazy+sorting

i'm having a lazyloading Datatable with dynamic columns generated
this is my dataTable
<p:dataTable var="iterator" id="dataTable"
value="#{MyManagedBean.lazyModel}"
paginator="true" rows="20"
lazy="true">
<p:columns value="#{MyManagedBean.columns}" var="column"
columnIndexVar="colIndex"
sortBy="#{iterator[column.property]}"
filterBy="#{iterator[column.property]}">
<f:facet name="header">
#{column.header}
</f:facet>
#{iterator[column.property]}
</p:columns>
</p:dataTable>
this works perfect without pagination. if i paginate, load() method does not give the SortField value, instead it gives me "property]"
can one help me in fixing this...
I believe this is a Primefaces bug.
I think the correct sort details should be passed to LazyDataModel.load() when paging in order to use in in your DB query.
Adding
|| (table.isLazy() && table.isPaginationRequest(context))
to the shouldDecode method in org.primefaces.component.datatable.feature.SortFeature should resolve this issue.
public boolean shouldDecode(FacesContext context, DataTable table) {
return isSortRequest(context, table) || (table.isLazy() && table.isPaginationRequest(context));
}
I've crated a new issue:
https://code.google.com/p/primefaces/issues/detail?id=7068

Primefaces - Custom Pagination/ Sorting load() issue

We are using Primefaces 3.0.RC2 in our application with seam faces and CDI. We have followed the lazy loaded data table implementation on the component showcase. Since we have a large dataset, we have overridden the load() method to fetch only pagewise results. (vs loading all records in memory at once).
The pagination works as expected, however the sorting does not. The records get sorted correctly the first time the column header is clicked. For all subsequent clicks, the load() method is called twice, sending different values for the sorting order as a result of which, the sort order remains the same on the table. It seems like both the load() calls are being made in the APPLY_REQUEST_VALUES phase.
Can anyone provide any inputs as to why this is happening and how it can be avoided. Any pointers would be highly appreciated.
Some additional info:
As stated earlier, we have overriden the load() method and have it actually query the DB to fetch sorted results pagewise (by specifying max results and order by in the query) and it works fine.
#Override
public List<ABC> load(int first, int pageSize, String sortField, SortOrder
sortOrder, Map<String, String> filters)
{
// Fetch data pagewise from the database
datasource = dao.findPagewiseSortedResults(sortField,
SortOrder.ASCENDING == sortOrder ? true : false, first, pageSize);
// Set the row count
this.setRowCount((int) dao.findTotalCount());
return datasource;
}
However, on clicking the column on the datamodel for sorting, 2 post requests are made.
Find below the xhtml code:
<p:dataTable id="dataTable" var="record"
value="#{testBean.lazyModel}" paginator="true" rows="5"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
selectionMode="single" selection="#{testBean.selectedRecord}"
sortBy="#{record.username}">
<p:ajax event="rowSelect" listener="#{testBean.onRowSelect}"
update=":form:display" oncomplete="accountDialog.show()" />
<p:ajax event="colResize" update=":form:growl"
listener="#{testBean.onResize}" />
<p:column sortBy="#{record.username}"
filterBy="#{record.username}">
<f:facet name="header">
<h:outputText value="User Name" />
</f:facet>
<h:outputText value="#{record.username}" />
</p:column>.........
</dataTable>
We have even upgraded to the latest Primefaces version (3.0.1) but it hasn't helped. Are we missing anything? Any pointers would be very helpful.
Thanks.
Since you are providing the sorting by use of the load() method, you don't have to use dataTable's native sorting tool. You need to remove the sortBy attribute from p:dataTable tag.
The component should be defined this way:
<p:dataTable id="dataTable" var="record"
value="#{testBean.lazyModel}" paginator="true" rows="5"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
selectionMode="single" selection="#{testBean.selectedRecord}" >
EDIT
This way, you'll have your column sortable exactly in the order specified by the client: you will read the SortOrder specified, with the Java code you have posted, and you will use that SortOrder consequently in your implementation of dao#findPagewiseSortedResults()

Validation for selected row in JSF h:datatable

I am having a tough time trying to find a solution to the following design related to h:dataTable.
I have certain number of rows predisplayed. The first column is only checkboxes. The rest of the columns are disabled by default. On selecting a checkbox the elements in the corresponding rows get enabled. On submit of the for the values in the enabled row have to be validated on the server side. I am able to validate for invalid inputs but am not finding a method to use required="true" conditionally. Or any other method. Could anyone please help me on this.
Thanks
Barun
I'm guessing you have a bean that looks something like this...
public class SomeBean {
boolean selected = false;
String someProperty;
...
}
If you have a controller for those beans your markup would look something like this...
<h:dataTable value="#{SomeController.someBeans}" var="someBean">
<h:column>
<f:facet name="header">Select</f:facet>
<h:selectBooleanCheckbox value="#{someBean.selected}"/>
</h:column>
<h:column>
<f:facet name="header">Input</f:facet>
<h:inputText value="#{someBean.someproperty}" required="#{someBean.selected}"/>
</h:column>
</h:dataTable>
You should have a method like:
public boolean isSelected(){
return selected;
}

Resources