tableView with data example

I am looking for some help building a tableView with the tableView widget where the rows that are in it are rows that call functions when pressed…
Some will load functions that open web page with the systemURL api some will actually load other screens with storyboard with the gotoScene call.

I have tried altering the example but all I get now is a whitescreen.

Any examples that have some working functions would be greatly appreciated.

  • Matt [import]uid: 18783 topic_id: 29205 reply_id: 329205[/import]

widget.newTableView() is something of a bear to get loaded initially since it’s not a single function call.

Realistically what you should do is build the exact bare minimum to construct a working tableView and then build onto it from there. (The API code works but adds some elaboration for “how do I do this?” purposes)

Assuming you have already required in the widget library, here’s what the bare minimum should look like:

[code]local options = { top=display.statusBarHeight } – maybe don’t even need to pass options, but…

– (1) This calls the list into being.
local list = widget.newTableView(options)

– (2) Whenever you touch a row this is called.
local function onRowTouch( event )
local row, rowGroup = event.target, event.view

if event.phase == “press” then
if not row.isCategory then rowGroup.alpha = 0.5; end

elseif event.phase == “release” then

if not row.isCategory then
– reRender property tells row to refresh if still onScreen when content moves
row.reRender = true
end
end

return true
end

– (3) This is called to render each row.
local function onRowRender( event )

end

– (4) This is called to generate the actual list - everything from this for loop is as important as a function.
for i = 1, #numrows do
local rowHeight, rowColor, lineColor, isCategory

– function below is responsible for creating the row
list:insertRow{ onEvent=onRowTouch, onRender=onRowRender, height=rowHeight, isCategory=isCategory, rowColor=rowColor, lineColor=lineColor }
end[/code]

That’s it. You could probably shorten it even more, but it’s not even really functional as is - I’m not sure if this actually works without inserting something into the rows.

Anyway, what you really need to do is feed a table so that “#numrows” bit works. The best way to do this is to actually feed it a table!

[code]-- My favorite colors
local colors = {}
colors[1] = { isCategory=true, name=“Colors List” }
colors[2] = { name=“Purple”, flavor=“Grape” }
colors[3] = { name=“Blue”, flavor=“Mountain Dew” }

– etc…

for i = 1, #colors do
local rowHeight, rowColor, lineColor, isCategory

if colors[i].isCategory then
isCategory = true
rowHeight = 24
elseif colors[i].flavor == “blue” then
rowColor = { 0, 0, 255 }
end

list:insertRow{ onEvent=onRowTouch, onRender=onRowRender, height=rowHeight, isCategory=isCategory, rowColor=rowColor, lineColor=lineColor }
end
[/code]

Why do you want a table with headers done first? Well apart from above (making the for loop really easy), it means you can call from that same table in onRowRender() - it’s just that instead of “i” you can use event.index.

Now to your specific question, you can solve that by:

  1. add functions to that table. For example if you had a function called "showColor(), you could type
colors[3].function = showColor -- just the name, not the ()

And then during on onRowTouch()

if event.phase == "ended" then colors[event.index].function() -- will call the function at that index, so if event.index = 3, then it runs showColor()

(Just keep in mind you would have to declare colours{} before the onRowTouch function or it will come up as nil) [import]uid: 41884 topic_id: 29205 reply_id: 117452[/import]

Awesome. This is very helpful and I will try this with my list in the am. Appreciate the example. [import]uid: 18783 topic_id: 29205 reply_id: 117455[/import]

Ok… so combining what you posted with the example in the api docs… I am now able to see the white tableview area and I get Row #2 and Row #3. I know that this is because the first row is a Category in your example.

How do I make it so that it is not the event.index # but the actual color name being listed? [import]uid: 18783 topic_id: 29205 reply_id: 117565[/import]

Well remember the whole advantage of having a table is that the list and your table are in sync - that is, row 32 in your table is the same as row 32 in the list, and so on.

So if you were adapting the API example, you need to look at onRowRender():

-- onRender listener for the tableView local text = display.newRetinaText( "Row #" .. event.index, 12, 0, "Helvetica-Bold", 18 ) text:setReferencePoint( display.CenterLeftReferencePoint ) text.y = row.height \* 0.5 if not row.isCategory then text.x = 15 text:setTextColor( 0 ) end

Right now, display.newText is going to say “Row #”…something. So you could change that part to this:

