Wednesday May 30, 2012

Problem with deleting table rows using ctrl+a for row selection

The following code is commonly shown and documented for how to access the row key of selected table rows in an ADF Faces table configured for multi row selection.

public void onRemoveSelectedTableRows(ActionEvent actionEvent) {
   RichTable richTable = … get access to your table instance …
   CollectionModel cm =(CollectionModel)richTable.getValue();
   RowKeySet rowKeySet = (RowKeySet)richTable.getSelectedRowKeys();        
  
   for (Object key : rowKeySet) {
      richTable.setRowKey(key);
      JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding)cm.getRowData();
      // do something with rowData e.g.update, print, copy
   }
   //optional, if you changed data, refresh the table      
   AdfFacesContext adfFacesContext = AdfFacesContext.getCurrentInstance();
   adfFacesContext.addPartialTarget(richTable);  
   return null;
}

The code shown above works for 99.5 % of all use cases that deal with multi row selection enabled ADF Faces tables, except for when users use the ctrl+a key to mark all rows for delete. Just to make sure I am clear: if you use ctrl+a to mark rows to perform any other operation on them – like bulk updating all rows for a specific attribute – then this works with the code shown above. Even for bulk row delete, any other mean of row selection (shift+click and multiple ctrl+click) works like a charm and the rows are deleted.

So apparently it is the use of ctrl+a that causes the problem when deleting multiple rows of an ADF Faces table. To implement code that works for all table selection use cases, including the one to delete all table rows in one go, you use the code shown below.

public void onRemoveSelectedTableRows(ActionEvent actionEvent) {
  RichTable richTable = … get access to your table instance …
  CollectionModel cm = (CollectionModel)richTable.getValue();
  RowKeySet rowKeySet = (RowKeySet)richTable.getSelectedRowKeys();

  Object[] rowKeySetArray = rowKeySet.toArray();   

  for (Object key : rowKeySetArray){           
    richTable.setRowKey(key);
    JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding)cm.getRowData();                           
    rowData.getRow().remove();
  }
  
  AdfFacesContext adfFacesContext = AdfFacesContext.getCurrentInstance();          
  adfFacesContext.addPartialTarget(richTable);
}

Wednesday Jan 18, 2012

How to access selected rows in an af:selectManyChoice component

To create an ADF bound select many choice component, drag a collection from the Data Controls panel to a JSF page. In the opened context menu, choose Multiple Selection | ADF Select Many Choice.

This generates the page source code similar to this:

<af:selectManyChoice value="#{bindings.allDepartments.inputValue}"  
                     label="#{bindings.allDepartments.label}"
                     id="smc1">
  <f:selectItems value="#{bindings.allDepartments.items}" id="si1"/>
</af:selectManyChoice>

Note that the value property of the SelectManyChoice component pints to the sane list binding as the f:selectItems tag. To access the user selected values, you use a managed bean to access the ADF binding layer.

If you are only interested in the selected values, then you use code like shown below. Note that the sample I built used JDeveloper 11g R2, which is why the ID type is Integer. Doing the same with JDeveloper 11g R1 would require the casting to oracle.jbo.domain.Number for ID columns.

public String cb1_action() {
  BindingContext bctx = BindingContext.getCurrent();
  BindingContainer bindings = bctx.getCurrentBindingsEntry();
  JUCtrlListBinding allDepartsmentList = 
           (JUCtrlListBinding) bindings.get("allDepartments");
    Object[] selVals = allDepartsmentList.getSelectedValues();
    for (int i = 0; i < selVals.length; i++) {
      Integer val = (Integer)selVals[i];
      //...
    }
   return null;
}

However, what if you wanted to know more about the selected list value; for example the value of another attribute of the selected row? In this case you use similar code, with a little change though. Instead of calling getSelectedValues(), the call is to getSelectedIndices().


public String cb1_action() {
  BindingContext bctx = BindingContext.getCurrent();
  BindingContainer bindings = bctx.getCurrentBindingsEntry();
  JUCtrlListBinding allDepartsmentList = 
          (JUCtrlListBinding) bindings.get("allDepartments");
  int[] selVals = allDepartsmentList.getSelectedIndices();
  for (int indx : selVals ) {
    Row rw = allDepartsmentList.getRowAtRangeIndex(indx);
    //... do your stuff
  }
  return null;
}

About

The Oracle JDeveloper forum ranks in the Top 5 of the most active forums on the Oracle Technology Network (OTN).



The OTN Harvest blog is a summary of selected topics posted on the OTN Oracle JDeveloper forum.



It is an effort to turn knowledge exchange into an interesting read for developers who enjoy little nuggets of wisdom





Frank Nimphius

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today