ON CHANGE in tGet
ON CHANGE in tGet
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
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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
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
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
VALID
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 ....
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
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
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).
[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
>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).
Code: Select all
class TXData from TData
data aOriginal init {}
method load
endclass
method load()
super:load()
acopy(::aBuffer, ::aOriginal)
return nil
James
Valid / On Change
Thanks.
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
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
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
Code: Select all
#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
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Works fine for me:
EMG
Code: Select all
#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
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Enrico,
Hmm, that does seem to work, but this doesn't. It returns nil.
James
Hmm, that does seem to work, but this doesn't. It returns nil.
James
Code: Select all
#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
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Continuing
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 <> oGet:oGet:origianl, msgInfo( "Data changed"), ), .t. )
// oGet:bLostFocus = { || MsgInfo( oGet:oGet:Original ) }
@ 3, 1 BUTTON "&Close";
ACTION oDlg:End()
ACTIVATE DIALOG oDlg;
CENTER
RETURN NIL
#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 <> oGet:oGet:origianl, msgInfo( "Data changed"), ), .t. )
// oGet:bLostFocus = { || MsgInfo( oGet:oGet:Original ) }
@ 3, 1 BUTTON "&Close";
ACTION oDlg:End()
ACTIVATE DIALOG oDlg;
CENTER
RETURN NIL
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact: