B4J Question FocusChanged hell...

Robert Maguire

Member
Licensed User
Longtime User
Hi All,

I'm returning to B4J after a number of years of doing other things (not coding) and thoroughly enjoying it with one exception, the FocusChanged event.

I'm writing a fairly standard style of desktop app that stores data in a SQLite database and is presented in a number of forms using textfields, comboboxes, etc. Nothing fancy. And yes... I'm using the standard B4J views, not the B4X ones (call me dinosaur).

My issue is this... I fetch a row from the database and populate three textviews on the form, which also has a 'Save' and 'Cancel' button. I want each field to be validated if the User presses Enter (Action) or tabs to another field (FocusChanged). If, however, validation of the field fails I want to show an error message (fx.MsgBox) and keep focus on the Invalid field.

This is not an issue with the Action event, obviously. The problem comes with FocusChanged... If you tab off (FocusChanged lost) a field and validation fails then a MsgBox is displayed but Clicking OK to dismiss it causes a FocusChanged event as well and trying to set the focus back to the invalid field starts to become unmanageable.

Similarly, if 'Cancel' is pressed and the field is invalid, I don't want to display the MsgBox error because the form is closed and we're not saving the record.

If 'Save' is pressed then I want to show the MsgBox error and return focus to the invalid field.

Does anybody have a remedy for this... like swallowing/cancelling subsequent (unwanted) FocusChanged events or some other UI error navigation management pattern?


Update: But in the meantime I have preserved my sanity by changing the app so that if a field fails validation the msgbox is displayed and the border colour is changed to red and NOT attempting to alter the focus programmatically.

I'd still like to know if anyone has a solution for diverting focus without causing unintentional FocusChanged events...
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Unrelated tip: use XUI.Msgbox. Same feature but cross platform.
If, however, validation of the field fails I want to show an error message (fx.MsgBox) and keep focus on the Invalid field.

Showing a msgbox and forcing the focus back, when the user switches to a different view is likely to result in a bad user experience. In the days of MS Access such behavior was common and it was indeed very annoying from the user perspective. It is much better to show that the field is invalid.
 
Upvote 0

Robert Maguire

Member
Licensed User
Longtime User
Thanks for the reply Erel... and yes it used to drive me insane in MS Access as well.

Will XUI.Msgbox behave differently in terms of causing FocusChanged to fire?

The reason I ask is because I don't need cross-platform capability, this app is simply for me and at the moment I kind of like vanilla.
I have reverted to validating without trying to control focus in any way, except when initially loading values from the database (because they are valid by default). Unfortunately I still get FocusChanged double validating because clicking OK on the MsgBox causes another FocusChanged event to fire...

I should add that Validation only occurs in FocusChanged when HasFocus is false (indicating that we're leaving the field).

I thought about swapping MsgBox for a timed Toast message box and I might try that but I feel that is a bit of a cop out, i.e. The app controlling me and not me controlling the app.

Thanks again... happy to hear any further advice you might have.
 
Upvote 0

Robert Maguire

Member
Licensed User
Longtime User
So... following on from Erel's points above I removed all code that attempts to guide the User based on field validation (i.e. no more RequestFocus to stay on an invalid field).
Instead I have opted to change the border colour of invalid fields to red and disable the Save button/menuitem if there are any invalid fields.
The other change is to show error messages via a toast popup (cutils.ShowNotification2), which doesn't force a FocusChange event on the invalid field (which was causing a second redundant validation check).
Upshot... the code is somewhat simpler, database integrity is preserved and the User is notified visually as well as textually that field(s) are invalid.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…