How Datatable holds my edited values - java

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

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

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

jsf table repeats itself

another weird jsf problem. my code looks something like this:
Java Bean:
class Bean {
private ArrayList<OutageTableHeader> outageTableHeaderData;
public ArrayList<OutageTableHeader> getOutageTableHeaderData() {
return outageTableHeaderData;
}
public void setOutageTableHeaderData(ArrayList<OutageTableHeader> value) {
this.outageTableHeaderData = value;
}
public List<OutageRowData> getOutageDataForTable() {
createOutageTableHeader(); // method which populates outageTableHeaderData with data
...
return(); // returns a list of OutageRowData objects, each for every row
}
}
my xhtml file:
...
<h:form>
<rich:dataTable id="outageOverviewTable"
value="#{mapOverviewManager.getOutageDataForTable()}" var="outageRow"
rendered="#{mapOverviewManager.outageDataForTable.size() > 0}"
headerClass="overviewHeader" cellpadding="0" cellspacing="0"
rowClasses="areaRowOdd, areaRowEven" style="width: auto">
<f:facet name="header">
<rich:columnGroup style="background: #ffffff">
<rich:column>
<h:outputText>TEST</h:outputText>
</rich:column>
<c:forEach items="#{mapOverviewManager.outageTableHeaderData}"
var="outHeader">
<rich:column colspan="#{outHeader.colSpan}">
<h:outputText value="#{outHeader.displayName}" />
</rich:column>
</c:forEach>
</rich:columnGroup>
</f:facet>
</rich:dataTable>
</h:form>
mapOverviewManager is my bean. Now I'm confronted with two problems
1) when I initally load the page, only "TEST" appears (the entry that is hard coded)
2) every time I press F5 to reload the page, the table expands itself. That is, exactly 32 entries (always the same) are appended to the end of the table and I don't know why?
This is rather strange because on the same page is a similar table, from which I basically copied the whole structure. Any suggestions?
You did not provide any meaningful data (not the scope of the bean, not even the code outageDataForTable property, not to mention the code that fetches data). But let me play a psychic for a second: the bean is session (or view) scoped, and you fetch the data in your getter?

h:dataTable binding => duplicate ID

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.

Categories