Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Validating a field; cancelling or closing the form

Status
Not open for further replies.

AndrewMozley

Programmer
Oct 15, 2005
621
GB
The value of a textbox is to be checked. Its Validate() method determines whether control can pass to the next field. There are however buttons for ‘Close’ and ‘Cancel’ on the form; If one of these is clicked the validation is bypassed; instead the user is asked whether he does indeed want to abandon what he was doing; he may also have clicked on the Top RH ‘X’ icon to close the form.

What is the best way of handling this in the Validate() method of the textbox?

At present the MouseEnter() and MouseLeave() methods of the ‘Close’ and ‘Cancel’ buttons can set a flag to say that the user has probably clicked on these buttons, but can one detect that the ‘Form Close’ button has been pressed?

Thanks
 
To detect the "X" icon the title bar,use the form's QueryUnload event. It fires when the user clicks the X, or tries to close the form by any other interactive method (such as closing the entire app or even closing down Windows). You can use the ReleaseType property to determine which of those actions applies.

However, it doesn't fire if you execute the form's Release method from your Close or Cancel button. But I'm puzzled as to how those buttons could get clicked. You seem to be saying that if the Validate detects an error, you want to let the user click a button to cancel the entire operation. But that's not possible. If the validation fails, the user cannot click the button; focus stays with the textbox.

There are other ways of closing the form during a validation. You could provide a Close button on a toolbar, or a Close command in the menu. In both those cases, the validation would by by-passed.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Quicker than a speeding bullet!

Thank you very much for your clear and helpful reply. Andrew M.
 
Andrew,

you should also know the two specific properties of buttons foreseen for the typical window UI guide of having a cancel/revert and OK button: The Cancel property and the Default property of the command button. Read about them and google more about it, you sure find lengthy discussions on how to make use of that.

The valid() method of controls is actually bad in that aspect, as they hinder these default and cancel buttons to react to ESC and ENTER finishing actions in forms.

And the typical solution is to react with LASTKEY() checks. Because once you set a buttons Cacnel=.T. the ESC key isn't only becoming his hotkey triggering it, a user clicking it also causes the ESC key pressed.

Mike is right with toolbar buttons for such functions not having that focus problem, but in the end, I see it wrong to do these kinds of micro validations of every single field. Rather have a central record validation method, not by chance there are table rules on top of field rules in DBFs, so sometimes you can't check a business rule just by looking at one (THIS.Value) value. Of course the valid method of a control can also read other control values and the DBF itself, even other tables data, that's not the problem, the problem is you may get a deadlock situation if a final decision depends on two single field values only making sense in dependence on each other and that can only be decided when they are all entered.

In short single field and control validations often make too early decisions and restrictions. Let a user type what he wants, you're typically buffering all that and can revert it overall, whether that's necessary or you can save the entered data should only be decided on all inputs.

The valid method could also be programmed to set the value back to the initially valid value instead of returning .f. as validation result. And last, not least it helps to have controls which allow a user to only set correct values, eg a calendar control instead of only a textbox.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Andrew, reading through your question again, I'm not sure I understood it the first time.

Are you saying that you want to give the user a way of cancelling a form if a validation check fails?

Or are you saying that you want the opposite: to prevent the cancelling of a form? I think your question could be interpreted either way.

In general, I prefer not to use the Validate event, precisely because it raises this kind of problem. I agree with Olaf that it is better to give the user free run of the form, and do all the validation at the end, at the point where the user requests the data to be saved. That approach is far better from the user interface point of view, in that it doesn't force the user to enter each field correctly before moving to the next. It also means that you can multi-field validation, that is, if Field A meets a certain condition, then Field B must meet a certain condition.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Mike

The field being validated is an account code or a (partial) name which allows the account to be determined.

The field may lose focus if (1) the user presses <Tab>, <Enter> or possibly clicks on the next data entry field> or (2) the user clicks on the <Cancel> or <Close> buttons or maybe on the X icon at the top RH corner.

In both cases the Validate() method fires up, but only in case (1) do we want the field to be validated and other data entry fields like ‘Customer contact’, invoice address to be refreshed. In case (2) the Validate method detects that the user probably does not want the field to be validated, and asks the user to confirm.

Thanks again for your help; it answered my question - very grateful.
 
Yes, you can't prevent the validate method to run, all you can do is detect what caused it with the well known and widely used LASTKEY() inspection.
You have other ways of autocompletion with using VFPs autocomplete features, which offers choices while you type or let autocomplete be triggered by space in interactivechange rather than aiting for the tab to move focus. You also have a series of events occurring and everyone should know that this happens in detail, you have not only Valid but also When(), Gotfocus() and Lostfocus() Clicking is just another meean of focus change, so you also have when in the command button before even Valid of a textbox occurs, you can know the next action is the click of a button this way, setting a status, for example.
I would just avoid using the Valid for any functionality at all. Yes, tab is the usual autocompletion finish, but in VFPs own autocomplete tab also lets you tab to the next control you need to use downarrow to pick one choice and then tab to pick it.

In the end, you want an intelligent reaction to anything that causes valid events, but that's not happening, you have to define it and the way it is you may have solved it inversely by identifying all the other reasons for the focus change.

If you really only want control.valid() to react to tabs with autcomplete, then put that code into IF LASTKEY()=9..ENDIF so it only racts to tabbing. If you then finaly return .T. you have the double function on TAB. and in the else branch you can revert or empty the field and interpret that as cancelling the autocomplete.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Thank you for your wide-ranging comments, Olaf. Although it does not apply in this case, I will investigate the 'Autocomplete' option, which may be useful on another project.

The test for LASTKEY() = 9 comes close to a solution, although I suppose that the user could legitimately have clicked on the next control (another textbox) on the form. Mike’s solution works well.

Thanks again.
 
AndrewMozeley said:
The test for LASTKEY() = 9 comes close to a solution, although I suppose that the user could legitimately have clicked on the next control (another textbox) on the form. Mike’s solution works well.

I think you misunderstood me, I wasn't saying ti make RETURN .T. depend on Lasteky()=9. make the autocomplete functionality of your code depend on it. You alwys Return .T., but only do the autocomplete as reaction to TAB this way. So if y user clicks elsewhere after having started to type, you interpret that as not wanting to complete the autocomplete.

Code:
IF LASTKEY()=9
  * your autocomplete behavior
ELSE
  * revert or drop value behavior
ENDIF
RETURN .T.

This needs no specific code elsewhere. Of course, you still can make use of a toolbar to not change focus and thus not trigger the valid event. In regard to save buttons, this often is the reason for not saving the current controls last change, as only passing valid stores it into the controlsource. That's about the pros and cons.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top