FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour ON CHANGE in tGet
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
ON CHANGE in tGet
Posted: Wed Jul 25, 2007 12:32 AM

Maybe old age is getting me.

I thought the ON CHANGE activated when the total value of a get was modified, not for each character entered. I realize a VALID tests the total value, but I want to run a function only if the total value changes, not everytime the field is displayed.

Currently, ON CHANGE will activate with every keystroke, as demonstrated in the following example. Is this a correct behavior ?

// Test On Change in get

INCLUDE "fivewin.CH"

PROCEDURE main

LOCAL oDlg
LOCAL oTestGet := SPACE(10)

DEFINE DIALOG oDlg SIZE 500, 300

@ 3, 10 GET oTestGet PICTURE "@!" ON CHANGE ( MsgAlert( "Changed" ) )

ACTIVATE DIALOG oDlg

RETURN NIL

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Wed Jul 25, 2007 12:58 AM

Tim,

Yes, that is the correct behavior for bChange. It is used to do special processing while the data is being input. You can use it for custom pictures, etc.

As you said, use the VALID clause. To use bValid just store the "before" value in a var and then test it with the after value in bValid. bValid won't be eval'd unless the user enters the field. If you are using a database, you can check the get var against the field contents to see if it has been changed instead of creating a "before" var.

James

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
VALID
Posted: Wed Jul 25, 2007 01:09 AM

James,

Using tData, I'm editing oDbf:var1 for example, and if I now change the content in the dialog, how can I validate against the original database unless I store a new var on loading the record ?

Tim

ie>

REDEFINE GET oGt1 VAR oDbf:var1 ID 201 OF oDlg ;
VALID testvalue( )

Where testvalue( ) only executes if the originally saved value of oDbf:var1 is changed in this control ?

I know I can read the value at load and store it to a variable that executes if there is a change, but I wanted to avoid the extra code if I can read the data ....

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Wed Jul 25, 2007 01:43 AM
Tim,

>Using tData, I'm editing oDbf:var1 for example, and if I now change the content in the dialog, how can I validate against the original database unless I store a new var on loading the record ?

Try this:

REDEFINE GET oGt1 VAR oDbf:var1 ID 201 OF oDlg ;
VALID if( oDbf:var1 <> (oDbf:cAlias)->var1, msgInfo( "Changed"),)

The upside is that you don't have any extra code, the downside is that this requires a disc read. But it will only do a disc read if the user enters the field.

Another approach is to create a subclass of TData or TCustomer or whatever you are using, and add another buffer array. In the load() method copy the data to this array also. Then you can test every field against the original without another disk read and without any more code (the same code is reused everywhere your database class is used).

class TXData from TData
   data aOriginal init {}
   method load
endclass

method load()
   super:load()
   acopy(::aBuffer, ::aOriginal)
return nil


[Note: I always recommend using a subclass of TData for each application, even if it starts out empty. Then you use this class in your app. When you later want to add a generic feature to the database class, you can just add it to this one subclass, and the entire application will inherit it without any other code changes.]

James
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Valid / On Change
Posted: Wed Jul 25, 2007 04:33 PM

Thanks.

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 11:05 AM
Tim,

There was something nagging me in the back of mind about this topic and it finally came to me.

In the old Clipper Get there was a var oGet:original which contained the original data. Unfortunately, in xHarbour this isn't working--it always returns nil. Too bad.

However, there is a simple workaround and that is to use oGet:cargo. It does require that you force this to be loaded in your code, but by doing this you can avoid an extra disk read or using an extra var. Below is a working sample.

Regards,
James


#include "fivewin.ch"

function main()
   local oDlg,oGet,oGet2,cVar:="Test     ",cVar2:="xxx       "

   define dialog oDlg

   @ 1,1 get oGet var cVar of oDlg ;
      valid if( oGet:cargo <> oGet:varGet(), (msgInfo("Changed"),.t.), (msgInfo("Not changed"),.t.) );

      oGet:cargo:= oGet:varGet()

   @ 2,1 get oGet2 var cVar2 of oDlg

   activate dialog oDlg centered

return nil
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 12:19 PM
Did you try

oGet:oGet:Original


?

EMG
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 12:58 PM

Enrico,

>Did you try

>oGet:oGet:Original

Yes, that is what I was referring to. It has never worked in Harbour or xHarbour as far as I know.

James

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 01:17 PM
Works fine for me:

#include "Fivewin.ch"


FUNCTION MAIN()

    LOCAL oDlg

    LOCAL oGet, cVar := PADR( "Test", 20 )

    DEFINE DIALOG oDlg 

    @ 1, 1 GET oGet VAR cVar

    oGet:bLostFocus = { || MsgInfo( oGet:oGet:Original ) }

    @ 3, 1 BUTTON "&Close";
           ACTION oDlg:End()

    ACTIVATE DIALOG oDlg;
             CENTER

    RETURN NIL


EMG
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 02:34 PM
Enrico,

Hmm, that does seem to work, but this doesn't. It returns nil.

James

#include "Fivewin.ch"

FUNCTION MAIN()

    LOCAL oDlg

    LOCAL oGet, cVar := PADR( "Test", 20 )

    DEFINE DIALOG oDlg

    @ 1, 1 GET oGet VAR cVar valid (msgInfo( oGet:oGet:original ),.t.)

   // oGet:bLostFocus = { || MsgInfo( oGet:oGet:Original ) }

    @ 3, 1 BUTTON "&Close";
           ACTION oDlg:End()

    ACTIVATE DIALOG oDlg;
             CENTER

    RETURN NIL
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 02:44 PM

Please remember that "Get:Original is meaningful only while the GET has input focus".

EMG

Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 04:11 PM

Enrico,

>Please remember that "Get:Original is meaningful only while the GET has input focus".

Are you saying that it doesn't have input focus when bValid is executed? I would think it has to have.

James

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Continuing
Posted: Thu Jul 26, 2007 04:39 PM

For the purpose of discussion, I would suppose this modification would work:

include "Fivewin.ch"

FUNCTION MAIN()

LOCAL oDlg

LOCAL oGet, cVar := PADR( "Test", 20 )

DEFINE DIALOG oDlg

@ 1, 1 GET oGet VAR cVar valid (IIF( cVar &lt;&gt; oGet:oGet:origianl, msgInfo( "Data changed"),  ), .t. )

// oGet:bLostFocus = { || MsgInfo( oGet:oGet:Original ) }

@ 3, 1 BUTTON "&amp;Close"; 
       ACTION oDlg:End()

ACTIVATE DIALOG oDlg; 
         CENTER

RETURN NIL
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 04:51 PM

Tim,

>For the purpose of discussion, I would suppose this modification would work:

No, from a VALID oGet:oGet:original returns nil. It does return the proper value from bLostFocus. This seems to be a bug to me.

James

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
ON CHANGE in tGet
Posted: Thu Jul 26, 2007 06:28 PM
James Bott wrote:Are you saying that it doesn't have input focus when bValid is executed?


Yes. Just check oGet:HasFocus. It is .T. in bLostFocus and .F. in bValid.

EMG