Filtering tableView rows..

Hi!

I have a tableView with rows, and a search box. Below is my code for inserting the rows into my tableView. I am trying to match the beginning few characters of my data with my search box input (which works great) but then only show rows of data that match the search. As you can see below, even if the words match, ALL my data is inserted into the table, and therefore not being filtered. The required logic is: Find the strings that match, and insert the correctly identified rows/data ONLY if the beginning characters match. Any advice on how to do this? I can’t seem to get my head around this. 

Thanks!

====

function flavorFunc88(table)

for i = 1, #table do

if( isFiltered == false ) and ( string.find( collection:sub(1,3), theCollection:sub(1,3)) ) then

   backgroundSearch:insertRow{

      rowHeight = 60,

      isCategory = false,

      rowColor = { 1, 1, 1 },

      lineColor = { 0.90, 0.90, 0.90 },

      params = {

         name = table[i].name,

        objectId = table[i].objectId

         – phone = myData[i].phone

      }

   }

end

end

 return flavorFunc88

end

=====

Maybe I’m misunderstanding your problem, but in your sample code it doesn’t look like all of your data would be inserted into the table.

The entire data set is being looped through, but backgroundSearch:insertRow is inside an if statement which will only return values if string.find manages to find the pattern you’ve specified.

I am slightly confused as to why this function appears to return itself though:

function flavorFunc88(table) ... return flavorFunc88 end

Honestly, the easiest thing to do is to destroy the tableView and recreate it, inserting only the records you care about. It will be fast enough it will happen in a single frame update, so there won’t be any blinking.

Admin note: Please do not post your question twice and particularly intentionally to the wrong forum.

i have tried to do that but just can’t get my head around it. Can you offer some sample code please?

Ps, I apologise for posting twice… Won’t happen again

Just so happens I’m working on a new business oriented sample app that lets you select locations from a search box. It’s not quite 100% what you’re looking for, but it’s close:

-- This function will generate the searchTableView from scratch. We don't want the -- tableView until we have a reason to search for it, so create it on the fly. It -- will be destroyed above when something is selcted but if it's not clean it up first. local function displayHits( ) -- if the tableView exists, destroy it if searchTableView then searchTableView:removeSelf() searchTableView = nil end -- create a new tableView searchTableView = widget.newTableView({ left = 20, top = locationEntryField.y + 15, height = display.actualContentHeight - locationEntryField.y - 65, width = display.actualContentWidth - 40, onRowRender = onSearchRowRender, onRowTouch = onSearchRowTouch, }) -- Loop over the locationChoices table which has the matched records from the -- database and insert the rows into the table. We need to also pass in the -- latitude and longitude as well for when we add an entry to the user's location -- table. local isCategory = false local rowHeight = 40 local rowColor = { default=theme.rowBackgroundColor, over=theme.rowBackgroundColor } local lineColor = { 0.5, 0.5, 0.5 } print("Before inserting rows into tableView") local t = system.getTimer() for i = 1, #locationChoices do print( locationChoices[i].name) searchTableView:insertRow({ isCategory = isCategory, rowHeight = rowHeight, rowColor = rowColor, lineColor = lineColor, params = { name = locationChoices[i].name, latitude = locationChoices[i].latitude, longitude = locationChoices[i].longitude, id = i }, }) end print("After inserting rows into tableView", system.getTimer() - t) end

-- Look up a string in the sqlite database. Return a list of matched locations. This is called -- from the text entry field's event handler. local function lookupCity( address ) table.remove( locationChoices ) locationChoices = nil locationChoices = {} print("Before Query" ) local t = system.getTimer( ) for row in myData.db:nrows("SELECT \* FROM cities WHERE LOWER(city) LIKE '" .. address .. "%' ORDER BY city") do locationChoices[#locationChoices + 1] = { name = row.city, latitude = row.latitude, longitude = row.longitude } print(row.city) end print("After Query", system.getTimer() - t) if #locationChoices \<= 100 then displayHits() end end

