I am using PrimeFaces 2.2, with JSF 2.0.3.
I have an xhtml view that contains the following datatable:
<p:dataTable id="fooTable"
widgetVar="fooTable"
rowKey="#{foo.id}"
var="foo"
value="#{fooQueue.foos}"
styleClass="table"
selection="#{fooQueue.selectedfoo}"
filteredValue="#{fooQueue.filteredfoos}"
paginatorPosition="bottom"
paginatorAlwaysVisible="true"
selectionMode="single"
rowEditListener="#{fooQueue.save}"
paginator="true"
rows="10"
rowIndexVar="#{foo.id}"
emptyMessage="No foos found with given criteria"
rowStyleClass="#{foo.status == const.submitted ? 'gray' : null}"
onRowSelectUpdate=":form:deleteValidation">
<p:column id="mothersName" filterBy="#{foo.header1}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Mother's Name" styleClass="tableHeader2" />
</f:facet>
<p:commandLink action="#{fooQueue.next(foo)}"
ajax="false"
disabled="#{foo.status == const.submitted || foo.id == 0}">
<f:setPropertyActionListener value="#{foo}" target="#{fooQueue.selectedfoo}" />
<h:outputText value="#{foo.header1}" styleClass="tableData" />
</p:commandLink>
</p:column>
<p:column sortBy="#{foo.header4}" >
<f:facet name="header">
<h:outputText value="DOB" styleClass="tableHeader2" style="width: 400px" />
</f:facet>
<h:outputText value="#{foo.header4}" styleClass="#{(foo.overSevenDays and foo.status != const.submitted and foo.id != 0)?'tableDataRed':'tableData'}" />
</p:column></p:dataTable>
.. with the following backing bean:
#ViewScoped
#ManagedBean
public class FooQueue extends BaseViewBean {
private List foos;
private Foo selectedFoo;
private List filterdFoos;
public FooQueue() {
logger.debug("Creating new FooRegQueue");
retrieveFooRecords();
}
private void retrieveFooRecords(){
foos = new ArrayList();
foos.addAll(fooService.getAllFoos());
}
public String next(Foo clickedFoo) {
System.out.println(clickedFoo.getId());
return "";
}
public Collection getFoos() {
return foos;
}
public Foo getSelectedFoo() {
return selectedFoo;
}
public void setSelectedFoo(Foo foo) {
if (foo != null) {
this.selectedFoo = foo;
}
}
public void setFilterdFoos(List filterdFoos) {
this.filterdFoos = filterdFoos;
}
public List getFilterdFoos() {
return filterdFoos;
}
}
Note the "commandLink" on the mother's name column, and the "sortBy" on the DOB column.
I've encountered a strange issue, which seems to be limited to IE, where if I sort the data by DOB, then paginate to the last page and click the commandLink of the last record in the table, it fires two action events. The first event correctly reports that I clicked on the last record in the sorted table. But the second invocation of the next() method is for the last record in the UNsorted table.
Can anyone identify anything wrong with my xhtml, or backing bean? Is this a known PrimeFaces issue? A known IE issue?
I am testing with IE 8.
I solved it. I simply had to change this:
<p:commandLink action="#{fooQueue.next(foo)}"
ajax="false"
disabled="#{foo.status == const.submitted || foo.id == 0}">
<f:setPropertyActionListener value="#{foo}" target="#{fooQueue.selectedfoo}" />
<h:outputText value="#{foo.header1}" styleClass="tableData" />
</p:commandLink>
to this:
<p:commandLink action="#{fooQueue.next(foo)}"
ajax="true"
disabled="#{foo.status == const.submitted || foo.id == 0}">
<f:setPropertyActionListener value="#{foo}" target="#{fooQueue.selectedfoo}" />
<h:outputText value="#{foo.header1}" styleClass="tableData" />
</p:commandLink>
Note the ajax="true". Because it was previously set to ajax="false", it was instantiating a new instance of my backing bean, and the row that was selected in the default sort order was being loaded. Now it does not instantiate a new instance, and I load the actual record I clicked on.
Related
I'm using Primefaces datatable with PF8.
Data is coming from ListDatamodel. I want to use Cell editing and implemented it exactly like shown in Primefaces showcase. After 3 or 4 inputs of new values, in the approriate bean the value gets updated, but with the old value. After a refresh of the page, the behaviour is normal again.
Here is the xhtml:
<p:dataTable style= "transform: scale(1); transform-origin: 0 0;" id="costingOverviewData" value="#{costingOverviewBean.model}" var="item"
editable="true" editMode="cell" selectionMode="single" disabledSelection="true"
rowStyleClass="#{(item.konto % 1000) eq 999 ? 'total':null}"
rowKey="#{item.ID}"
>
<p:ajax event="cellEdit" listener="#{costingOverviewBean.onCellEdit}" process="#this" />
<p:column rendered = "#{costingOverviewBean.showVorkalk ne false}" style="min-width: 20px;width:20px; max-width: 20px;">
<h:outputText value="#{item.konto}" />
</p:column>
<p:column style="min-width: 200px;width:200px; max-width: 200px;" >
<h:outputText value="#{item.beschreibung}" />
</p:column>
<p:column rendered = "#{costingOverviewBean.showVorkalk eq true}" width="75" headerText="#{res['COV_VorkalkQuantity']}" style="text-align:right">
<p:cellEditor>
<f:facet name="output">
<p:outputPanel style="#{item.menge_Vorkalk ne null ? 'border-style:solid;border-color:grey;border-width:0.5pt':'border-style:none'}">
<p:outputLabel value="#{item.menge_Vorkalk}">
<f:convertNumber integerOnly="true"></f:convertNumber>
</p:outputLabel>
</p:outputPanel>
</f:facet>
<f:facet name="input">
<p:inputNumber rendered="#{item.menge_Vorkalk ne null ? 'true':'false'}" id="menge_Vorkalk_Input" value="#{item.menge_Vorkalk}" style="width:96%">
</p:inputNumber>
</f:facet>
</p:cellEditor>
...
And here the bean:
public DataModel <KontenrahmenIstkosten> getModel() throws IOException {
if(model == null){
load_Strukturplan();
}
if (model == null){
model = new ListDataModel<KontenrahmenIstkosten>(list);
converter = new NumberConverter();
}
return this.model;
}
...
public void onCellEdit(CellEditEvent event) throws IOException {
System.out.println(event.getNewValue());
System.out.println(event.getRowKey());
init();
//PrimeFaces.current().ajax().update("form:pnlOfferEdit");
}
}
In extreme cases, I got also wrong data in fields which I never touched, and the whole table is messed up.
I'm struggling for 3 days now. Any help is appreciated!!
Edit: during value editing, getmodel() is called several times before calling of onCellEdit().
Is this normal behaviour? From my feeling, I face here a timing issue: Sometimes it is luckily working, sometimes not.
Did you try it without the process="#this"?
This only submits the values from the component.
<p:ajax event="cellEdit" listener="#{costingOverviewBean.onCellEdit}"/>
Or you can try adding the id instead of #this
<p:ajax event="cellEdit" listener="#{costingOverviewBean.onCellEdit}" process="costingOverviewData"/>
in my xhtml i define a inputText variable from which i want to set a specific value to a specific field in my List. Every time i click confirm and debug my code the value is returned as "" (that i set in my init function). I have also tried hardcoding my inputText value to be set to dashboardFilterDialogBean.dashboardObject.texts[0] as in the only item in the list i define but still no result. I get 0 exceptions in my console
Xhtml
<p:dialog id="dashboardFilterDialog">
<h:form id="dashboard_filter_dialog_form">
<ui:repeat value="#{dashboardFilterDialogBean.dashboardObject.texts}" varStatus="loop">
<p:row>
<p:column>
<h:outputText value="Text" />
</p:column>
<p:column>
<p:inputText value="#{dashboardFilterDialogBean.dashboardObject.texts[loop.index]}" />
</p:column>
</p:row>
</ui:repeat>
</h:form>
<f:facet name="footer">
<h:form id="submit_dashboards_dialog_form">
<p:commandButton id="confirm_button" actionListener="#{dashboardFilterDialogBean.confirm()}" />
</h:form>
</f:facet>
</p:dialog>
Bean
public class DashboardFilterDialogBean {
private DashboardObject dashboardObject;
#PostConstruct
public void init() {
dashboardObject.getTexts().add("");
}
public void confirm() {
for (String txtValue : getDashboardObject().getTexts()) {
if (!txtValue.equals("")) {
...;
}
}
}
public DashboardObject getDashboardObject() {
return dashboardObject;
}
public void setDashboardObject(DashboardObject dashboardObject) {
this.dashboardObject = dashboardObject;
}
}
Object
public class DashboardObject {
private List<String> texts;
public DashboardObject() {
texts = new ArrayList<String>();
}
public List<String> getTexts() {
return texts;
}
public void setTexts(List<String> texts) {
this.texts = texts;
}
}
I've fixed my issue by adding <p:ajax event="blur" process="#this" /> into my inputText so it saves the value before i click confirm. So the end code looks like this:
<p:inputText value="#{dashboardFilterDialogBean.dashboardObject.texts[loop.index]}" />
<p:ajax event="blur" process="#this" />
</p:inputText>
I have a XHTML page in which there are four textboxes
<h:column >
<f:facet name="header">
<h:outputText value="Start Date" />
</f:facet>
<h:inputText id="startDate" value="#{sampleVO.startDate}" />
</h:column>
<h:column >
<f:facet name="header">
<h:outputText value="End Date" />
</f:facet>
<h:inputText id="endDate" value="#{sampleVO.endDate}" />
</h:column>
<h:column >
<f:facet name="header">
<h:outputText value="Start Date" />
</f:facet>
<h:inputText id="startDate1" value="#{sampleVO.startDate}" />
</h:column>
<h:column >
<f:facet name="header">
<h:outputText value="End Date" />
</f:facet>
<h:inputText id="endDate1" value="#{sampleVO.endDate}" />
</h:column>
I need to put a validation on Start Date and End Date. If user enters some Start and End date in id="startDate" & id="endDate" lets say Start Date: "01/01/2012" (1jan) and End Date: 01/31/2012 and if user enters some dates on id="startDate1" and id="endDate1" id="startDate1" should always be greater thn id="endDate" i.e date Ranges should not Overlap
public class SampleServiceimpl implements SampleService {
private List<SampleVO> listOfSample;
//this function gets called when clicked on Submit button on XHTML page
public Void submit() {
// how can i call datesOverLaps function to check entered
// start date and End date not overlapping, Also how to
// display the error message on XHTML page using FacingContext
}
public boolean datesOverlaps(List<SampleVO> sampleVO) {
final Date early = sampleVO.getStartDate();
final Date late = sampleVO.getEndDate();
for(SampleVO existing : sampleVO) {
if(!(early.isAfter(existing.getEnd())) ||
(late.isBefore(existing.getStart()))){
return true;
}
}
return false;
}
}
Not sure if the above boolean function is current and would work in the scenario.
Any help would be appreciated.
I spend 6 hours on this. But i solved it. My english is bad.
Add binding atribute on dataTable, pointing to UIDData field in backingbean (Bind table)
<h:dataTable value="#{narocilo.podatki}" id="tabela" var="podatek" border="0" bgcolor="#F6FAF0" style="width:100%;" cellspacing="0" cellpadding="2" headerClass="header" rowClasses="#{narocilo.rowClasses}" columnClasses="align_left,align_right,align_center,align_right,align_right,align_center_konec" **binding="#{narocilo.podatkiData}"**>
Before the end of form ad
<h:inputHidden id="validator" **validator="#{narocilo.validateKolicinaCena}"** value="morabiti"/>
validator method in backing bean
public void validateKolicinaCena(FacesContext aContext,UIComponent aComponent,Object aValue) {
int shrani_index = fPodatkiData.getRowIndex();
UIComponent column_kol = fPodatkiData.getChildren().get(2);
UIComponent column_cen = fPodatkiData.getChildren().get(5);
for(int i=0; i<fPodatkiData.getRowCount(); i++) {
fPodatkiData.setRowIndex(i);
UIInput kolicina_input = (UIInput) column_kol.findComponent("kolicina");
UIInput cena_input = (UIInput) column_cen.findComponent("cena");
Object kolicina = kolicina_input.getLocalValue();
Object cena = cena_input.getLocalValue();
if(kolicina == null && cena != null) {
kolicina_input.setValid(false);
FacesMessage sporocilo = Sporocila.getMessage("si.alkimisticus.bitea.error", "javax.faces.component.UIInput.REQUIRED", null);
sporocilo.setSeverity(FacesMessage.SEVERITY_ERROR);
aContext.addMessage(kolicina_input.getClientId(aContext), sporocilo);
} else if(kolicina != null && cena == null) {
cena_input.setValid(false);
FacesMessage sporocilo = Sporocila.getMessage("si.alkimisticus.bitea.error", "javax.faces.component.UIInput.REQUIRED", null);
sporocilo.setSeverity(FacesMessage.SEVERITY_ERROR);
aContext.addMessage(cena_input.getClientId(aContext), sporocilo);
} else {
kolicina_input.setValid(true);
cena_input.setValid(true);
}
}
fPodatkiData.setRowIndex(shrani_index);}
I am using java 6 jsf 1.2 and richfaces 3.3.3
When I call the function getRowData on the Binded UIDataTable
public void priorityChanged(ValueChangeEvent event) {
Task currentTask = (Task) table.getRowData();
with
<h:selectOneMenu id="id182_#{rkv}" value="#{dataItem.priority}"
valueChangeListener="#{customerAdminHandler.priorityChanged}"
onchange="submit()">
<f:selectItems value="#{customerAdminHandler.priorityTypes}" />
</h:selectOneMenu>
i get an exception on the table.getRowData();
java.lang.IllegalArgumentException
at javax.faces.model.ListDataModel.getRowData(ListDataModel.java:150)
at org.ajax4jsf.model.SequenceDataModel.getRowData(SequenceDataModel.java:147)
at org.ajax4jsf.component.UIDataAdaptorBase.getRowData(UIDataAdaptorBase.java:257)
I bypassed the problem by using
<f:setPropertyActionListener value="#{dataItem}"
target="#{customerProductsHandler.currentApp}" />
instead of a binding table.
the same code worked for me on a clean environment so i guess there is some sort of jar problem.
anyway , for future reference I found the following information usefull for using a binding table
Richfaces 3.3 uses:
org.richfaces.component.html.HtmlDataTable
Richfaces 4 uses:
org.richfaces.component.UIDataTable
jsf1.2 uses:
javax.faces.component.html.HtmlDataTable;
jsf 2 uses:
import javax.faces.model.DataModel;
Have you binded your rich:dataTable to a component attribute of your managed bean? Plus, the type of the attribute must be org.richfaces.component.html.HtmlDataTable, at least this is how we achieved to select one row of the datatable (using the example code of #BalusC here).
The jsp code:
<script type="text/javascript">
function dataTableSelectOneRadio(radio) {
var id = radio.name.substring(radio.name.lastIndexOf(':'));
var el = radio.form.elements;
for (var i = 0; i < el.length; i++) {
if(el[i].name != undefined) {
if (el[i].name.substring(el[i].name.lastIndexOf(':')) == id) {
el[i].checked = false;
}
}
}
radio.checked = true;
}
</script>
<!-- some html/jsp code -->
<rich:dataTable id="dtDocCartera" style="width:100%"
binding="#{busquedaDocCartera.hdtCredito}"
value="#{busquedaDocCartera.lstCredito}" var="credito" rows="15">
<rich:column>
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
<h:selectOneRadio onclick="dataTableSelectOneRadio(this)"
valueChangeListener="#{busquedaDocCartera.setSelectedItem}">
<f:selectItem itemValue="null"/>
</h:selectOneRadio>
</rich:column>
<rich:column style="text-align:center">
<f:facet name="header">
<h:outputText value="Some Data" />
</f:facet>
<h:outputText value="#{credito.data}" />
</rich:column>
</rich:dataTable>
And this is our managed bean:
#KeepAlive(ajaxOnly=false)
public class PBusquedaDocCartera {
private HtmlDataTable hdtCredito;
private List<ECredito> lstCredito;
//This will be the selected data
private ECredito credito;
//getters and setters for attributes...
public void setSelectedItem(ValueChangeEvent event) {
try {
credito = (ECredito)hdtCredito.getRowData();
} catch (Exception objEx) {
//logging errors...
}
}
}
I'm trying to filter a dataTable using Primefaces much like this example. (In a web browser) I type the text I want to filter by, it works once but when I remove the text I've written the result stays the same when it should go back to it's original state.
So it works once and then won't respond. (I can remove or re-type the filter text I've written but it does not affect the table anymore)
Sorry about the weird attribute names in the code, bear with me. :)
xhtml-page:
<h:form>
<p:dataTable var="aggr" value="#{aggregationManagedBean.logiskAdressatModel}"
widgetVar="aggrTable"
emptyMessage="No aggr found with given criteria">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Filter:" />
<p:inputText id="globalFilter" onkeyup="aggrTable.filter()" />
</p:outputPanel>
</f:facet>
<p:column filterBy="#{aggr.name}">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{aggr.name}" />
</p:column>
</p:dataTable>
</h:form>
backing bean:
#ManagedBean
#SessionScoped
public class AggregationManagedBean {
private List<LogiskAdressat> logiskaAdressater;
private DataModel<LogiskAdressat> logiskAdressatModel;
public AggregationManagedBean() {
logiskaAdressater = getLogiskaAdressater();
logiskAdressatModel = new ListDataModel<LogiskAdressat>(logiskaAdressater);
}
private static List<LogiskAdressat> getLogiskaAdressater(){
List<LogiskAdressat> logiskaAdressater = new ArrayList<LogiskAdressat>();
logiskaAdressater.add(new LogiskAdressat("01 addr_id 01", "Joe"));
logiskaAdressater.add(new LogiskAdressat("02 addr_id 02", "John"));
logiskaAdressater.add(new LogiskAdressat("03 addr_id 03", "Jake"));
return logiskaAdressater;
}
public DataModel<LogiskAdressat> getLogiskAdressatModel() {
return logiskAdressatModel;
}
public void setLogiskAdressatModel(DataModel<LogiskAdressat> adressatModel) {
this.setLogiskAdressatModel(adressatModel);
}
}
Is LogiskAdressat Serializable?
If not, then try making it Serializable -
public class LogiskAdressat implements Serializable {
//....