h:dataTable binding => duplicate ID - java

I have a problem using HtmlDataTable for viewing data from database.
When I create component, the table has sometimes (not always) twice number of columns.
It is shown correctly and after several refreshes (without move in dtb or something) there is for example 6 columns instead of 3 and application (sometimes) become unstable.
Since this time I can't work with table because it reports "duplicate Id for a component"..
Simple example (source: http://balusc.blogspot.com/2006/06/using-datatables.html):
<h:form id="bde">
<h:dataTable id="tbl"
binding="#{myBDE.dataTable}"
value="#{myBDE.dataList}"
var="bdeItem">
<h:column>
<f:facet name="header">
<h:outputText value="S" />
</f:facet>
<h:outputText value="#{bdeItem.s}" rendered="#{!myBDE.editModeRow}"/>
<h:inputText value="#{bdeItem.s}" rendered="#{myBDE.editModeRow}" required="true" size="3"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{bdeItem.id}"/>
</h:column>
</h:dataTable>
</h:form>
And java.class
protected HtmlDataTable dataTable;
public void setDataTable(HtmlDataTable dataTable)
{
this.dataTable = dataTable;
}
public HtmlDataTable getDataTable()
{
if (dataTable == null)
{
dataTable = new HtmlDataTable();
dataTable.setRows(DEFAULT_TABLE_ROWS);
}
return dataTable;
}
And the Error message:
javax.servlet.ServletException: Component ID j_idt92:bde:tbl:j_idt129 has already been found in the view.
javax.faces.webapp.FacesServlet.service(FacesServlet.java:422)
root cause
java.lang.IllegalStateException: Component ID j_idt92:bde2:tbl:j_idt129 has already been found in the view.
com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)
com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)
com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)
com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)
com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)
com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)
com.sun.faces.application.view.StateManagementStrategyImpl.saveView(StateManagementStrategyImpl.java:144)
com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:133)
com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:418)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)
Followed by tree of components.
I thing there's nothing duplicated in code, but dataTable create a new columns and after that it's really duplicated
I have two working similar modules, and the third doesn´t work.
Have you ever met this kind of problem?
Thanks for advice

This can happen if the bean is session scoped instead of request scoped and you're sharing this bean among multiple views. Best is to keep the bean to which the component is been bound in the request scope.
As an alternative, you can also use DataModel as value instead of binding the table to HtmlDataTable if the functional requirement is to get the currently selected row.

Related

primefaces filterby function gives no results

I am trying to filter a datatable by adding the following code:
<p:dataTable value="#{hoofdschermBean.onderzoekers}" widgetVar="onderzoekerTable" var="onderzoekeritem" rendered="#{not empty hoofdschermBean.onderzoekers}" rowStyleClass="tablerow" draggableColumns="true">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Zoeken:" />
<p:inputText id="globalFilter" onkeyup="PF('onderzoekerTable').filter()" style="width:150px" placeholder="Enter keyword"/>
</p:outputPanel>
</f:facet>
However it does not filter when I fill something in this textbox, it says no records found.
If I add filterBy on a column, only than this textbox can filter on the column variable. What am I doing wrong here?
(P.S. I do not want to have filter functions on every separate column, that is why I wanted this facet only!)
#Edit 14:32 27-11-2014
I have also tried to use
filteredValue="#{hoofdschermBean.gefilterdeOnderzoekers}"
and to use ViewScoped and SessionScoped.
Do you have a List<> field in your managedBean so the filtered values can be saved somewhere? Also, you'd need to reference this value with a filteredValue="#{hoofdschermBean.filtered...}"attribute in your dataTable-Tag.
(Like in the PrimeFaces ShowCase, where they have a List<Car> filteredCars; in their managedBean)
Also, it might be helpful to check the scope of your ManagedBean

JSF 1.1 Datatable CRUD operation

We have a old application running with JSF 1.1, cannot upgrade due to client specification.
I would like to know is it possible to have a datatable with JSF 1.1 and upon clicking a button or link in datatable row open a dialog popup and do CRUD operation?
Thanks
Edit 1
I guess Apache Trinidad supports JSF 1.1. Can I do CRUD operation with Trinidad?
I think using Richfaces 3.1.6 (JSF 1.1 compatible) with the great A4J, will help you doing so:
<h:form id="myForm">
<rich:dataTable width="100%" style="border:none;margin-left:15px;" id="tableId" columnClasses="colClass"
value="#{managedBean.someList}" var="someVar">
<h:column> some content for this column </h:column>
<h:column>
<a4j:commandLink styleClass="linkClass" value="Delete" reRender="myForm:myModal" ajaxSingle="true" oncomplete="#{rich:component('myForm:myModal')}.show()" actionListener="#{managedBean.someMethodToUpdateDTO}">
<a4j:actionparam value="#{someVar.idForExample}" name="someName" assignTo="#{managedBean.someDTOObjectToBeUpdated.id}"/>
</a4j:commandLink>
</h:column>
</rich:dataTable>
<rich:modalPanel id="panel" width="350" height="100">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Are you really, really sure to delete this one!!! #{managedBean.someDTOObjectToBeUpdated.name}"></h:outputText>
</h:panelGroup>
</f:facet>
<a4j:commandButton styleClass="btnClass" value="Oui" ajaxSingle="true" oncomplete="#{rich:component('myForm:myModal')}.hide()" reRedner="myForm:tableId" action="#{managedBean.deleteIt}">
</rich:modalPanel>
</h:form>
someMethodToUpdateDTO is a method, in your managed bean that looks like this:
public void someMethodToUpdateDTO(ActionEvent event){
//In this method I just load the object from somewhere else
someDTOObjectToBeUpdated = someDAO.getObject(someDTOObjectToBeUpdated.getId());
//someDTOObjectToBeUpdated is an attribute of your managed bean, of course with its getter and setter
}
Hope this helps,
Cheers