local text = display.newRetinaText( colors[event.index].name, 12, 0, "Helvetica-Bold", 18 )

The other thing you can do if you have already declared the text object is to change it.

-- in this case, the text object is literally called text... text.text = "Whatever you want!"

So you could, for example, change what the text says within the “if not row.isCategory” section so it says something else only when the row is not a category.

Just two things to keep in mind:

  1. Whenever you change text, it is a good idea to set the X and Y position of your text again. Changing text basically destroys your reference point.

  2. display.newRetinaText() has been deprecated. You can safely use display.newText() instead. [import]uid: 41884 topic_id: 29205 reply_id: 117615[/import]

sorry to keep bugging you but I have made some big progress with this so far… The only hangup I have is where to place the line you mentioned

  
colors[3].function = showColor -- just the name, not the ()  

I have the category working, the title (name) and I added a subtitle and arrow and all the positioning and it works… just don’t get where to add the .function

thanks in advance [import]uid: 18783 topic_id: 29205 reply_id: 117806[/import]

Depends what you mean?

You call the function by adding this line to onRowTouch(), inside the if event.phase == “ended” section.

colors[event.index].function()

What you stored at that table .function entry isn’t really a name at all - it’s a reference. Names are stuff like “name”. When you drop the quotation marks you’re making a reference, usually to a variable.

On the table side, things are much more flexible. When you use named table entries order doesn’t matter.

[code]-- This…
local table = { width=32, num=47, hello=“hey there” }

– Is the same as this…
local table = {}
table.width = 32
table.num = 47
table.hello = “hey there”

– is the same as this
local table = { num=47 }
table.width = 32
table.hello = “hey there”[/code]

So you can add stuff to your table in whatever order you want (so long as you give them names) and even add stuff later. Just keep in mind that is not the same as this:

local table = { 32, 47, "hello"} --table[1] = 32 --table[2] = 47 --table[3] = "hello"

Unnamed stuff assumes number code like that instead.

[import]uid: 41884 topic_id: 29205 reply_id: 117809[/import]

so for my table I was doing this…

 local books = {}  
 books[1] = { isCategory=true, name="Books" }  
 books[2] = { name="Book 1", subtitle="Cool Book", function="showBook1"}  
 books[3] = { name="Book 2", subtitle="Cool Book 2" }  

The above addition of function= breaks the app and spits this at me in the console…
‘(’ expected near ‘=’

and then the onRowTouch code as you described earlier… I am basically using books instead of colors. [import]uid: 18783 topic_id: 29205 reply_id: 117811[/import]

Yeah so as I mentioned function needs to be a reference, not text.

"This is text, or in programming terms, a string." 42 -- this is a number. dude -- this is a reference.

references are like bookmarks. Somewhere you declare what the reference is, like this:

local coolvariable

By default, it equals ‘nil’. (nothing). But it’s still a variable! So whenever you type coolvariable (without quotation marks), Corona doesn’t see that word it all. It sees the value of the word, which in this case is still ‘nil’.

So what your table should do is this:

[code]-- somewhere in your file before the table, you make a function.
local function changeMind()
print(“hum hah!”)
end

– then in your table say
local books = {}
books[1] = { isCategory=true, name=“Books” }
books[2] = { name=“Book 1”, subtitle=“Cool Book”, function=changeMind }
books[3] = { name=“Book 2”, subtitle=“Cool Book 2” }[/code]

Because you said changeMind instead of “changeMind”, Corona actually looks for whatever changeMind is, which in this case is a function, not because it says function in the table, but because a function already exists called that.

Table entries can be anything you want.

[code]table[1].example = 34 – a number
table[2].example = “hey” – a string

local function test() end
table[3].example = test – a function

table[4].example = {} – another table!!

local coolvar = “hey”
table[5].example = coolvar – a variable. So it would really equal “hey”
[/code] [import]uid: 41884 topic_id: 29205 reply_id: 117826[/import]

@richard9 == +10

Nice job with the tables lesson!

Nail [import]uid: 106779 topic_id: 29205 reply_id: 117828[/import]

True except even without the quotes which I forgot to mention I tried it would give the same error. So long story short changing it from function=showBook1 in the table to go=showBook1 and then addressing this in the release section with go instead of function it actually works so far.

Matt
[import]uid: 18783 topic_id: 29205 reply_id: 117876[/import]