Please disable your adblock and script blockers to view this page

Search this blog

Wednesday 24 February 2016

Drag Drop in same table to reorder rows, Update Attribute value to make it persistent

This post is based on Frank's article on reordering table rows using drag drop functionality of ADF Faces, post uses iterator indexing to change order of rows and it works pretty good

Recently i came across a question on OTN forum asking about making this ordering persistent on base of some attribute value so for that we have to maintain a serial no attribute for each row and when user performs Drag n Drop , serial no. will be swapped and updated ordering of rows will be shown to user and it is persistent as updated attribute's value is saved in database

So for this use case i have added a Serial No. column in Departments table of HR Schema

Let's see how to implement this
  • Create a Fusion Web Application and prepare model using Departments table of HR Schema

  • Drop Departments view object as table on page, drop af:dragSource and af:collectionDropTarget as child of af:table in order to enable Drag n Drop functionality 


  • Define Drop Listener for drop target and set Model Name (this will be discriminant of drag source) and actions 

  •          Set properties of Drag Source


  • See Managed Bean code , Helper methods and Drop Listener Code
  • Required Packages

    import java.util.Iterator;
    import java.util.List;
    
    import oracle.adf.model.BindingContext;
    import oracle.adf.view.rich.component.rich.data.RichTable;
    import oracle.adf.view.rich.datatransfer.DataFlavor;
    import oracle.adf.view.rich.datatransfer.Transferable;
    import oracle.adf.view.rich.dnd.DnDAction;
    import oracle.adf.view.rich.event.DropEvent;
    
    import oracle.binding.BindingContainer;
    import oracle.binding.OperationBinding;
    
    import oracle.jbo.Row;
    
    import org.apache.myfaces.trinidad.model.RowKeySet;
    


    Helper Methods

        /**Method to get BindingContainer of current viewPort
         * @return
         */
        public BindingContainer getBindingsCont() {
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**
         * Generic Method to execute operation
         * */
        public OperationBinding executeOperation(String operation) {
            OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
            return createParam;
        }
    


    Drop Listener (Gets dragged and drop rowsite and swaps serial no)

        /**Method to handle drop event
         * @param dropEvent
         * @return
         */
        public DnDAction reOrderDropListener(DropEvent dropEvent) {
            //get the table instance. This information is later used
    
            RichTable table = (RichTable) dropEvent.getDragComponent();
            List dropRowKey = (List) dropEvent.getDropSite(); //if no dropsite then drop area was not a data area
            if (dropRowKey == null) {
                return DnDAction.NONE;
            }
            //The transferable is the payload that contains the dragged row's
            //row key that we use to access the dragged row handle in the ADF
            //iterator binding
            Transferable t = dropEvent.getTransferable();
            //here "reorderrow" is the discriminant used in drag source
            DataFlavor<RowKeySet> df = DataFlavor.getDataFlavor(RowKeySet.class, "reorderrow");
            RowKeySet rks = t.getData(df);
            Iterator iter = rks.iterator();
    
            //for this use case the re-order of rows is one-by-one, which means
            //that the rowKeySet should only contain a single entry. If it
            //contains more then still we only look at a singe (first) row key entry
            List draggedRowKey = (List) iter.next();
    
            //Dragged Row
            Row dragRow = (Row) table.getRowData(draggedRowKey);
    
            //Drop Row
            Row dropRow = (Row) table.getRowData(dropRowKey);
    
            //Get Serial No from dragged row
            Integer dragSno = (Integer) dragRow.getAttribute("Sno");
            //Get Serial No of dropped row
            Integer dropSno = (Integer) dropRow.getAttribute("Sno");
    
            //Swap Values to change order in DB
            dragRow.setAttribute("Sno", dropSno);
            dropRow.setAttribute("Sno", dragSno);
    
            //Call Commit Operation to save chanes in database
            executeOperation("Commit").execute();
    
            //Call Execute operation to see updated records
            executeOperation("Execute").execute();
            return DnDAction.MOVE;
        }
    


  • Now run and check application. Dragged Purchasing department and dropped on Administration
       
         After calling drop listener -


Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

2 comments :

  1. Hi Ashish,
    Thank you for the blog. We are currently on 12.2.1.3 and both your sample application and our changes doesnt seem to be working. Any idea if there is any known issue on the approach above?
    The 12.2.1.3 documentation does not mention any changes to af:dragSource and af:collectionDropTarget

    ReplyDelete
    Replies
    1. Hi HDS

      I have checked sample application and it is working for me , Try running application in a different machine or browser

      Ashish

      Delete