get row from rich:datatable binding table - java

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...
}
}
}

Related

Primefaces Datatable submits wrong data by Celledit

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"/>

Updating a selected row in datatable in jsf

I am Creating a jsf application and I need to perform CRUD. So far I have managed to delete,create,and read but am unable to update the record.So my problem is, I want when the user click the update button a dialog box to pop with the details of the selected row and update the details. Here is My sample code.
<p:panelGrid columns="2">
<h:outputLabel value="Account Id"/>
<h:inputText value="#{accCtr.acc.accountNum}" />
<h:outputLabel value="Account Bal"/>
<h:inputText value="#{accCtr.acc.balance}"/>
<h:outputLabel />
<p:commandButton action="#{accCtr.create()}" value="Enter" update="dt"/>
</p:panelGrid>
<p:dataTable value="#{accCtr.list}" var="i" id="dt" style="width: 40%;" rowStyleClass="height" rowKey="#{accCtr.acc.accountNum}" >
<p:column>
<f:facet name="header">Account Num</f:facet>
#{i.accountNum}
</p:column>
<p:column>
<f:facet name="header">Account Balance</f:facet>
#{i.balance}
</p:column>
<p:column>
<f:facet name="header">Action</f:facet>
<p:commandButton value="Remove" styleClass="height"
action="#{accCtr.removeAccount(i)}"
/>
<p:commandButton value="Edit" styleClass="height"
onclick="pop.show()"
action="#{accCtr.edit(i)}"
>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<p:dialog widgetVar="pop" header="Account Edit">
<h:form>
<p:panelGrid columns="2">
<h:outputLabel value="Account Balance"/>
<h:inputText value="#{accCtr.acc.balance}"/>
<h:outputLabel/>
<p:commandButton value="Update"/>
</p:panelGrid>
</h:form>
</p:dialog>
can someone help me.
and my backing bean.
#ManagedBean(name="accCtr")
#SessionScoped
public class AccountController {
List<AccountTable> list=new ArrayList<>();
public AccountController() {
}
private Account_dao getDao()
{
return new Account_dao();
}
public List<AccountTable> getList() {
return getDao().findAll();
}
public void setList(List<AccountTable> list) {
this.list = list;
}
public void removeAccount(AccountTable acc) {
getDao().remove(acc);
}
public AccountTable acc=new AccountTable();
public AccountTable getAcc() {
return acc;
}
public void setAcc(AccountTable acc) {
this.acc = acc;
}
public void edit(AccountTable acc) {
setAcc(acc);
}
public String create()
{
this.acc.setUserid(10);
getDao().create(this.acc);
return "index";
}
Change your
<p:commandButton value="Edit" styleClass="height"
onclick="pop.show()"
action="#{accCtr.edit(i)}"
/>
to
<p:commandButton value="Edit" styleClass="height"
oncomplete="pop.show()"
actionListener="#{accCtr.edit(i)}"
process="#this" update=":your_dialog_form_id"
/>
A few things: In general the action atributte is used for navigation (redirect to another page for instance). Also is better to use oncomplete beacuse it gets executed when your ajax request is completed, instead of onclick that fires the action (open the dialog in your case) in the moment when you press the button, skipping validation and such things.
If your problem was, refreshing the dialog content, with the update/process (ajax) mechanism, will be updated with your current selection if you do like the second snippet.

JSF / Primefaces dataTable and sorting issue

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.

Cross Field Validation in JSF h:dataTable

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);}

Filter DataTable in Primefaces only works once

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 {
//....

Categories