Trying To Create Search A ListBox Autocomplete Style

Hi,

I am trying to create an autocomplete type method in which the user types text into a Textbox to search a long list of data in a Listbox and with every Key Stroke the list becomes shorter until only the exact text in the TextBox matches the listbox.

I found an old thread on the RealBasic Forum site that I think was addressing this, but it never was completed. The link was:

http://forums.realsoftware.com/viewtopic.php?f=1&t=23884

What I have is a Textbox called "EditField1 and a Listbox called Listbox1. I put the following code into a method called FindCode

[code] dim value As String = EditField1.Text
Dim I As Integer
dim FoundAt As Integer = -1

FoundAt = -1
for i = 0 to Listbox1.ListCount-1
if Listbox1.List(i) = Value then
FoundAt = i
exit
end
next
if FoundAt >= 0 then
Listbox1.ListIndex = FoundAt
else
Beep
MsgBox “The text “+Chr(34)+Value+Chr(34)+” could not be found.”
end[/code]

I then call the method on the KeyUp event handler. Whatever I type, I get the MsgBox text thats says it could not be found, even though that text is listed in the Listbox.

Does anyone see what I am doing wrong. I remember VB6 used to have an easy way of doing this, but I can’t seem to figure it out for Xojo.

Any help would be greatly appreciated. I would think this would be a handy feature for other developers.

[quote] FoundAt = -1
for i = 0 to Listbox1.ListCount-1
if Listbox1.List(i) = Value then
FoundAt = i
exit
end
next
if FoundAt >= 0 then
Listbox1.ListIndex = FoundAt
else
Beep
MsgBox “The text “+Chr(34)+Value+Chr(34)+” could not be found.”
end [/quote]

try:
if Listbox1.List(i).Left(Value.Len) = Value then
or:
if Listbox1.Cell(i, 0).Left(Value.Len) = Value then

Hi Joachim Kuno,

Thank you for taking the time to help me. Both lines of code worked well. They will highlight the first word that start with the letter you typed into the textbox.

I was just wondering if there was a technique that would make it so it would do the following.

If you had a Listbox with the following list:

About
Able
Apple
Big
Box
Cat
Crow

You typed an ‘A’ into the textbox. Is there a way to reload the listbox so it just shows all the words that begin with ‘A’? And then when you typed a ‘b’ after that to reload the list to just display the words About and Able in the list? That way a long list of data in a listbox can be quickly reduced to just a few choices.

Yes.

  1. Create a subclass of ListBox
  2. Store About, Able, … in a property MyList() of this Class
  3. then

Listbox1.DeleteAllRows

for i = 0 to MyList.Ubound
if MyList(i).Left(Value.Len) = Value then
Listbox1.AddRow MyList(i)
end
next

Hi Joachim,

Now I am a little lost. I only know enough Xojo to be dangerous and have never used subclasses before. So tell me if I am doing this correctly.

  1. In that Window where I created the Listbox1 and EditField1, I added a Class and its called Class1.
  2. Under the Super I selected Control > RectControl > Listbox.

Is that correct so far?

  1. Now I should create a property called MyList? What should be the “Type”? How do I add About, Able? Do I do it:

Listbox1.AddRow "About" Listbox1.AddRow "Able" ???

Do I put this code in the property or in the FindData method of the window?

[code]Listbox1.DeleteAllRows

for i = 0 to MyList.Ubound
if MyList(i).Left(Value.Len) = Value then
Listbox1.AddRow MyList(i)
end
next[/code]

Sorry to ask so many questions. I am just learning some new stuff that I have never used before. I really appreciate you helping me out.

Jim

QuickSample: https://dl.dropboxusercontent.com/u/103694210/Autocomplete.zip

Hi Joachim,

Thank you so much for taking the time to create that sample app. That was extremely helpful and works great. I really appreciate your help.

I have been playing around with it all day and I have one more question, if I may.

I am using Option Buttons to load certain data into the listbox. In the open event of MyListBox I put in this code to load the listbox with the correct data depending on which Option button is set to True.

[code] If frmIncidentTypes.optNumber.Value = True Then
Load100 //Load100 is a method under MyListBox
ElseIf frmIncidentTypes.optType.Value = True Then
Load100R //Load100R is a method under MyListBox
End If

raiseevent Open[/code]

That populates the listbox with the correct list, and works fine.

I also have code so I can toggle between the lists. For instance the optType code is this

MyListBox1.Load100R myListBox1.find ""

That works also, the thing is, how do I clear the contents of the listbox before loading the newlist? What happens when I toggle between the two option buttons is that the new list is added to the end of the old list. It does not erase the old list first.

Using the code

myListBox1.DeleteAllRows does not seem to work.

Do you know a way I can delete the contents of the listbox before refreshing it with the new list?

Again, thanks for all your help.

Jim

redim myList(-1)

myList.append “Alternate Item1”
myList.append “Alternate Item2”
myList.append “Alternate Item3”
myList.append “Alternate Item4”
myList.append “Alternate Item5”

Hi Joachim,

That worked perfectly!!! Thanks so much for all your help, and thanks for posting that small app. I really appreciate it. You’re a lifesaver!!

Jim

Hi Joachim,

I just have one more question.

In your code you have the line adding rows to a ListBox in the first column only. Example:

While Not rs.eof myList.append (rs.Field("Members").StringValue) rs.MoveNext wend

But what if I also wanted to add some more data to a second column in the same Listbox, but just use the first column as autocomplete. If you were just adding data to a normal listbox it would be:

While Not rs.eof
List1.AddRow
List1.Cell(frmEmail.List1.LastIndex,0)= (rs.Field(“Members”).StringValue)
List1.Cell(frmEmail.List1.LastIndex,1)= (rs.Field(“Email”).StringValue)

rs.MoveNext
wend

Is there a way of adding data to the 2 columns and still have the autocomplete code work?

Jim

Autocomplete_v2.zip

dim FoundAt As Integer = -1
FoundAt = -1
You set twice the value to FoundAt
You fill an integer with -1 ?

Why not? Integer (Int32) Range: -2,147,483,648 to 2,147,483,647

Either I completely forgot that or I do not slept enough this night :slight_smile:

In the docs, Integer disappears; they use Int and UInt (and I was probably thinking at UInteger).

But there is still a useless line that set -1 to the Integer…

Joachim thanks so much for taking the time to prepare that project. It worked perfectly. I really appreciate your help. You’re a genius! :slight_smile:

Thanks again.

Hi,

I am a newbie to programming and hence looking for examples…The Autocomplete example above is what I was looking for but I want each row in a listbox to be clickable, for example if I select “Apple” from the list then a external file apple.txt should get open. Searched forum and seems it can be done from celltag/ rowtag but unable to achieve it… Please help…

Listbox with the following list:
About
Able
Apple
Big
Box
Cat
Crow

[quote=43213:@Ram Kapoor]I want each row in a listbox to be clickable, for example if I select “Apple” from the list then a external file apple.txt should get open. Searched forum and seems it can be done from celltag/ rowtag but unable to achieve it… Please help…

[/quote]
Try the CellClick event and use the row and column parameters with an array of data. Then use the value in the array to open the file.