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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How best to trap "exit" from controls? Lost Focus? Validate? Other? 3

Status
Not open for further replies.

johnk

MIS
Jun 3, 1999
217
US
I'm starting to work on a sticky issue. We have provided the following functionality in our apps. I'll illustrate with entry of Customer ID on, say, an order entry form.<br>
<br>
Sometimes the enterer knows the ID and is a speed keyer. We provide a text box for that. Frequently the enterer knows only the name. We position another text box (actually a custom control we built) for name beside the one for ID. Our custom control contains a drop down combo and a command button. We have built in &quot;autofill&quot; in the combo. The command button produces a custom search screen.<br>
<br>
When either control is &quot;exited&quot; we fill in the other, then also fill in the default ship-to ID for that customer.<br>
<br>
Our problem is this. There are circumstances one of these controls is exited and we don't &quot;catch&quot; it. Like clicking on a menu item, or on our tool bar. Lost focus doesn't fire because the orig control still has focus. It looks like validate is not the answer since the above don't expose a &quot;causes validation&quot; property. Any other approach we can think of would involve tedious state flags which could be really difficult to maintain.<br>
<br>
Any suggestions would be greatly appreciated.<br>
<p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
If you get rid of the combo box and put 2 or more search boxes on your form you have less headaches and happier end users.<br>
1 to look up by Number, one for Name, one for something else<br>
I've had upto 6.<br>
Then put a find button so if someone types something in any box it will pass a SQL statement to the db and return your results. Then put the results in a datagrid on a form<br>
click the one you want in the datagrid and be done.<br>
<br>
Here is an example on my WEB site.<br>
<A HREF=" TARGET="_new">go to the bottom of the page<br>
I know it's in Access but it works just the same in VB<br>
Access allows you to create it 20 times faster.<br>
I call it &quot;Find It FAST 99&quot;<br>
It finds anything FAST....Data is data. <p> DougP<br><a href=mailto: dposton@universal1.com> dposton@universal1.com</a><br><a href= > </a><br>
 
