Quote:If I understand correctly, you want the subform elements to act like they are actually just in the parent record, and not from another database.
No, I want the subform to act as though it
is a parent. The cleanest, most supportable code, would never "know" that it is a subform - just that is a form. To an extent, we've managed this. The form view subforms not only share the same code with main forms, but
are the same code as main forms. There are a handful of exceptions, where a form has to ask itself if it is "parented" - but only a few.
The table view subforms - on the other hand, are not so consistent. This is due to the relationship between a table and a record. Each row represents a record. That means that even very simple navigation in a table view subform can and must generate a large number of events - and communicate with the engine (on the server).
What is important to understand, though, is that this is not a case of dual focus. It is a case of "enter" events running or not.. When a main form is advanced, that qualifies as a "form enter" - little debate. That the focus goes to the appropriate LE when the form advances and causes an LE enter, again - is not widely debated. Because it is the same code as a main form, the subforms also get an enter event while Sesame recursively updates the main and its subs. If we then prevented the LE enter in the subform, we would be inconsistent and the main forms would act different;ly from the subform. This may be convenient, but it is also less predictable - in that same form at different "levels" acts differently depending on that level.
That is really the issue of debate, and has been hotly debated among the developers (and even within this developer). For example - if the main form view form runs form event on advance, then to be consistent, shouldn't each row of the table (as they are the data equal of a single form: one record) also run form enter?
I originally set up the system so that enter and exit event were driven entirely by true focus. But the Q&A community found this to be insufficient. For example - there are several ways to advance a form that don't involve entering the form - such as using the record counter or the command tree. That would allow a form to advance without the form enter event running. The beautiful simple rule - that an enter (real actual, user goes in a form/LE) causes an enter event - did not please the Q&A event advocates. On the other hand, that kind of simplicity has a great deal of appeal in the clarity and predictability of its statement.
But, again for example, using a strict focus model - would also cause the form enter to run if you moused to another application and back into Sesame - on the same form.
So I ended up asking myself a lot of questions: what should happen if the user moves from the command tree to a form they have already been on? What happens if they move from a main form to a subform on that main form? What happens if they move back to the main form from the subform? What happens if they advance the main form, and thereby advance the sub-sub-sub-form? Etc.. Then I looked at the events coming in from the actual GUI, the windows and widgets, and tried to reconcile the several hundred possible events with the several thousand possible navigational cases.
I am not trying to offer excuses, and we will do what we can to remedy any anomalies found - but, I would recommend that whenever programming in any GUI environment (not just Sesame), that you adopt the practice of "state programming". That means you check and maintain the state of your data - as opposed to reacting to the user or events.
The reasoning behind this is obvious if you have an especially "twitchy" user, who, without regard, clicks on fields repetitively and unpredicatbly with the mouse, or taps on PgUp / PgDn nervously. Or, worse, presses F9 / F10 over and over again - for fun.
In any GUI environment, the user has a random access device - the mouse. Even in Q&A, you can use a "goto" and attempt to lock the user into a field - but the mouse will always let them out. And the more extreme the attempt to control the user, the further they will go to extremes to do what they think they want to do, even if it is not the right thing to do. The more extreme the actions of the user, the more likely they are to make extreme mistakes. One of the most common examples of this is the "strict phone number" template. If a designer deploys the usual ten digit template (###) ###-####, it is only a matter of time before extensions and international numbers start showing up in other fields.
In "state programming" the designer attempts to react to changes in the data, as opposed to the actions of the user. Lets say for example that you want to increment a value when the user enters a particular LE. But, you know that the user may and will enter that field repetively. If you simply put the increment in the LE enter event, the number will increment without control. But if you protect that increment with a global static variable that indicates that the number has been incremented already (its "state" transitions from unincremented to incremented), then no harm done. You can also then "protect" that LE by saving that number from edits after it has been incremented. That state flag, typically gets cleared when the number is used in calculation. Again, typically, the number, nor the flag are retained.
In state programming the form or forms and each LE (the data as a whole) maintains its "state". It then can transition from any single state to another state - but only after a minimum set of conditions have been met in the data. The designer can make clear the "state" of the data to the user through visual cueing (color, label, position, size, messages, etc...). Each state then enables or allows particular actions to take place, which - in turn, allow the next change of state.
I'm not sure if I've explained this well and I guess I should apologise for blathering on, but it is actually always much simpler than it sounds when explained, and is one of those things that is easier done than said.