The views expressed on this blog are my own and do not necessarily reflect the views of my employer.

Saturday, April 16, 2011

Programmatically refreshing the child nodes of an <af:tree>

There are use cases where you may need to refresh(re-execute the query) the child nodes of a <af:tree> or <af:treeTable> programmatically . In this post I'm discussing a simple implementation for the same.

Query execution for retrieving child nodes

A bit of theory before getting in to the code sample. When you expand top level nodes for the first time, runtime will traverse through the View Link Accessor for the parent Row and identifies the child RowSet/ViewObject and execute the same. The execution of child View Object result in child nodes. When you expand the parent once again, the parent row may find an existing QueryCollection(wrapper object over Rows) with the matching row filter, e.g. say DeptId=10. This existing QC, which already has the filtered list of rows is re-used at this stage. In case you may need to refresh the child RowSet in all cases, you may need to brutally execute the corresponding RowSet. The below shown code snippet executes child Employees RowSet for a specific DepartmentId.

This example displays tree table for Department-Employee hierarchy. A pop up is given for editing Employee data. You can edit the Employee details and click on the Update button to refresh the corresponding child nodes displayed on the parent page. In the edit pop up, there is a check box(labelled as HiddenFlag) to control the visibility of the corresponding row displayed in the tree table. If you select this check box, row is removed from the corresponding RowSet( which constitutes the child nodes of the tree table).

The EmployeesViewImpl::rowQualifies(...) has been overridden to enable the in memeory filtering for the child nodes . Please see this post in case you are not familiar with this concept. the above given efreshChildEmployees(Number deptId) is wired to the 'update' button which ensure the execution of EmployeesViewImpl::rowQualifies(...) by brutally executing the child RowSet.

5 comments:

I just need to execute a custom query on the view object. My query is structured as follows :select * from mytablewhere id in(select id from mytableconnect by nocycle prior parentid = idstart with id in(select id from mytablewhere attt1=:inp1

... and so on))

Here clauses are set depending on the input values from user.For example :if (input=null) clause1=""; (blank)else clause1=" and upper(att2) like upper(" input ")";

When I give this query in my code, and display the data in a tree, I can only see the parents. When I try to navigate to children of nodes, it is blank. No idea why this is happening. And when I provide these clauses with some predefined values (no bind variables) in design view of VO, it works fine.

I also wonder whether these kind of clauses can be given using setNamedWhereClauseParam() method of VO.

I assume you are using the above said VO for child nodes.If yes try overrunning ViewObjectImpl::prepareRowSetForQuery(ViewRowSetImpl vrs) for child VO to pass the bind parameters- http://jobinesh.blogspot.com/2011/05/preparing-viewobjects-query-for.html

how can we implement the same thing if we are using POJOs and say on click of a Row we then fetch the child details for that row using a pl/sql api and want to re-render/refresh the details for that node?