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

Drop-down Combo – starting at a specified key

Status
Not open for further replies.

AndrewMozley

Programmer
Oct 15, 2005
621
GB
I have a table of product codes (ordered by field Prod) and have placed a drop-down combo on a form so that the user can key in a partial key, so that when he opens up the combo he can select from the range of products beginning with that partial key. The properties of the combo are :

Style =0; Rowsource Type = 6 (Fields); Rowsource = “Product.Prod,Description”; Format = “!
I have SET EXACT OFF

If I key in a full product code, say “P12” into the combo and open it up, the drop-down does indeed show a list of products P12, P33, P304 . . If however I key in a partial code “P”, then I am given the list of products starting at the first product, B01.

In this second case I would like the list to show P01, P02, P09 &c, so starting at the next product after the “P” that I have entered. How do I do that?

A second matter is that the drop-down shown does indeed show the product and description, but the dividing vertical bar shows as a jagged line. Can I get this to be a straight vertical line while still using a proportional font (Arial)?

Thanks. Andrew
 
Andrew,

Have you got the combo's IncrementalSearch property set to .T.? Does that do what you want? You will also need to set the Style property to 2, not 0.

Re your second question, set the combo's ColumnWidths property. This needs to contain a comma-delimited list of the widths of the columns, in pixels. In this case, it might be something like 25,100.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Mike

Spot on on the Column widths query. Thanks (I had forgotten that).

No joy yet on displaying records from a specified point. In fact Incremental search was already .T., by default. I have also SET NEAR ON.

One other oddity is that if I enter A into the combo and press Enter, it just goes to the next control; I thought that it would open up the combo, but to do that I have to press on the arrow on the right. Is that normal?
 
It seems you have the combobox in style=0 (Dropdown combo). Then the combobox is two controls in one, a textbox and a dropdown list. Entering anything into the textbox portion doesn't cause incremental search.

If you set the combobox style=2 the incremental search kicks in. The disadvantage in the dropdown list mode is you don't see the partial value entered and you have to be fast, two chars entered with a pause longer than what you set _incseek.

There is no way to combine this native in a mode taking the text for incremental search, but you could of course use the interactive change to locate for product.prod = this.text

The combobox in Dropdown combo style hasn't a native link of text and value, because you can have many different uses for that control, one time use the text for filtering the list, at other times to add an entered value to the list, so how you link the two controls of this two-in-one control is not implemented in the base class and left up to you, the developer.

Bye, Olaf.

 
Andrew,

As I mentioned - and as Olaf confirmed - you need to set the Style property to 2 in order for IncrementalSearch to work.

Actually, it does work with Style = 0, but only when the drop-down portion of the control is open. So another option would be to leave the Style set to 0, and to programmatically open the drop-down by issuing [tt]KEYBOARD '{ALT+DNARROW}'[/tt], perhaps in the GotFocus.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike,

I see, that works. But still the disadvantage is any char entered will not only move to the first record starting with it, it'll also become the value of the textbox portion. You can continue typing and incremental search will continue incremental as it should, but you can't see what you type, you can't type as slow as you want and you can't DEL one char, if you mistyped.

A textbox with autocomplete will perhaps fit better to your needs, Andrew.

Bye, Olaf.
 
But still the disadvantage is any char entered will not only move to the first record starting with it, it'll also become the value of the textbox portion.

I agree. It's not an approach I would take myself, but I thought I'd mention it for completeness.

Agree also that an autocomplete textbox might be a better solution. Would that meet your needs, Andrew?

Mike




__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you both very much for your kind and prompt help. I now see that your first reply, Mike, where you said that setting Style = 2 invokes the automatic search - if you are quick enough on the keyboard, does the trick.

What I might also like to do is to take some action after the user keys a value into the text box, which would then open the list and allow me to specify some rule for selecting the record; this would then display the eligible records in the list.

So (Hypothetical example), I might like the user to be able to key #G into the text box, whereupon the list is opened, and only Green products are shown in the list, and then scroll and click on one of them.

To elaborate, I might like to execute code such as :
Code:
SET FILTER TO “GREEN” $ UPPER(Prod.Description)
. . . and then have the combo list filled with relevant records from which he can click on the one he wants.

