Discussion:
Using LostFocus instead of Valid
(too old to reply)
Gene Wirchenko
2013-01-28 20:28:56 UTC
Permalink
Dear Foxers:

I have used Valid for validation in my app since the beginning. I
would now like to change it over to using LostFocus since I can not
SetFocus when there is a Valid being executed.

What is a good way of doing this?

I have come up with something that works, but it is a kludge.


I can catch the error easily enough, but there is the issue of
how to keep the focus in the control with the error.

I have a form property (.oErrorCtl) for the last error control.

.oErrorCtl is initialised to .null. in the form's .init().

For a given control, if validation succeeds, .oErrorCtl is set to
.null..

For a given control, if validation fails, .oErrorCtl is set to
this (which is the error control) and the event processing continues
(which gives focus to the next control). In the .GotFocus() of the
next control, .oErrorCtl is checked if it is not null, the focus gets
sent back with
thisform.oErrorCtl.SetFocus()


Is there a better way?

Sincerely,

Gene Wirchenko
Bernhard Sander
2013-01-29 12:59:55 UTC
Permalink
Hi Gene,
Post by Gene Wirchenko
I have used Valid for validation in my app since the beginning. I
would now like to change it over to using LostFocus since I can not
SetFocus when there is a Valid being executed.
What is a good way of doing this?
I have come up with something that works, but it is a kludge.
I can catch the error easily enough, but there is the issue of
how to keep the focus in the control with the error.
I have a form property (.oErrorCtl) for the last error control.
.oErrorCtl is initialised to .null. in the form's .init().
For a given control, if validation succeeds, .oErrorCtl is set to
.null..
For a given control, if validation fails, .oErrorCtl is set to
this (which is the error control) and the event processing continues
(which gives focus to the next control). In the .GotFocus() of the
next control, .oErrorCtl is checked if it is not null, the focus gets
sent back with
thisform.oErrorCtl.SetFocus()
Is there a better way?
I think there is.
The valid event processes a return value.
I've used this feature already in Fox/DOS to implement a "geographical"
navigation in a form, i.e. if the user presse Up, then focus does not go to the
previous control (which is may be left of the active control) but to the control
above the active control etc.

a) logical value:
.T. : validation was ok and focus advandes to the next control
This is the normal behaviour if there is no RETURN statement in the valid
routine, since foxpro returns .T. from any function without return statement.
.F.: validation was not ok, focus stays in this control and an error message
appears (this at least was the case in old fox dos)

b) numerical value:
If it is 0, then focus stays in the control. Nothing else (like error message)
happens-
If it is a positive number, focus advances this number of controls in activation
order.
If it is a negative number, focus goes back this number of controls.
When the absolute value of the number is larger than there are controls, then
focus advandes to the first respectively last control in activation order (or
maybe an error occurs, I don't remember exactly)

c) object name
simply the name of an object, not a string!
If that control exists, focus goes to that control.

Have a look at "Valid event" and "Return" in the help file.
Just have a try since the explanation in the help is quite poor.

Regards

Bernhard Sander
Gene Wirchenko
2013-01-29 18:30:33 UTC
Permalink
On Tue, 29 Jan 2013 13:59:55 +0100, Bernhard Sander <***@kein.spam>
wrote:

[snip]
Post by Bernhard Sander
Have a look at "Valid event" and "Return" in the help file.
Just have a try since the explanation in the help is quite poor.
I know how Valid works. I have been using it for over a decade.

The problem is that you can not have more than one Valid method
in the execution chain. That is why some moved to using LostFocus. I
have nested forms sometimes and would like to have validation on the
nested form.

Sincerely,

Gene Wirchenko
Post by Bernhard Sander
Regards
Bernhard Sander
Dan Freeman
2013-01-29 18:11:56 UTC
Permalink
Post by Gene Wirchenko
I have used Valid for validation in my app since the beginning. I
would now like to change it over to using LostFocus since I can not
SetFocus when there is a Valid being executed.
I think this is wrong-headed. It isn't one or the other.

