CAF- Adding new rows in a content provider is not reflected on server side.

Hi,
I’m trying to implement a functionality in CAF with which a user can add/remove rows in a table and on click of save button the action should get all the row values from the table and send it to a flow service.

So far I have a service which populates the row values in the table from the database. After the user adds a new row and enters values in the text boxes and clicks save the new row disappears. i.e the row is getting added on client side but the values are not sent to server side.

Here is the code that im using for save action.


public String saveUsers() {

                selectedRWProperty = new java.util.ArrayList<java.lang.String>();

                List<Object> selectedRows = this.resultProvider.getSelectedRows();
                if (selectedRows != null && selectedRows.size() != 0) {
                        for (Iterator iterator = selectedRows.iterator(); iterator.hasNext();) {

                            com.webmethods.caf.is.wsclient.myPackage.cafservices.selectusers_caf.__results c = ( 
com.webmethods.caf.is.wsclient.myPackage.cafservices.selectusers_caf.__results) iterator.next();

//These are the different fields in each row
                                selectedRWProperty.add(c.getUSERNAME());
                                selectedRWProperty.add(c.getPLANTCODE());
                                selectedRWProperty.add(c.getGROUPING());
                                selectedRWProperty.add(c.getWRITE());
                                selectedRWProperty.add(c.getREAD());
                        }
                }

            resolveDataBinding(SAVEUSERS_PROPERTY_BINDINGS, this, "saveUsers.this", true, false);
                return OUTCOME_OK;
        }

After i click the save button, the newly added rows disappear and also the values are not sent to the server.

What might be the problem? Or is there any steps that I need to follow while implementing the add/remove row functionality?

Regards,
Monish

Hi. This can be a tricky operation and we hope to be able to help automate it in the future. In the meantime I’d recommend having a look at some of these posts: http://tech.forums.softwareag.com/techjforum/jforum.page?module=search&action=search&search_keywords=getSelectedRows&match_type=all&exclude_keywords=&search_author_name=&search_forum=187&sort_by=relevance&search_cat=&show_results=topics&search_prev=0&select=-1

In those topics there are some pointers to code samples, community articles and some “gotchas” that others have experienced.

Hope this helps.
Regards,
–mark

Hi

You may have more luck directly updating the model (ie the data source the Content Provider is using) with the new row. It sucks, but CPs often can’t be trusted to do what they advertise they can do :slight_smile:

Sorry, because this brings its own set of problems, particularly if you change the data model in IS later, but give it a shot. At least those problems can be solved with tedious amounts of Java mappings!

Some things to consider,

  1. You must use an ‘updateable’ table content provider.
  2. If there are validation or conversion errors in the submitted form, the request lifecycle will fail during the ‘validate’ phase and never make it to the ‘update model’ phase where the table rows are added to the backing content provider.

Hi Eric

Is it possible to see a minimal CAF project where this works? A (selectable) updateable content provider on top of a document list, which makes a table, there’s a CAF Add Row Button on the table, and when the form the table’s in is submitted, the original document list is updated?

Sorry for a big ask, but I’ve never seen this working, and your post gave me hope!

Rob

Sorry to push but this is becoming a blocker for us. Is there any way to do it?

Okay - this is the way I’ve found. Basically entirely thanks to Javier.

Includes obvious stuff. Parts only there to show what’s happening are in italics:

  1. Have a document list in the CAF bindings that represents what the table will display/update (here called docList; document type caf.war.sampleProject.is.document.Sample_doc_listDoc)
  2. Right click on the document list / create new content provider (selectable/updateable) (here called docListProvider)
  3. Double click on docListProvider in bindings to open the following code:
public com.webmethods.caf.faces.data.object.SelectableListTableContentProvider getDocListProvider()  {
                     if (docListProvider == null) {
                         docListProvider = (com.webmethods.caf.faces.data.object.SelectableListTableContentProvider)resolveExpression("#{DocListProvider}");
                     }

                     resolveDataBinding(DOCLISTPROVIDER_PROPERTY_BINDINGS, docListProvider, "docListProvider", false, false);
                     return docListProvider;
       }

Move the resolveDataBinding into the if statement, so it now looks like this:

public com.webmethods.caf.faces.data.object.SelectableListTableContentProvider getDocListProvider()  {
                     if (docListProvider == null) {
                         docListProvider = (com.webmethods.caf.faces.data.object.SelectableListTableContentProvider)resolveExpression("#{DocListProvider}");
                         resolveDataBinding(DOCLISTPROVIDER_PROPERTY_BINDINGS, docListProvider, "docListProvider", false, false);
                     }
       
                     return docListProvider;
       }
  1. Drag docListProvider onto the screen inside a form to create a table
  2. Edit the table to change control to input types
  3. Add an Add Row button to the screen and point it at the table
  4. Add an action called actionAddRowToTable
  5. Inside actionAddRowToTable, add the following code after resolveDataBinding:
docList = (ArrayList<caf.war.sampleProject.is.document.Sample_doc_listDoc>) getDocListProvider().getList();
  1. Drag docList onto the screen to make a table to show what’s in it. It will make a table called asyncTable1.
  2. Add a Submit Button to submit the form the table’s in. Make its action actionAddRowToTable. Set it to refresh asyncTable1.
  3. Add some rows to the table, and enter data. Hit Submit. You should see the correct data reflected in the second table.