How can I detect that the user has pressed the enter or tab key after keying #G, and what method should I invoke to cause the list to be displayed?
 
Actually you already have the partial answers.

1. [pre]InteractiveChange[/pre] is the event after each keypress, also there is the [pre]KeyPress[/pre] event, you'd check [pre]IF LASTKEY()=13[/pre] to react to ENTER or RETURN and then check [pre]Combobox.Text[/pre] for the value entered.
2. [pre]KEYBOARD '{ALT+DNARROW}'[/pre]

Bye, Olaf.
 
setting Style = 2 invokes the automatic search - if you are quick enough on the keyboard

If your users complain that they need more time to enter the keystrokes, consider increasing the value of _INCSEEK. See the Help page for more details.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Yes, I also already mentioned _INCSEEK. Still you don't have a visual feedback of what you entered so far and using some shorthand code like #G, though no product has that code and it's expanded to GREEN, you'd need your own incremental search code anyway, using Interactivechange.

Bye, Olaf.
 
Olaf said:
I also already mentioned _INCSEEK

So you did. I didn't notice.

Andrew said:
So (Hypothetical example), I might like the user to be able to key #G into the text box, whereupon the list is opened, and only Green products are shown

Personally, I'm not keen on using special characters in that way, from a user interface point of view. There are bound to be users who don't know - or don't remember - to key a # (or whatever) to achieve that goal. But that's just my personal opinion; I won't insist on it.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Olaf

Your instruction KEYBOARD '{ALT+DNARROW}' can indeed open a list. However if I execute this in the KeyPress() method to pick up the Enter key, focus has already passed to the next control. Am I doing something wrong?

I have reverted to the Combo having Style = 0, so that I can take action when the user enters a partial key, as follows :

(Forgive me, Mike) If he enters a value beginning #, e.g. #GR, I want to open up the list and restrict it to records with “GR” in the description. Otherwise I want to position the list at the value (say “P12”) that he has entered, and let him scroll up and down the list in the normal way.

This is the code that I have a present. Happy to accept criticism and advice.

Code:
* Method Mycombo.KeyPress()
LPARAMETERS nKeyCode, nShiftAltCtrl
* LOCAL lKey
WITH Thisform
   PUBLIC lKey
   IF LASTKEY() = 13
      lKey = RTRIM(This.DisplayValue)
      IF LEFT(lKey,1) = "#"
         lKey = SUBSTR(lKey,2)
         SET FILTER TO lKey $ UPPER(Prod.Description)
        ELSE
         SEEK lKey
         ENDIF
       KEYBOARD'{ALT+DNARROW}'
      ENDIF
   ENDWITH
RETURN DODEFAULT(nKeyCode, nShiftAltCtrl)

A few issues that I have not yet resolved.

1. In the case of the #GR search, I find that I have to make my filter comparison into a global variable. If I just declare lKey as LOCAL, I get an error message when the DnArrow function is invoked. I feel that I should not burden the environment with PUBLIC variables! Is there any way round this

2. For my attempt at searching from a particular record, where I optimistically execute a SEEK command, this has no effect; the list box still opens starting at the first record. Is there a way (with style = 2) to position at a specified record?

3. As mentioned, the DnArrow key is applied to the next control - so I could only get this technique to work if the combo is the only control on the form.

As always. Andrew
 
Well, TAB and ENTER are default keys to leave a control. To prevent ENTER from leaving the combobox you'd need to return 0 from the VALID event, if LASTKEY()=13, so in Valid do
Code:
IF LASTKEY()=13
   Return 0
ENDIF

If you don't turn off incrementalsearch the combobox will control what record is the current postion, so if you do individial searching turn incrementalsearch off.

Bye, Olaf.
 
I feel that I should not burden the environment with PUBLIC variables! Is there any way round this

Most certainly. Use a custom property. If the combo box behaviour that you are trying to achieve is to be reusable, then the combo should be a custom class, and you would use a custom property of that class for the lKey value. Otherwise, make it a custom property of the form.

However, I can't help feeling that this whole thing is getting much too complicated for what you want to achieve. I would second Olaf's suggestion of using an auto-complete text box instead. Not only is it quite simple to use, it is something users are now very accustomed to seeing in other software products.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top