In the old days, we used Valid for *both* validation and navigation
because it's the only thing we had.

Now they're separate acts that mean different things. Valid determines
whether or not focus is allowed to leave the current control. Lostfocus
happens after focus has left the control, implying that validation has
been satisfied, and allows you to interfere in normal tab order.

If you need your validation to move focus to (for example) the previous
control, then RETURN -1 in the Valid method, but it's still an act of
validation.

They're really very different conditions and using one for the other's
purpose seems like you're swimming against the tide. You wouldn't use
Click() to handle a Keypress().

Dan
Gene Wirchenko
2013-01-29 23:07:57 UTC
Permalink
On Tue, 29 Jan 2013 10:11:56 -0800, Dan Freeman <***@dfapam.com>
wrote:

[snip]
Post by Dan Freeman
They're really very different conditions and using one for the other's
purpose seems like you're swimming against the tide. You wouldn't use
Click() to handle a Keypress().
It is a limitation of VFP that one can not have a second Valid
being executed while there is another in the call chain. I sometimes
have a Valid being executed and would then like to have validation on
a nested form. I can not do that using Valid. With LostFocus, it is
apparently possible. I want that flexibility. My app would be more
user-friendly.

Sincerely,

Gene Wirchenko
Dan Freeman
2013-01-30 05:50:43 UTC
Permalink
Post by Gene Wirchenko
[snip]
Post by Dan Freeman
They're really very different conditions and using one for the other's
purpose seems like you're swimming against the tide. You wouldn't use
Click() to handle a Keypress().
It is a limitation of VFP that one can not have a second Valid
being executed while there is another in the call chain. I sometimes
have a Valid being executed and would then like to have validation on
a nested form. I can not do that using Valid. With LostFocus, it is
apparently possible. I want that flexibility. My app would be more
user-friendly.
Seems like you're playing convenient semantics games.

In the VFP object model, valid must return before focus can leave a
control. You want to use another control in another VFP container to do
something you're calling validation, and that's fine, but it isn't what
VFP calls validation.

In that case, your previously described observer pattern is appropriate
but all behaviors rightly belong in the observer and not in the object
being observed.

When bypassing VFP's normal tab order processing there won't be any
convenient way to taking advantage of the tab order processing that
you're intentionally bypassing. Full kludge ahead!

Dan
Gene Wirchenko
2013-01-30 20:19:40 UTC
Permalink
Post by Dan Freeman
Post by Gene Wirchenko
[snip]
Post by Dan Freeman
They're really very different conditions and using one for the other's
purpose seems like you're swimming against the tide. You wouldn't use
Click() to handle a Keypress().
It is a limitation of VFP that one can not have a second Valid
being executed while there is another in the call chain. I sometimes
have a Valid being executed and would then like to have validation on
a nested form. I can not do that using Valid. With LostFocus, it is
apparently possible. I want that flexibility. My app would be more
user-friendly.
Seems like you're playing convenient semantics games.
I have no idea what you are talking about.
Post by Dan Freeman
In the VFP object model, valid must return before focus can leave a
control. You want to use another control in another VFP container to do
something you're calling validation, and that's fine, but it isn't what
VFP calls validation.
No. As I stated, the validation is done in the same control's
LostFocus. It is only the SetFocus that is elsewhere.
Post by Dan Freeman
In that case, your previously described observer pattern is appropriate
but all behaviors rightly belong in the observer and not in the object
being observed.
When bypassing VFP's normal tab order processing there won't be any
convenient way to taking advantage of the tab order processing that
you're intentionally bypassing. Full kludge ahead!
Someone else, on ProFox, was nice enough to point out that I
should use nodefault in the LostFocus to cancel the focus change. That
works nicely.

Sincerely,

Gene Wirchenko

Loading...