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!

Incremental Searching Listbox

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

What is the easiest way to get this behavior... a user starts typing data into a listbox and the listbox automatically populates itself and selects the 1st matching record with matching data as typed and sets the listbox's value property to the selected value and highlights it if it matches.

I have IncrementalSearch set to .T. and have been trying code in the InteractiveChange event to no avail, so I must be missing something here.

Using VFP9sp2...

I've also used this code in an user entry textbox that populates the listbox, but is very inefficient;
.list1.RowSourceType = 3
.list1.RowSource = 'SELECT vendor_id, v_name distinct FROM inv_list WHERE vendor_id = UPPER(ALLTRIM(this.value)) order by vendor_id into cursor curVendor'

The idea here is upon entering the listbox the user starts typing the search term and the listbox incrementally builds a list of matches and when the user is within sight of the intended value they can easily use their arrows to finish selecting the one desired. All this is done without ever switching to the mouse...

Also having an issue showing the 2 fields in the listbox.

Thanks, Stanley
 
Incrementalsearch searches within the list of already bound records and moves within them, so you wouldn't build the list.
An approach perhaps a littel more user friendly is to SET FILTER.

Both the native incrementalsearch and SET FILTER work better with not too long DBFs.

Do you have an index on vendor_id?

Bye, Olaf.


 
Oh, and the query won't work with this.value. The listbox.value is the currently selected item and is empty, if none is selected, also it's not what the user typed. If you want your kind of incremental search you'd add a seperate textbox for the user to enter the begin of the vendor_id.

Bye, Olaf.
 
Hi Olaf,

>> Oh, and the query won't work with this.value. The listbox.value is the currently selected item
>> and is empty, if none is selected, also it's not what the user typed. If you want your kind
>> of incremental search you'd add a seperate textbox for the user to enter the begin of the vendor_id.

Yes I know. I copied those 2 lines from a "with thisform --- endwith" construct, and forgot to add thisform as a prefix to the 2 lines that you picked up on. I was using those 2 lines in the Interactivechange event of a textbox that was taking input from the user and building the cursor for the listbox. That works, but highly in-efficient, as I explained in my opening question.

The behavior I'm trying to achieve is something like this, but first let me show you some data that could be used and you can see why the previous ways are in-efficient. Lets consider we are increm searching vendor names like:

Washington County Auto Parts
Washington County Circuit Clerk
Washington County Judge
Washington County Newspaper
Washington County Radio Station

Behavior wanted is... user tabs into the listbox and starts typing "Wash" and the 1st item that matches "Wash" is shown and selected, with the other "Wash" items in the list to pick from. If the user was going for "Washington County Newspaper", the user would type "Wash" and the down arrow 3 times and it would be selected, then tab to next listbox for a similar experience. Much quicker than typing out "Washington County N"... No switching back and forth from mouse to keyboard.

I need to solve this as the form I'm working on has 4 such listboxes that need this type of behavior.

Thanks,
Stanley
 
Well, that's what incremental search will do, just not select the first, but it'll scroll to it, and instead of continuing to type "...ington" you can simply use downarrow and pick one.
So simply set the rowsource to the inv_list and incrementalsearch .t., activate the listbox and type Wash.

Pay attention to _INCSEEK. If typing slower than 2 keys per second your incremental search starts from scratch again.

Bye, Olaf.
 
Thanks guys.... Exactly what I'm looking for...

Thanks again,
Stanley
 
Dan,

Just once is enough... [URL unfurl="true"]http://www.tomorrowssolutionsllc.com/Conference%20Sessions/Creating%20Helpful%20User%20Interfaces.pdf[/url]

You can see quite a lot of code needed to get it that way compare to just setting incrementalsearch. But if you don't like just the scroll to the searched record instead of filtering and marking/selecting the first item, then you are not alone.

I'd recommend using
rowsourcetype: 6 (FIELDS)
rowsource:inv_list.v_name, vendor_id
incrementalsearch:.t.

set up columncount and columnwidths as needed, maybe you really want to search vendor_id instead of v_name, but that doesn't seem like it, incrementalsearch will always search in the first column. You can bind to the second column, the ID, if there is a vendor_id controlsource that should be set to the user selection.

Then set _incseek=1.5 for the slow typers (it doesn't hinder fast typing, just you have to wait 1.5 to begin searching with the first letter again).

An autocomplete textbox is another solution, true. But it'll not show a list to pick from initially.
A Combobox also offers the same as a listbox, just showing one list item, when collapsed.

Bye, Olaf.
 
OK, instead of using a listbox, I'm using a combo, (uses less screen real estate) but still not getting the behavior I've described. I've not been able to auto expand the combo when the control receives focus and ready to take keystrokes that then starts the increm search. I've also spent some time with Tamar's Quickbooks combo example. It forces mousing, which I'm trying to eliminate the mouse for data entry. The actions are:

1. tab into combo, (the combo auto expands with preferably the last selected item is now selected)
2. start typing, (Incremental search begins, highlighting/selecting whats been typed in so far)
3. ability for user to use up and down arrows as well as page up and down keys to navigate the list,
4. Press enter or tab to leave combo while setting its "DisplayValue" to the selected item.

This makes for a very efficient data entry mechanism.

Thanks,
Stanley
 
Well,

having a clear idea of what you want and what you get easy is two different things. You can surely try to get close to your plan, but it needs some programming.
Things you'll never be able to do is to highlight what has been entered so far in incremental search in all the items, as you can see in eg the URL bar of most browsers.

Anyway, one recommended setting for the combobox is using it with Style=0. Help says this is the default, I'm not so sure.
This let's users type something in the textbox portion, which isn't necessarily an item of the dropdown list, so you can use that as filter, as you did before with the seperate teextbox, just now it's integrated.

Programmatic Dropdown of the combobox can be done two ways referring to MS support: I'd go for the KEYBOARD command.

To let the entered value filter the list the simplest method may be SET FILTER TO field = ALLTRIM(_Screen.Activecontrol.displaytext), also in the gotfocus, perhaps. Cautious, this filter needs to be set to nothing, when the combobox loses focus. Also you can't use THIS or THISFORM, as the scope of the filter expression is neither the control nor the form. Not resetting the filter will tthrow an error, so SET FILTER TO in the combobox.valid event, before it loses focus.

That would be near to your goal, without highlighting the list items.

Bye, Olaf.
 
To auto-drop a combo when the user lands this, put:

KEYBOARD "{Alt+DNARROW}"

in the combo's GotFocus.

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top