ADF DI - How to operate on a selected row in the table component within excel

Printer-friendly versionPDF version
ADF-DI Excel

 

ADF DI is ADF's desktop integration that enables a user to work with data in an excel sheet. It is not too feature rich and has its limitations, but it also does well, what it sets out to do. Basically batch creates, deletes and updates are really no problems for tables.

 

But working for PLM, we don't really have tables but treetables in the form of BOMs. Displaying such BOMs is easy enough, you can use recursive sql statements or the Oracle CONNECT BY clause and flatten the BOM to table form for display in excel. Thereafter updates to the BOM tree structures are also trivially handled by excel. You can also enable delete on the excel sheet and delete any rows simplistically. That all works out of the box.

 

 

Now what if you need to insert rows at any given level of BOM tree in excel ?

 

 

Well ADF DI has you covered in that front as well, sort of. What you would probably do is enable the "RowActions.InsertRowEnabled" flag on the "Worksheet Properties". This allows you to insert rows randomly anywhere in your flattened BOM tree and during upload the rows get created in the model. You basically use Excel formulas to default Id attributes that constitute the hierarchy in the BOM tree. You can create any number of rows offline for existing rows on the model and batch insert. BUT now imagine if your adding a row to a newly added row. Till the server round trip has not happened, you need to creatively manage the hierarchical Ids. Maybe allot temporary ids to point to parent and child row in BOM and than once row gets uploaded on server, do updates to the same and re-write the correct server side Ids. Seems like an overkill but might work. Don't ask me how though, as I did not go down this path yet. The pro from this approach is that all this can happen offline from the server and you batch upload your changes. And that would be only reason to bear all this pain.

 

 

Now if you can live without Offline Insert operations and are ok with bulk or single insert operations in an online mode i.e. your insert row operation immediately runs to server, creates rows, sets parent-child ids and downloads the results to your excel sheet for further editing than the next fiendish solution I propose is for you.

 

 

The Clue to the solution

 

 

What we really need is as soon as the Insert operation takes place, based on, say the currently selected row, we perform our operation. So the newly created row could be a child or an immediate sibling of the currently selected row. For this we need to know on the model layer what is the currently selected row, when the Insert operation occurs. The RowActions.InsertAfterRowActionID and RowActions.InsertBeforeRowActionID only occur on Upload and not really when you click Insert row in excel sheet. So it is completely offline till you trigger "Upload". So in essence no server round trip On Insert and no current row context.

 

 

The recipe to the solution

 

 

For the imaginative, if you went through the ADF DI documentation, the only operation that is happening in context of a *currently selected row* is the delete row operation. I put it in stars as you can do it in batch i.e. select more than one rows and perform delete on each one of them. That is our silver lining. For purist, they might scream. But what follows is a solution that will work. The concept is so simple, I am surprised why ADF DI does not offer this as an out of the box solution, i.e. select multiple rows and conduct an operation on them. There should really be an ER for it.

 

 

Anyways, for this solution, first take a look at the below Action Set you create for any generic operation that you need to perform in context of a currently selected row.

 

 

Now let my provide a description from top down to what is happening in this action set.

 

 

toggleDelToOpOnSelRowForDI: This is a java method exposed from the model layer (AM or VO method) that basically just sets a flag on the AM managed Userdata Hashtable object on the Session. This flag is what we will later access. So you can set this flag something like below:

 

 

 

public void toggleDelToOpOnSelRowForDI() {
        Session session = getApplicationModule().getSession();
        session.getUserData().put("TOGGLE_DI_DELETE_TO_MY_DESIRED_OP_FLAG", Boolean.TRUE);
    }

 

 

DeleteFlaggedRows: The next operation is the out-of-the-box operation from ADF DI to delete rows. Put that in first as below:

 

 

 

 

Now go to your VO that is used to render the table and override the below method:

 

 

 

@Override
    public void removeCurrentRow() {
        Hashtable hashtable = getApplicationModule().getSession().getUserData();
        Boolean myCustomOp = hashtable.get("TOGGLE_DI_DELETE_TO_MY_DESIRED_OP_FLAG") == null ? Boolean.FALSE : Boolean.TRUE ;
        MyBOMVORowImpl row = (MyBOMVORowImpl) getCurrentRow();
        if ( myCustomOp )
            row.doMyCustomOpOnRow();  // add child or sibling or default values or do calcs whatever
        else {
            super.removeCurrentRow();
        }
    }

 

 

Note how we looked up the previously set up flag from our first action in the Action Set list. You can check for as many flags as you like and switch operations using further "else ifs" in this method.

 

resetDelToggelesForDI: Before the action set completes we need to revert back the standard delete behaviour. This is a java method exposed from the model layer (AM or VO method) that trivially removed the flag from the User session. Put this method in the same place where your setter is.

 

 

 

public void toggleDelToOpOnSelRowForDI() {
        Session session = getApplicationModule().getSession();
        session.getUserData().remove("TOGGLE_DI_DELETE_TO_MY_DESIRED_OP_FLAG");
}

 

 

 

 

The Next method is commit and than you need to basically call a method that re-executes the query of your VO. Finally download the results to excel. These last steps are necessary otherwise for my case the newly inserted row was appearing a level above where it could be considered correct. After re-execute query and download, the location was always correct for my inserts.

 

Modify all status messages and annotations and labels in the Action Sets and the user won't even see the standard "Deleting Rows" messages. And the success message will also get modified. So you wont confuse your users if you are doing some other operation instead of delete by showing delete on various labels.

 

 

So enjoy this fiendish solution. Not really what the ADF developers might have intended for this operation, but it serves a useful purpose. Create an ER for oracle to officially support this :)

Tags:

Top level category:

Add new comment