JSF datatable populate rows based on selection

I have two datatables in one jsf page and both are having two different managed beans.
//master table
<p:dataTable id="dataTable" var="req" lazy="true"
value="#{emp.lazyModel}" paginator="true" rows="10"
selection="#{emp.selectedRequest}">
<p:ajax event="rowSelectRadio" listener="#{emp.onRowSelect}" />
<p:column selectionMode=">
<h:outputText value="#{req.empNo}" />
</p:column>
// detail table
<p:dataTable id="Det" var="det" lazy="true"
value="#{dept.lazyModel}" paginator="true" rows="1">
<p:column>
<f:facet name="header">
<h:outputText value="DeptNo" />
</f:facet>
<h:outputText value="#{det.deptNo}" />
</p:column>
Managed beans respectively
// Master table managed Bean
#Named("emp")
#ViewAccessScoped
public class EmployeeManagedBean implements Serializable {
#PostConstruct
public void init() {
initTable();
}
// Detail table managed Bean
#Named("dept")
#ViewAccessScoped
public class DepartmentManagedBean implements Serializable {
#PostConstruct
public void init() {
initTable();
}
initTable() is a method which populates LazyModel for both managed beans
When I select a row in master datatable, I am able to get selected row value in managed bean for first datatable which is EmployeeManagedBean
My question is what is the best approach to populate the second datatable by passing the selected row value of first datatable to second managed bean and thus populate the second datatable? The triggering point to display values in second datable should be based on the selection of a row in first datatable.
Any help is highly appreciable.
Thanks
I am new with this all, but I try doing like this:
pass selected row to second bean (DepartmentManagedBean)
took departments according to selected row
update second datatable, using p:ajax attribute update

How Datatable holds my edited values

<h:dataTable value="#{studentBean2.studentList}" var="student">
<h:column>
<f:facet name="header">
<h:outputText value="STUDENT-ID" />
</f:facet>
<h:outputText value="#{student.studentId}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="STUDENT-NAME" />
</f:facet>
<h:inputText value="#{student.studentName}" />
</h:column>
.........
.........
</h:dataTable>
<h:commandButton type="submit" action="#{studentBean2.action}" value="ENTER" />
As from the above code, datatable values can be edited in <h:inputText> field and submitted. Those edited values are seen in action() method of bean StudentBean2.
As I followed the log, it showed that when I submit the page in the phase "Apply Request Values" the getStudentList() method is called. In this method I do the JDBC call to fetch students from the Database and set the newly fetched studentlist.
But in the "Invoke Application" phase, in method action() I get the edited data in the list which I have submitted. How exactly does this happen?
JSF has set them for you during the update model values phase. During this phase, the processUpdates() method of every component will be invoked. In case of the <h:dataTable> it's the UIData#processUpdates(). For every row it will then invoke the same method of the input component, which is in your case UIInput#processUpdates().
Basically:
get data model of UIData; // studentList = studentBean2.getStudentList()
for (every row of data model) {
get the current row item by index; // student = studentList.get(index)
for (every child UIInput component of UIData) {
set its value; // student.setStudentName(value)
}
}
Unrelated to the concrete problem, doing the JDBC call inside the getter method is a bad idea. The getter method will be called more than once during bean's life, so the JDBC call will be unnecessarily made too many times. You should make the JDBC call in bean's (post)constructor instead. See also Why JSF calls getters multiple times.

Richfaces 4 Datatable with onclick Event on row

I have a simple Richfaces 4 <rich:dataTable> with some <rich:column>s.
Now I want if I press on one row, that below the table the ID of the row should be displayed.
Here is what I did so far:
<rich:dataTable value="#{placeholder_control.lichtList}" var="licht" width="100%" id="lichtListe" columns="2">
<rich:column>
<f:facet name="header">
<h:outputText value="Beschreibung" />
</f:facet>
<h:outputText value="#{licht['beschreibung'].stringValue}" width="20" />
<a4j:ajax immediate="true" event="onclick" render="testingID" listener="#{placeholder_control.selectActiveLight}">
<f:attribute name="rowKey" value="#{licht['id'].stringValue}" />
</a4j:ajax>
</rich:column>
...
...
<h:outputText value="This is the id : #{placeholder_control.selectedLight}" id="testingID"></h:outputText>
The managed bean placeholder_control looks like this
#ManagedBean (name="placeholder_control")
#SessionScoped
public class ControlPlaceholder {
public void selectActiveLight(ActionEvent evt) {
String selectedRow = (String) evt.getComponent().getAttributes().get("rowKey");
System.out.println("Selected Light : " + selectedRow);
setSelectedLight(selectedRow);
}
Everything will be rendered correctly, but if I click on the row (on this column), nothing happens. I also tried to put a non existing method (on purpose) to the listener. I hoped that I get an error message but nothing happend.
If I look at the HTML source code, there is nothing with onclick at that <td> element.
Anyone has an idea?
hi friend take a look to rich:extended datatable, i used it to do a task that meet your requirements.
here is the showcase for richfaces 4 and explains the use of extended datatable: http://richfaces-showcase.appspot.com/richfaces/component-sample.jsf?demo=extendedDataTable&sample=exTableSelection&skin=blueSky
cheers

Categories