Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Accessing form data before change

  1. #1
    Senior Member
    Join Date
    Jul 2013
    Location
    Ontario, Canada
    Posts
    658

    Accessing form data before change

    Hello,

    When you edit a form field, you have the options to accept or reject your change.
    I'm assuming the data is stored in some Lianja buffer.

    How do you access the the buffered data?

    Basically I need to track what change was made (for potential audit purposes) so I would need to know what the data originally was and what is was changed to.

    Cory

  2. #2
    Lianja Team davefoss's Avatar
    Join Date
    Feb 2012
    Posts
    111
    Hi Cory,

    Can you be a little more specific? It's probably just me, but the way I'm reading your post it seems to be contradicting itself. The first paragraph seems to be asking about a situation where a user types something into a field and then changes their mind and hits Cancel, while the last paragraph is asking about a data change that was actually committed?

  3. #3
    Lianja Development Team barrymavin's Avatar
    Join Date
    Feb 2012
    Location
    UK, USA, Thailand
    Posts
    6,221
    Hi Cory,

    Look at OLDVAL(), CURVAL() and OLDVALUES() in the doc wiki.

    Also SCATTER and SCATTER OLDVALUES which you can use with DIFFOBJ() to get the changes as an object which you can serialize using JSON_ENCODE() to store an audit trail.

    Also study SET TIMELINE ON, LIST TIMELINE etc which handles audit trails automatically albeit not for VTs which are on a remote machine and are being accessed/updated by applications that it does not know about.
    Principal developer of Lianja, Recital and other products

    Follow me on:

    Twitter: http://twitter.com/lianjaInc
    Facebook: http://www.facebook.com/LianjaInc
    LinkedIn: http://www.linkedin.com/in/barrymavin

  4. #4
    Lianja MVP
    Join Date
    Feb 2012
    Location
    Berea, KY, USA
    Posts
    2,068
    Hi Cory,

    Barry listed the functions available to give you the information you need. You would use those functions at the database level in the onbeforeupdate trigger, where those functions are still able to get the information you need to create a custom audit trail. The other option, of course, is to track all changes using Lianja's built-in ability.

    hth,

    Hank

  5. #5
    Senior Member
    Join Date
    Jul 2013
    Location
    Ontario, Canada
    Posts
    658
    Hello,

    Thank you for the responses.
    My desktop app uses virtual tables for the sections.

    Dave:
    Yes, you are correct.
    Let me try to explain further.
    The user may have edited a field although the change is not yet committed. By cancelling the edit, the field would revert back to the text prior to the change (potentially by reading a buffer to re-display the original value - assuming the value is actually being modified).

    Once the change has been committed, is there a method to determine what the old value was versus what the new value is.

    In a separate table, we track the changes made to the data (as well as other information).
    For example, the user edits an address field and clicks 'Enter'
    We would record something similar to: "CG changed address from 123 Fake Street to 987 Unknown Street"

    I don't know exactly when a table is updated, although it appears that when a user clicks the enter key after modifying a form fields, the virtual table commits the data and updates the actual table.


    Barry:
    When does the data actually get changed?
    I have added code in the section beforeupdate() and afterupdate() events using curval() and oldval(). I have also accessed the field itself and tried the same code for the changed() and datachanged() events. Nothing seems to display the new value.

    If I were to use SCATTER and SCATTER OLDVALUES, when would I access this?


    Hank:
    When or how would I use the onbeforeupdate trigger, based on a user changing a field linked with a virtual table?
    Apparently this is called when the user attempt to save the record - although when is the record actually saved?


    In my case, the user doesn't click a save button or use navigation to change records.
    The record is displayed from information gathered from a search panel.
    The user could either:
    - edit another field in the current or different section;
    - change pages to modify other data;
    - reset/clear the displayed information or ;
    - perform another search.

    Cory

  6. #6
    Lianja Development Team barrymavin's Avatar
    Join Date
    Feb 2012
    Location
    UK, USA, Thailand
    Posts
    6,221
    Hi Cory,

    As I have explained many times before, Lianja uses row buffering. A record is updated when the buffer is flushed or when you commit or navigate to another record.

    Data from the UI does not magically transfer into the buffers of the embedded database until the field loses focus at which point it will be pushed into the current buffer.

    When a record is read, it becomes the "Active record".

    There are two buffers. The "old data" and the "current data".

    Changes in the UI update the "current data".

    When a check for updating a record is made there is an internal flag to denote "dirty" and the contents of the "old" and "new" values are compared.

    Thats what oldval() and curval() give you.

    The "Changed" delegate is called whenever data changes in the UI. There is a delegate for "Formitem", "section" and "page". Lianja looks up the UI hierarchy to determine which one to call. This means you can have a one for a section and not have to duplicate it for each formitem in the section. Thats where you would use SCATTER etc.
    Last edited by barrymavin; 2015-04-27 at 23:05.
    Principal developer of Lianja, Recital and other products

    Follow me on:

    Twitter: http://twitter.com/lianjaInc
    Facebook: http://www.facebook.com/LianjaInc
    LinkedIn: http://www.linkedin.com/in/barrymavin

  7. #7
    Senior Member
    Join Date
    Jul 2013
    Location
    Ontario, Canada
    Posts
    658
    Hi Barry,

    I'm trying to work through this although I am having some difficulty.

    In the section changed event, I have something similar to the following:
    select vt_abc
    scatter oldvalues name oldvalues
    scatter name currentvalues
    oDifferences = diffobj(oldvalues, currentvalues)

    I'm confused how to navigate the values returned from DIFFOBJ().
    Say there are two values that have changes
    Code:
    Object (refcnt=2)
    (
       [addr2] => SOME ADDRESS 2   
       [addr3] => SOME ADDRESS 3
    )
    How would I loop through the object to determine the column names?

    Using the following only seems to return the description/value, not the column.
    Code:
    FOR i = 1 TO ALEN(oDifferences)
        ? oDifferences[1]
    ENDFOR
    Cory
    Last edited by CGibson; 2015-04-28 at 11:25.

  8. #8
    Lianja MVP
    Join Date
    Feb 2012
    Location
    Berea, KY, USA
    Posts
    2,068
    Hi Cory,

    Code:
    foreach oDifferences as cField => unewvalue
         ? cField, unewvalue
    endfor
    hth,

    Hank

  9. #9
    Lianja MVP
    Join Date
    Dec 2012
    Location
    Croatia, Zagreb
    Posts
    1,121
    To get the column (the key instead of value), use the same FOREACH approach as in dynamic/associative arrays, not FOR loop.
    See: http://www.lianja.com/community/show...ciative-arrays

    Code:
    // declare an empty dynamic arraya = array()
    
    // declare a simple dynamic array
    a = array("barry", "recital", "boston")
    foreach a as value
        ? value
    endfor
    
    // to add new elements to a dynamic array do this
    a[] = "london"
    a[]  = date()
    a[] = 21
    
    // declare an associative array
    a = array("name" => "barry", "company" => "recital", "location" => "boston")
    ? "length of a is " + len(a)
    foreach a as key => value
        ? "key=" + key + ", value=" + value
    endfor
    
    // associative arrays act just like objects and we can access their members using common OO syntax
    ? a.name
    ? a.company
    
    // alternaively you can look up values like this
    ? a["name"]
    ? a["company"]
    
    // adding new key/value pairs is simple
    a[ "age" ] = 21
    a[" date" ] = date()
    
    // to inspect a dynamic array just do this ? a
    Last edited by josipradnik; 2015-04-28 at 13:30.

  10. #10
    Senior Member
    Join Date
    Jul 2013
    Location
    Ontario, Canada
    Posts
    658
    Hi Hank & Josip,

    Thank you greatly.
    That is what I was looking for.

    Does anyone know if this is the only way to access the key/member names of an array or object?

    Cory

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Journey into the Cloud
Join us