原文:http://technology.amis.nl/2006/07/27/creating-a-dynamic-ajax-column-footer-summary-in-a-table-component-using-adf-faces/
为了防止打不开,复制原文如下:
Creating a dynamic (AJAX) Column Footer Summary in a Table Component using ADF Faces
One fairly common requirement for web applications is the display of Summary fields with calculated values. An obvious example is a table of multiple records with column-summaries appearing underneath the table. Using ADF Faces technology, it is fairly simple to quickly develop an application that presents a multi-record layout based on data retrieved from a database. In this article we will see how we can add a summary column to the columns in such a table layout – and to make those summaries automatically updating when a value for one of the records in the table is changed in the specific column.
Creating the master-detail application
The application I use for this example is a well-known one: a Master-Detail (form-table) page for DEPT and EMP. For each Department, we will see the details in a Form layout with underneath a Table component with all Employees in the Department.
Using JDeveloper 10.1.3, ADF BC, ADF Binding (Framework) and ADF Faces, creating such a page is almost trivial, especially if you generate it using JHeadstart 10.1.3 (which is what I did here). In quick summary the steps:
- Create new Application, choose Web Technology (ADF BC and JSF) as Technology Template; Model and ViewController project are created automatically
- Create Business Components from Tables EMP and DEPT in SCOTT schema in the Model project; add View Link from Source DeptView to Target EmpView
- Using JHeadstart: enable JHeadstart on the ViewController project, create default Application Definition file, generate the application
- Without JHeadstart: create a new JSF JSP page, drag and drop DeptView from the AppModule DataControl as Editable Form, drag and drop EmpView2 under DeptView to the jspx page.
- Run the Application to verify the data is shown and the master-detail coordination works as expected.
Add the Salary Summary to the DeptView ViewObject
We want this page to also contain the summary of all salaries in the currently selected Department. Where to put it is a later concern, let’s first get it on the page in the first place. The steps for this are:
1. Select the DeptView ViewObject and select Edit from the RMB menu
2. On the Attributes tab, press the New button to create a new (transient) attribute called SalSum. SalSum is of type Number, is Never updateable and is not mapped to Column or SQL
3. On the Java Tab, check the checkbox Generate Java File under View Row Class DeptViewRowImpl; also check the Accessors checkbox:
4. Press OK to close the VO Editor wizard.
5. From the RMB menu on the DeptView VO, select the option Goto View Row Class
Locate the Number getSalSum() accessor method. Replace the default implementation with this one:
publicNumber getSalSum(){<br />RowIterator emps = getEmpView(); <br />Number sum =newNumber(0);<br />while(emps.hasNext()){<br /> sum = sum.add((Number)emps.next().getAttribute("Sal")); <br />}<br />return sum;<br />}<br />
6. Add the SalarySum to the page either by dragging and dropping it from the DataControl Palette, or by synchronizing the Dept Group in the JHeadstart Application Definition editor and regenerating the application.
7. Run the application to inspect the newly added SalarySum. It should contain the correct sum of the salaries in the currently selected department. If you change the value of one of the salaries, it will currently not be updated automatically when you leave the field. It will however be synchronized for example when you sort the table by clicking one of the sortable column headers.
Creating a proper Column Footer with the Salary Summary
The next step is to create the proper layout for the Salary Summary: we want to have it displayed in Footer underneath the Salary Column in our Table Component. The ADF Faces Column Component has a so called footer facet. We can use that facet to specify whatever should be rendered underneath the column. So we can implement the column footer facet for the Salary column, containing the SalarySummary, much like this:
<af:column sortable="true" noWrap="true"<br /> sortProperty="Sal" formatType="number"><br /> <f:facet name="header"><br /><h:panelGroup> <br /><h:outputText value="Salary"/><br /></h:panelGroup><br /> </f:facet><br /><af:inputText id="DetailEmpSal" value="#{row.Sal}"<br /> required="#{bindings.DetailEmpSal.mandatory}"<br /> rows="#{bindings.DetailEmpSal.displayHeight}"<br /> columns="#{bindings.DetailEmpSal.displayWidth}"<br /> maximumLength="10"><br /><f:convertNumber groupingUsed="false" <br /> pattern="#{bindings.DetailEmpSal.format}"/><br /></af:inputText><br /> <f:facet name="footer"><br /><h:panelGroup><br /> <af:outputText id="DeptEmpSalSum"<br /> value="#{bindings.DeptEmpSalSum.inputValue}"><br /> <f:convertNumber groupingUsed="false"<br /> pattern="#{bindings.DetailEmpSal.format}"/><br /></af:outputText> <br /></h:panelGroup><br /></f:facet><br /></af:column><br />
However, it turns out that the Column Footer Facet gets only rendered if also the Table’s Footer Facet has been specified. Otherwise, the column footer is simply not rendered! The table footer facet is like this:
<f:facet name="footer"><br /> <af:outputText id="deptEmpTableFooter" value="Summary:"/><br /></f:facet><br /></af:table><br />
Dynamically Refreshing the Salary Summary whenever a Salary value is changed
At this point, when the page is loaded, the Summary is displayed as expected. However, if we change the value of one of the salaries, the Summary is not immediately updated. Only when the table is refreshed for some other reason, such as sorting or detail disclosure/hide will the new summary value be shown. What we would like to have is an immediate update of the Summary whenever one of the Salaries is changed. We want to leverage the Partial Page Refresh mechanism of ADF Faces to help us realize this.
1. Let’s ensure that a change in a salary value causes an immediate submit to the server. We can easily do that by setting the autoSubmit attribute for the DetailEmpSal inputText component to true:
<af:inputText id="DetailEmpSal" value="#{row.Sal}"<br /> required="#{bindings.DetailEmpSal.mandatory}"<br /> rows="#{bindings.DetailEmpSal.displayHeight}"<br /> columns="#{bindings.DetailEmpSal.displayWidth}"<br /> maximumLength="10" autoSubmit="true"><br /><f:convertNumber groupingUsed="false"<br /> pattern="#{bindings.DetailEmpSal.format}"/><br /></af:inputText><br />
2. In order to update the SummarySal element upon processing the Partial Page Refresh caused by the Sal
ary change, we have to set the partia
lTriggers attribute.
However, here we run into a problem: we need to specify the ID of the component whose change should trigger the update of the Salary Sum in the partialTriggers attribute for the DeptEmpSalSum component. However, even though the ID for the Salary inputText component seems simple enough – DetailEmpSal – this is not the correct value! Since the Salary field will appear not once but once for every record in our table component and the ID needs to be unique, the actual ID will be different. Each Salary field will have an ID that includes DetailEmpSal as well as :0, :1, :2 etc. to make the ID values unique.
When I try a temporary workaround, just to see whether things are working, I run into a second issue: if I specify partialTriggers="DeptEmpDname" for the Column Footer Facet and/or the Table Footer Facet, it turns out that they are not in fact refreshed when PPR is processed. Only when I specify partialTriggers="DeptEmpDname" at the level of the Table Component will the Footer Facets be properly updated as part of the PPR processing cycle. That means I have now achieved that whenever I change one or more Salary values and I subsequently change the Department Name in the Master record, I get ‘dynamic, instantaneous’ update of the Salary Sum. Almost there, but not quite. By the way: what I am doing here is somewhat similar to Frank Nimphius’ blog article: ADF Faces: Compute totals of selected rows in a multi select table. He does not seem to have a problem with Table Footer refresh so perhaps I am doing something wrong here.
After consulting Frank and Duncan Mills, I am pointed in a new direction: programmatically specifying the targets of Partial Page Refresh. Sounds interesting, let’s try it out:
Programmatically specifying the targets of Partial Page Refresh
There is an API call – AdfFacesContext.getCurrentInstance().addPartialTarget(<the component to
refresh>); – that Duncan suggested to me. This should allow me to specify the Table – or perhaps even the Table and/or Column Footer Facet – that should be refreshed as part of the current PPR cycle. Of course, this call should be made whenever Salary has been changed. So using a ValueChangeListener, I should be well on my way. Should I not?
1. Create a new class EmpMgr to handle the Salary Changed event by adding the EmployeeTable to the list of partial targets:
import javax.faces.application.Application;<br /> import javax.faces.component.UIComponent;<br /> import javax.faces.context.FacesContext;<br /> import javax.faces.event.ValueChangeEvent;<br /><br /> import oracle.adf.view.faces.context.AdfFacesContext;<br /><br /> publicclassEmpMgr{<br />publicEmpMgr(){<br />}<br /><br /> publicvoidHandleSalaryChangeEvent(ValueChangeEvent valueChangeEvent) {<br />Application app =FacesContext.getCurrentInstance().getApplication(); <br />UIComponent table =(UIComponent)app.createValueBinding( "#{DetailEmpCollectionModel.table}").getValue(FacesContext.getCurrentInstance()); <br />AdfFacesContext.getCurrentInstance().addPartialTarget(table);<br /><br />}<br />} <br />
Note: the table component had its Binding property already set to #{DetailEmpCollectionModel.table}; I am simply reusing that binding. Also note that trying to use the DeptEmpSalSum outputText as partialTarget did not lead to a refresh: I had to use the table as refresh target.
2. Configure this new class as Managed Bean
...<br /><managed-bean><br /><managed-bean-name>EmpMgr< /managed-bean-name><br /><managed-bean-class>EmpMgr< /managed-bean-class><br /><managed-bean-scope>session< /managed-bean-scope><br /></managed-bean><br /></faces-config><br />
3. Specify a ValueChangeListener for the Salary field in my Employees table:
<af:inputText id="DetailEmpSal" value="#{row.Sal}"<br /> required="#{bindings.DetailEmpSal.mandatory}"<br /> rows="#{bindings.DetailEmpSal.displayHeight}"<br /> columns="#{bindings.DetailEmpSal.displayWidth}"<br /> maximumLength="10" autoSubmit="true"<br /> valueChangeListener="#{EmpMgr.HandleSalaryChangeEvent}"><br /><f:convertNumber groupingUsed="false"<br /> pattern="#{bindings.DetailEmpSal.format}"/><br /></af:inputText><br /> <br />
4. Run the application, change a salary and keep your fingers crossed… IT WORKS!!!! (Thanks Frank and Duncan). Note: this opens up a lot of very interesting possibilities: we can determine dynamically on the server side which fields to be updated in the browser by simply adding them to the list of partialTargets.
相关推荐
ADF实现多选框及分页的Table组件,提供例如上一页,下一页,首页,尾页,以及页码下拉菜单来实现数据分页显示
ADF中最常用的Table组件af:table具有非常多的内置功能,如排序、过滤、切换列位置,以及通过滚动条来实现的分页。默认情况下,通过滚动条,af:table会和后端的data control配合实现数据分批展现。在af:table中选择某...
ADF4351配置程序,主要是C51配置ADF5351/4350
12 Using ADF Faces Components 13 Applying Standards to the Application 14 Building a Query Page with UI Components 15 Creating Updatable Pages 16 Handling Application Events 17 Creating the Business ...
基于80c51f芯片控制的频率合成器adf4360-7
包含 ADF 重定向页面 换界面皮肤方法
英文版的,中文版还在找。貌似中文的ADF设计网上都是付费购买的。。。。
adf入门开发相关
NULL 博文链接:https://genius.iteye.com/blog/1099251
Oracle ADF 11g在RichTable添加行到最后一行
'''进行ADF检验 adf_test的返回值 Test statistic:代表检验统计量 p-value:代表p值检验的概率 Lags used:使用的滞后k,autolag=AIC时会自动选择滞后 Number of Observations Used:样本数量 Critical Value(5%) :...
ADF Table 选中某行,popup弹出编辑和添加例子
ADF4351锁相环例程,能输出35M~4400M的信号
在ADF的Table中,我们能实现在表格中添加,编辑,删除行的功能,以及一行数据中的级联。然而在多数时候,当一行的列太多,表格中的数据量不多的时候,这种在table中直接添加的方式则显得很不友好,因为要来回的拉动...
基于MSP430F5438A的数字锁相环ADF4351合成频率源的设计 ADF4351驱动程序
ADF Toolbox in MATLAB.
MJPG-streamer源码
ADF4350结合外部环路滤波器和外部基准频率使用时,可实现小数N分频或整数N分频锁相环(PLL)频率合成器。 ADF4350具有一个集成电压控制振荡器(VCO),其基波输出频率范围为2200 MHz至4400 MHz。此外,利用1/2/4/8/16...
在MATLAB中检验数据的单位根,关于单位根检测的matlab代码
stm32平台的ADF4002锁相环芯片驱动程序