Hi John,<br>
<br>
Would it be possible to disable the controls that allow your user to exit a control (until you're ready) without it losing focus?<br>
<br>
It's something that's irritated me as well, doesn't seem to be a good general answer to it.<br>
<br>
Mike <p>Mike Lacey<br><a href=mailto:Mike_Lacey@Cargill.Com>Mike_Lacey@Cargill.Com</a><br><a href= Cargill's Corporate Web Site</a><br>
 
Hi John!<br>
<br>
We've seen the &quot;lost exit&quot; problem too. We ended up redesigning the form to not use that 'feature'.<br>
<br>
I would do like Doug said, and have two find fields plus a &quot;Search Now&quot; button. <br>
<br>
I might make an improvement/suggestion in that if you are using MS SQL Server, Oracle or DB2 (i.e. a *real* database), you use the built-in SoundEx SQL function. This is an algorithm from the 1960's that strips vowels and consonents that sound alike out of a string, reducing it to four characters. A similar algorithm is used by the 411 operator to find the telephone listing you asked for.<br>
<br>
Use it like this in your SQL:<br>
&nbsp;&nbsp;&nbsp;&nbsp;SELECT CustomerID, CustomerName, BalanceOwed from CustomerTable where SoundEx(CustomerName)=SoundEx(UsersRequest);<br>
<br>
This is not the fastest query in the world (it will probably end up doing a table scan). You could make it much quicker by adding a column to your table that contained pre-SoundExed key values. Use triggers to make sure that column gets updated every time you update a row, or insert a new row.<br>
<br>
One consequence of this is that you probably won't be getting a single row back. But the rows that you <b>do</b> get back will be very close to what the user wanted, and they can easily choose the one they want, rather than sorting through 20-gazillion rows. But you know your data best, and if there are only going to be 35 customers, this would be overkill :-&gt;<br>
<br>
Chip H.<br>

 
Thanks to all for your considered responses.<br>
<br>
Here is what we have decided to experiment with. Our best solution will come from &quot;knowing&quot; when a specific control has (1) experienced a change in its text property, and (2) the user feels that the control has been exited (even though the control still has focus).<br>
<br>
We will continue to house our &quot;exit&quot; code in the lost focus event. We are a little wary of using the change event. We will add saving of the text property in the got focus event. In each place where user can pass control without lost focus firing (menu selection, clicking on tool bar, clicking on upper right &quot;X&quot;) we will check active control for change in saved text property value. If changed, we will run the lost focus event for that control.<br>
<br>
Any other thoughts would be welcomed. I'll post our test results. <p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
Chip, Mike & Doug,<br>
<br>
I read back through your responses with interest. We too are interested in providing easy-to-use intuitive data finding capabilities. We have developed a universal &quot;scheme&quot; which uses much repetitive code which we have built into our code generators. It includes Universal Query-by-Forms and a Uniform Locate ability.<br>
<br>
Universal Query-by-Forms. All of our forms include a tool bar with our standard icons. One is &quot;Find&quot; which conditions all input controls on the form to accept search criteria. Another is &quot;Find Now&quot; which executes the search by forwarding the search parameters down to an SQL generator which produces code specific to whatever database is used (our code works with all major RDBMS's). Our application programmers need add NO code at all. For example, in order entry this provides for finding all orders for a customer, for finding all orders containing a specific item (or range of items), all unshipped orders for California, etc.<br>
<br>
Uniform Locate ability. We wanted to take this uniform way of finding data a step more by furnishing a uniform way of finding specific values for an entry control (such as finding customer record in OE). We built a Locate module as a class. It responds to parameters and displays a form containing a selection grid (as Doug does). For customers or inventory items this may be a large collection. This form includes an entry text box which can be conditioned to any column in the grid by clicking on the column header (which immediately sorts the grid on that column). Keying into that control causes the grid to position the first row matching keyed characters with each key stroke. A strong advantage of this is that all &quot;Locate&quot; functions work in a uniform and intuitive way, and all with minimal work for the app programmer.<br>
<br>
With all this, our current problem is limited to nailing down just when the user has intended to exit from a control, whether VB thinks so or not. Thanks to Mike for reminding us about disabling controls.<br>
<br>
Just wanted to share back as you shared. Our initial testing of the technique in my previous post has gone well. I'll post the conclusion in a few days.<br>
<p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
Having posted the original question in this thread, I'd like to share where we are with it.<br>
<br>
The problem is that we need an absolutely dependable firing of an event when a control on a form has been &quot;exited&quot;. Using Lost Focus is not a sure thing as user can click on, for example, an icon on our tool bar and lost focus would not fire (right then).<br>
<br>
I have had to divert to other tasks, but here is what I'm thinking of. Use the Validate event instead of Lost Focus. We will turn on Causes Validation property for all other controls on the form which have that property. Here's the tricky part where Causes Validation is not available:<br>
<br>
Add a small text box to each form. Set Visible = False and Causes Validation = True. Everywhere Causes Validation is not available (like Query Unload) code SmallTextBox.GotFocus.<br>
<br>
I'll post more when we test. We may run into unwelcome event firings. Let me know if you can see that I'm off track.<br>
<p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
That looks interesting John - please let us know how well it works.<br>
<br>
Mike<br>
<p>Mike Lacey<br><a href=mailto:Mike_Lacey@Cargill.Com>Mike_Lacey@Cargill.Com</a><br><a href= Cargill's Corporate Web Site</a><br>
 
Well, the approach in my post of 3/15 is not solid enough for us. Setting focus in a hidden control just to fire any pending Validate events, and then immediately setting focus in some visible control just gets messy.<br>
<br>
So here is my next idea. Build a subroutine to hold all logic previously in LostFocus events. Case statements will be used, each having the name of a control as the selector. There are perhaps 10 to 15 places in each of our UI programs that can receive control without causing a LostFocus event to fire - ToolBar icons, menu selections, and Query Unload. In each of these places we will record the name of the control which still has focus, then call the above subroutine using the control name as a parameter.<br>
<br>
If it is a control with no lost focus event, then no Case select will occur.<br>
<br>
As before, I'll post results here of our experience. I'm posting this now in hopes anyone spotting a logic hole would share. It's pretty hard to conclusively test this stuff. <p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
&gt; As before, I'll post results here of our experience. I'm posting this now in hopes anyone spotting a logic hole would share. It's pretty hard to conclusively test this stuff. &lt;<br>
<br>
Good luck, John. I think you will find this approach to be exceedingly difficult to test, as someone (usually a non-programmer) will always find a spot to click on that you didn't account for.<br>
<br>
But, let us know how it goes.<br>
<br>
Chip H.<br>

 
Chip, This event driven world does indeed drive us old character screen heads crazy. Yet, the functionality provided to the user is obviously way beyond the old ways, and is all well worth it.<br>
<br>
I think we have a fighting chance to avoid getting focus for an &quot;unplanned&quot; control because we have very strong standards (enforced, in part, by our code generator) for the use of controls.<br>
<br>
To us, having a sure and certain knowledge that all the expected events have fired is such a fundamental and important issue that we are making this fuss about it. I'll sure report back. <p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
Well, I think we have finally resolved this issue.&nbsp;&nbsp;We don't have enough mileage on it yet to declare victory, but we are already retrofitting some of our work to use it.<br><br>With the usual disclaimer about my lack of current programming knowledge, here's what we are now doing:<br><br>1.&nbsp;&nbsp;In each Lost Focus event replace validation logic with a call to a DoValidation subroutine with the control name as the parameter.&nbsp;&nbsp;(exp. DoValidation txtEntryField).<br><br>2.&nbsp;&nbsp;Create a subroutine (we call it DoValidation).&nbsp;&nbsp;It will house all validation statements that used to reside in Lost Focus of each separate control.&nbsp;&nbsp;It will use one parameter (we call Field).<br><br>Within a Case statement structure, place the validation code that used to reside in the lost focus events.<br><br>So far this just rearranges the placement of the validation code.&nbsp;&nbsp;Next comes why we did this.<br><br>3.&nbsp;&nbsp;Identify everywhere in your form where control can be passed without triggering a LostFocus event in a control.&nbsp;&nbsp;For us this includes ToolBar buttons, Menu items and the QueryUnload event.&nbsp;&nbsp;In each of these add the following code:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;DoValidation FormName.ActiveControl<br><br>4.&nbsp;&nbsp;Since the ActiveControl property will still have the name of the last control that had focus, this will assure that the proper validation will take place.<br><br>I hope anyone who can see where this will cause trouble will respond.<br> <p>John Kisner<br><a href=mailto:jlkisner@jlkisner.com>jlkisner@jlkisner.com</a><br><a href= > </a><br>
 
Thanks John, that's a solid bit of work. <p>Mike<br><a href=mailto:michael.j.lacey@ntlworld.com>michael.j.lacey@ntlworld.com</a><br><a href= Cargill's Corporate Web Site</a><br>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top