-- handle the user input --local hasFetchedLocationList = false local function fieldHandler( textField ) return function( event ) print( event.phase, textField().text ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- Since we are just starting to type, indicate we haven't done a DB lookup yet. --hasFetchedLocationList = false elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field elseif ( "editing" == event.phase ) then -- don't query the database for one or two letters. if string.len( textField().text ) \> 2 then lookupCity( textField().text ) else if searchTableView then searchTableView:removeSelf() searchTableView = nil end end elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard -- There are two ways to select the location. Tapping the table row, or hitting the submit/enter key. -- This handles the enter key scenerio. print( textField().text ) lookupCity( textField().text ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end

I have a native new text field and in it, I look to see if I have a string 3 characters or more (> 2). Since I don’t want to return thousands of places that start with the  letter ‘s’. Once I have the 3 letters or more, I query the database by calling lookupCity( address ). This query’s the database and gets a list of locations that match the first N letters. I produce a table named “locationChoices” which holds all of the returned locations and then I call displayHits(). Display hits kills an existing tableView and recreates it. Then I insert records for each item in locationChoices. Each time the user types a letter, I repeat the process. Finally if they hit the enter on the keyboard it will also do a search. Now I had to put a limit on the search. Do you know how many records I pulled back that started with “San”? There is a that that says if I have more than 100 items, don’t build the table. This makes the user type more to get to a reasonable amount of hits. 100 may still be too many. No one is going to scroll through that many (at least not for my use).

Thank you!!! That was EXTREMELY helpful! Just implemented and it all works great!!! You are a star!

Maybe I’m misunderstanding your problem, but in your sample code it doesn’t look like all of your data would be inserted into the table.

The entire data set is being looped through, but backgroundSearch:insertRow is inside an if statement which will only return values if string.find manages to find the pattern you’ve specified.

I am slightly confused as to why this function appears to return itself though:

function flavorFunc88(table) ... return flavorFunc88 end

Honestly, the easiest thing to do is to destroy the tableView and recreate it, inserting only the records you care about. It will be fast enough it will happen in a single frame update, so there won’t be any blinking.

Admin note: Please do not post your question twice and particularly intentionally to the wrong forum.

i have tried to do that but just can’t get my head around it. Can you offer some sample code please?

Ps, I apologise for posting twice… Won’t happen again

Just so happens I’m working on a new business oriented sample app that lets you select locations from a search box. It’s not quite 100% what you’re looking for, but it’s close:

-- This function will generate the searchTableView from scratch. We don't want the -- tableView until we have a reason to search for it, so create it on the fly. It -- will be destroyed above when something is selcted but if it's not clean it up first. local function displayHits( ) -- if the tableView exists, destroy it if searchTableView then searchTableView:removeSelf() searchTableView = nil end -- create a new tableView searchTableView = widget.newTableView({ left = 20, top = locationEntryField.y + 15, height = display.actualContentHeight - locationEntryField.y - 65, width = display.actualContentWidth - 40, onRowRender = onSearchRowRender, onRowTouch = onSearchRowTouch, }) -- Loop over the locationChoices table which has the matched records from the -- database and insert the rows into the table. We need to also pass in the -- latitude and longitude as well for when we add an entry to the user's location -- table. local isCategory = false local rowHeight = 40 local rowColor = { default=theme.rowBackgroundColor, over=theme.rowBackgroundColor } local lineColor = { 0.5, 0.5, 0.5 } print("Before inserting rows into tableView") local t = system.getTimer() for i = 1, #locationChoices do print( locationChoices[i].name) searchTableView:insertRow({ isCategory = isCategory, rowHeight = rowHeight, rowColor = rowColor, lineColor = lineColor, params = { name = locationChoices[i].name, latitude = locationChoices[i].latitude, longitude = locationChoices[i].longitude, id = i }, }) end print("After inserting rows into tableView", system.getTimer() - t) end

-- Look up a string in the sqlite database. Return a list of matched locations. This is called -- from the text entry field's event handler. local function lookupCity( address ) table.remove( locationChoices ) locationChoices = nil locationChoices = {} print("Before Query" ) local t = system.getTimer( ) for row in myData.db:nrows("SELECT \* FROM cities WHERE LOWER(city) LIKE '" .. address .. "%' ORDER BY city") do locationChoices[#locationChoices + 1] = { name = row.city, latitude = row.latitude, longitude = row.longitude } print(row.city) end print("After Query", system.getTimer() - t) if #locationChoices \<= 100 then displayHits() end end

-- handle the user input --local hasFetchedLocationList = false local function fieldHandler( textField ) return function( event ) print( event.phase, textField().text ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- Since we are just starting to type, indicate we haven't done a DB lookup yet. --hasFetchedLocationList = false elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field elseif ( "editing" == event.phase ) then -- don't query the database for one or two letters. if string.len( textField().text ) \> 2 then lookupCity( textField().text ) else if searchTableView then searchTableView:removeSelf() searchTableView = nil end end elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard -- There are two ways to select the location. Tapping the table row, or hitting the submit/enter key. -- This handles the enter key scenerio. print( textField().text ) lookupCity( textField().text ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end

I have a native new text field and in it, I look to see if I have a string 3 characters or more (> 2). Since I don’t want to return thousands of places that start with the  letter ‘s’. Once I have the 3 letters or more, I query the database by calling lookupCity( address ). This query’s the database and gets a list of locations that match the first N letters. I produce a table named “locationChoices” which holds all of the returned locations and then I call displayHits(). Display hits kills an existing tableView and recreates it. Then I insert records for each item in locationChoices. Each time the user types a letter, I repeat the process. Finally if they hit the enter on the keyboard it will also do a search. Now I had to put a limit on the search. Do you know how many records I pulled back that started with “San”? There is a that that says if I have more than 100 items, don’t build the table. This makes the user type more to get to a reasonable amount of hits. 100 may still be too many. No one is going to scroll through that many (at least not for my use).

Thank you!!! That was EXTREMELY helpful! Just implemented and it all works great!!! You are a star!