Trying to create search box to work with Table View. Need some Help...

Hey guys,
Been working on a project for the past year or so and it’s finally near completion. One last thing I wanted to do was to add search functionality to the table that I have (it’s an array of about 500 items, each with about 30 different data descriptions. i.e. data[1].drink = coffee, data[1].temp=hot, etc) the program mixes a bit of director, table view, and tabbar together.

Ok, so on to the problem.

I want to be able to search the table using a text field and output a tableview of relevant data. I.E. if the user searches for cof, Coffee, coffee ice cream, Coffin, etc will show up. For the purposes of my above array, I would only need to search all 500 of the data[x].drink arrays.

Thanks to the awesomeness of this community, I’ve managed to get this far:

local searchBox = native.newTextField( 200, 5, 600, 80,fieldHandler )
searchBox:setReferencePoint(display.CenterReferencePoint);
searchBox.isEditable = true;
searchBox.text = “”;
searchBox.size = 50;
local fieldHandler = function( event )
print( event.phase )
if “began” == event.phase then
– NOT SURE what to put here
searchBox.text = “”;
elseif “editing” == event.phase then
elseif “ended” == event.phase then
– NOT SURE what to put here
native.setKeyboardFocus( nil )

elseif “submitted” == event.phase then
– NOT SURE what to put here
native.setKeyboardFocus( nil )
end
end
Any advice on how to fill in the blanks would be much appreciated. Your E-Karma will be vastly increased. [import]uid: 77043 topic_id: 31396 reply_id: 331396[/import]

Quickest way I can think of – throw all your drinks into a database and pull from there to fill your tableView. That way when you do a search you can just do something like:

sql = “select * from drinks where name like ‘%iced%’ or description like ‘%iced%’”

That should bring back a list of all iced drinks that you can then display in the tableView.

The database is your friend for something like this. And lots of other things. :slight_smile:

Jay
[import]uid: 9440 topic_id: 31396 reply_id: 125495[/import]

Since you already are creating a tableview, why not just include/process the filter term when you normally create the rows (your existng tableView code)? If the filter text is empty (no search entry by user), then just show all the data when you build the tableView (as you are now)…

The actual test as to whether to include the row in the tableView or not is just a simple string search, which looks kinda like this:

local isFiltered = false  
  
 if( filterText ~= "" ) then -- Don't filter if filterText is empty.  
 if( string.find(string.lower( myRow.title ) , string.lower( filterText ) ) then   
 isFiltered = false -- Don't filter this one out, we found the string.  
 else  
 isFiltered = true -- Filter it out, search term is not in the string.  
 end  
 end  
  
 if( isFiltered == false ) then  
 -- Now we add the row to the tableview, if not filtered  
 end   

Note that if you want to just keep re-using the same tableView, there’s a deleteAllRows function (or you could just kill the old one, and create a new one each time it’s re-filtered, I suppose). [import]uid: 79933 topic_id: 31396 reply_id: 125496[/import]

Thanks for the quick reply! I thought about this, but unfortunately I have no experience with databases. my table is also about 16000 lines of code, so I’m not sure how long it would take for me to convert it to a database. [import]uid: 77043 topic_id: 31396 reply_id: 125575[/import]

Mpappas, thanks for the code snippet!

This theory behind this seems like it would work, but I’m still not sure how to take the text that is inputted into the text field and store it as filterText.
(I’m assuming filterText, for the purpose of your example, is the text taken from the search box)

would something like this work:

local fieldHandler = function( getObj )
print( event.phase )
if “began” == event.phase then
searchBox.text = “”;
elseif “editing” == event.phase then
elseif “ended” == event.phase then

native.setKeyboardFocus( nil )

elseif “submitted” == event.phase then

searchBox.text = tostring(getobj().text)

native.setKeyboardFocus( nil )
end
end
I normally can fingure these kinds of things out through trial and error, but I’m building for android on a PC and the PC simulator can’t handle native text fields. This means I have to build and transfer the app every time I want to test. Also, since I’m using director, it’s tough to trouble shoot why the code isn’t working as the simulator gives me a general error when trying to open the file. Again, thanks for all the help! [import]uid: 77043 topic_id: 31396 reply_id: 125581[/import]

If your text input variable is a global, just reference that directly in place of filterText. So, yes something like your searchBox.text = statement in the submitted state would be the idea (once input is complete, save off the text).

As far as inputting a user text field nicely… Your code above looks kinda lite…

Corona is a bit clunky for text input. I probably spent a good week getting my text input working well cross platform – a lot of details to manage directly (field size, input length, dealing with special chars, etc)

If your looking for something that already exists to handle the text input, the corona Code Exchange probably has something pre-rolled you can copy into your project… Once you have the input working, save the text off (as you outline aboce) and then do the filter process I outlined above in your tableView create function. [import]uid: 79933 topic_id: 31396 reply_id: 125590[/import]

Quickest way I can think of – throw all your drinks into a database and pull from there to fill your tableView. That way when you do a search you can just do something like:

sql = “select * from drinks where name like ‘%iced%’ or description like ‘%iced%’”

That should bring back a list of all iced drinks that you can then display in the tableView.

The database is your friend for something like this. And lots of other things. :slight_smile:

Jay
[import]uid: 9440 topic_id: 31396 reply_id: 125495[/import]

Since you already are creating a tableview, why not just include/process the filter term when you normally create the rows (your existng tableView code)? If the filter text is empty (no search entry by user), then just show all the data when you build the tableView (as you are now)…

The actual test as to whether to include the row in the tableView or not is just a simple string search, which looks kinda like this:

local isFiltered = false  
  
 if( filterText ~= "" ) then -- Don't filter if filterText is empty.  
 if( string.find(string.lower( myRow.title ) , string.lower( filterText ) ) then   
 isFiltered = false -- Don't filter this one out, we found the string.  
 else  
 isFiltered = true -- Filter it out, search term is not in the string.  
 end  
 end  
  
 if( isFiltered == false ) then  
 -- Now we add the row to the tableview, if not filtered  
 end   

Note that if you want to just keep re-using the same tableView, there’s a deleteAllRows function (or you could just kill the old one, and create a new one each time it’s re-filtered, I suppose). [import]uid: 79933 topic_id: 31396 reply_id: 125496[/import]

Thanks for the quick reply! I thought about this, but unfortunately I have no experience with databases. my table is also about 16000 lines of code, so I’m not sure how long it would take for me to convert it to a database. [import]uid: 77043 topic_id: 31396 reply_id: 125575[/import]

Mpappas, thanks for the code snippet!

This theory behind this seems like it would work, but I’m still not sure how to take the text that is inputted into the text field and store it as filterText.
(I’m assuming filterText, for the purpose of your example, is the text taken from the search box)

would something like this work:

local fieldHandler = function( getObj )
print( event.phase )
if “began” == event.phase then
searchBox.text = “”;
elseif “editing” == event.phase then
elseif “ended” == event.phase then

native.setKeyboardFocus( nil )

elseif “submitted” == event.phase then

searchBox.text = tostring(getobj().text)

native.setKeyboardFocus( nil )
end
end
I normally can fingure these kinds of things out through trial and error, but I’m building for android on a PC and the PC simulator can’t handle native text fields. This means I have to build and transfer the app every time I want to test. Also, since I’m using director, it’s tough to trouble shoot why the code isn’t working as the simulator gives me a general error when trying to open the file. Again, thanks for all the help! [import]uid: 77043 topic_id: 31396 reply_id: 125581[/import]

If your text input variable is a global, just reference that directly in place of filterText. So, yes something like your searchBox.text = statement in the submitted state would be the idea (once input is complete, save off the text).

As far as inputting a user text field nicely… Your code above looks kinda lite…

Corona is a bit clunky for text input. I probably spent a good week getting my text input working well cross platform – a lot of details to manage directly (field size, input length, dealing with special chars, etc)

If your looking for something that already exists to handle the text input, the corona Code Exchange probably has something pre-rolled you can copy into your project… Once you have the input working, save the text off (as you outline aboce) and then do the filter process I outlined above in your tableView create function. [import]uid: 79933 topic_id: 31396 reply_id: 125590[/import]

I’m finally finding my way back to the search functionality and have made major headway thanks to your advice. The search almost works, but it stops searching once isFiltered gets returned as true. I’m thinking I need to add an else statement to tell the list to continue, but I’m not having much luck. Any advice? Again, thank you so much for the help. [import]uid: 77043 topic_id: 31396 reply_id: 143116[/import]

I’m finally finding my way back to the search functionality and have made major headway thanks to your advice. The search almost works, but it stops searching once isFiltered gets returned as true. I’m thinking I need to add an else statement to tell the list to continue, but I’m not having much luck. Any advice? Again, thank you so much for the help. [import]uid: 77043 topic_id: 31396 reply_id: 143116[/import]

I’m finally finding my way back to the search functionality and have made major headway thanks to your advice. The search almost works, but it stops searching once isFiltered gets returned as true. I’m thinking I need to add an else statement to tell the list to continue, but I’m not having much luck. Any advice? Again, thank you so much for the help. [import]uid: 77043 topic_id: 31396 reply_id: 143116[/import]

I’m finally finding my way back to the search functionality and have made major headway thanks to your advice. The search almost works, but it stops searching once isFiltered gets returned as true. I’m thinking I need to add an else statement to tell the list to continue, but I’m not having much luck. Any advice? Again, thank you so much for the help. [import]uid: 77043 topic_id: 31396 reply_id: 143116[/import]