Refreshing the contents of Smart Data Browser after updating

Posted by Admin on 26-May-2010 15:06

I'm trying to implement the following:

  • SDO with Orders
  • SDO with Order Lines
  • SDO with notes on Order
  • SDO with notes on Order Lines
  • SDB and SDV on each of these SDO's

When I'm adding an order line, and insert it between two existing lines, I'm incrementing the "higher" order lines in a  beginTransActionValidate, and trigger an openQuery in endTransactionValidate. Also, when the lines being incremented have a note attached to them, the notes are renumbered to point to the right order lines.

I'm able to do all this, and have correct data in the database. However, the SDB on Order Lines will rebuild with the correct information, and then have as the last line the line I just added.

Example:

Before:

LineItem
1AAA
2BBB
3CCC
4DDD
5EEE

Action: Insert a line between lines 2 and 3, with item ZZZ

After:

LineItem
1AAA
2BBB
3ZZZ
4CCC
5DDD
6EEE
3ZZZ

How do I get rid of the extra line, and reposition the browser on the actual line that I just added? I'm using Progress 10.B05 on Windows XP.

All Replies

Posted by Håvard Danielsen on 28-May-2010 12:47

Please use the Dynamics and ADM2 forum for questions about SmartObjects.

---

The duplicate rows are caused by your call to openQuery in endTransactionValidate. This is never the right place to directly control client side behavior, but the problem with duplicate rows is a known SDO issue that also may occur if you append new batches after you have added new rows.

The behavior is caused by the fact that the SDO temp-table rows are sorted by the RowNum field.  New records get high numbers and will always appear last in the browse.

There are many ways to avoid or workaround this behavior.

A reopen of the query will ensure that the rows get new row numbers, but it would need to be done from the client. The code example below shows an override of submitRow (in the SDO or adm2/customdata.p) thar reopens/refreshes the query when a new record has been added.

function submitRow returns logical
  (pcRowIdent as character,pcValueList as character) :
   define variable lnew as logical no-undo.
   define variable lok as logical no-undo.
   lnew = {fn getNewRow}.
   lok = super(pcRowIdent, pcValueList).  
   if lnew and lok then
       {fn refreshQuery}.
end function.

You left out an important part of the version number, but I'm guessing you are on 10.0B05, which is very lacking compared to current adm2, and probably require that you add your own refreshQuery

Here's the current data.p version:

FUNCTION refreshQuery RETURNS LOGICAL
  (  ) :
/*------------------------------------------------------------------------------
Purpose: Refresh browse query and reposition to currently selected row
   Notes: This is a refresh of the current query, so a never opened or closed
          query will not be refreshed by this.
        - Currently refreshes all dependant active child queries.  
------------------------------------------------------------------------------*/
  DEFINE VARIABLE cRowIdent AS CHARACTER  NO-UNDO.
  DEFINE VARIABLE lOpen     AS LOGICAL    NO-UNDO.
  DEFINE VARIABLE lOk       AS LOGICAL    NO-UNDO.

  &SCOPED-DEFINE xp-assign
  {get Rowident cRowIdent}
  {get QueryOpen lOpen}
  .
  &UNDEFINE xp-assign
 
  IF lOpen THEN
  DO:
    {fn closeQuery}.
    IF cRowIdent > "":U THEN
      lOk =  {fnarg fetchRowWhere cRowIdent}.
  
    if lok then 
    do:
      run updateQueryPosition in target-procedure.           
     /* different, since we refreshed children and repositioned to first
       (server only reads children for one parent record) */
      publish "dataAvailable" from target-procedure ('different').
      {set NewBatchInfo '':U}.
    end. 
    else    
      RUN fetchFirst IN TARGET-PROCEDURE.
   
    RETURN TRUE.
  END.
  RETURN FALSE.
END FUNCTION.

Message was edited by: Havard Danielsen

Posted by Håvard Danielsen on 28-May-2010 13:14

For some reason I cannot edit the above, so I have to use a reply:

I assume fetchRowWhere, which is the actual call to retreive data in the code above, exists in version 10.0. If it doesn't then you would use some combination of closeQuery and findRowwhere or fetchRowident.

Note: This approach requires an extra Appserver hit to resort the data. You could implement your own client resort and call this from submitRow instead. A client resort in an SDO would require traversing the RowObject rows using the current sort expression and reassigning the RowNum accordingly.

Note: The current/new row will probably not be positioned at the exact row in the viewport where it was added. You would probably override updateRecord (and possibly addRecord) in the browse and use set-repositioned-row or something to control this if necessary.

--

Just for the record, the DataView always resorts data locally on Add and can be configured to do this also on Update.

Posted by Admin on 29-May-2010 13:14

Hi Havard,

Thanks, this seems to work! and you were right about the version, 10.0B05 (so many 0's I though I'd leave one off... )

I tried it by using adm2/custom/datacustom.p and adding the new submitRow function and the refreshQuery function. Somehow, that didn't work - I can see the custom functions in the procedure viewer, but they never get executed. But adding them as local overrides in the SDO worked like a charm.

I'm not going to worry about the datacustom.p procedure - the development environment has some strange behavior when using ADM2 procedures, and as long as this works I'm happy.

Thanks again!

Cheers,

Ron.

This thread is closed