Blog | Crank Software

Storyboard Tutorial: Creating User Interface Table Variables

Written by Sarah Collie | Sep 24, 2014 7:59:36 PM

Updated on February 18, 2020
Sometimes the best way to display data in Storyboard is with tables and table variables. Tables, as well as cells within the table, are able to contain several render extensions, aka user interface table variables. This allows them to behave dynamically and perform a wide variety of tasks. 

Getting started with user interface table variables

Before getting started, download the example that we've started for you and import it into Storyboard. You should see something that looks like this:



Adding User Interface Table Variables

If you were to run the application at this point, it wouldn't do too much. All of the cells in the table are the same. They all have the same text and there aren't enough of them to make up an entire week. To create a table variable:

  1. Click the table cell.
  2. Select the Text render extension.
  3. Bind a variable to the text value.


Creating the new table variable

In the Table Variable Selection dialog:

  1. Click the New Variable button.
  2. Type "text" in the Name field.
  3. Select the Create a table cell variable checkbox to indicate that we are creating a table variable.
  4. Extend it to the 5th row (we could do all 7 here but we may not know how many rows there will be).
  5. Finish and select that variable.

Loading data

In the Application Model, double-click callbacks.lua to open it up for editing. Let's add code to iterate through the weekdays table to populate the table cells that we have so far.

  1. Copy and paste the code below to fill in the load_table function.
  2. Run the program and press Load Table.
function load_table(mapargs)

local data={}

for i=1,#weekdays do --The "#weekdays here returns the number of entries in the table."
--When changing table variables, you specify them by layer_name.control_name.variable_name.row.col
data["TableLayer.weekdays.text."..i..".1"] = weekdays[i]

end

gre.set_data(data)
end

Expanding the table rows to include selected data

A week isn't complete with only six days, so we will need to add Sunday to the table. But right now, our table is only six rows long. There are several ways to change the number of rows in a table, but for our purposes, the Lua function gre.set_table_attrs() is most appropriate. That function expects a table of tags with their values, as well as the name of a table. Paste this function underneath the gre.set_data(data) we just added:

function load_table(mapargs)

local data={}

for i=1,#weekdays do --The "#weekdays here returns the number of entries in the table."

data["TableLayer.weekdays.text."..i..".1"] = weekdays[i] --When changing table variables, you specify them by layer_name.control_name.variable_name.row.col

end

gre.set_data(data)

local tag_table={}
tag_table["rows"] = #weekdays
gre.set_table_attrs("TableLayer.weekdays.text.",tag_table)
end

Now, let's run the application again and check our progress.

Adding a new variable for Fill

Let's add another table variable but this time to the Fill render extension. To start, you'll notice we've only included 4 of the rows.

  1. Click the table cell.
  2. Select the Fill render extension.
  3. Switch the render extension from a static to dynamic variable.
  4. Click the New Variable button.
  5. Type "fill" in the Name field.
  6. Select the Create a table cell variable checkbox to indicate that we are creating a table variable.
  7. Extend it to the 4th row as you see in the screenshot below.
  8. Click Finish.

 

Run this in the simulator now and you'll find that the fills seem to be black in all the rows from 4 onward. This is because there is no data to go on when  those cells are being filled out. To fix this, add the following under our text variable change in the load table:

data["TableLayer.weekdays.fill."..i..".1"] = 0x6D8F3A

Run that to see this fixed.

Adding interactivity to the table

Next, we're going to add a few actions on the user interface table cell. We'll add gre.cell.gotfocus with a Data Change action, gre.cell.lostfocus with a Data Change action, and gre.press with a Lua Script action. gotfocus will change the table fill to #A7C445 and lostfocus will change it to #6D8F3A. The press event will call the Lua function cb_cell_press. You can add those parameters below the trigger events on the Actions tab, as you can see below:

Understanding which row was pressed

Now that we have some highlighted cells and some dynamic data, let's see which row is pressed. We've already attached the Lua function cb_cell_press, so now we can add the following function and code to our callbacks.lua script:

function cb_cell_press(mapargs)

local cell=mapargs.context_row

print(cell)
end

Run it and press on a couple rows.


 

Ensuring a meaningful response

What we see printed out in the Storyboard console is the row number of each cell we press. While that's a step forward, we'd probably want more than just the row number. We could print weekdays[cell], but what if that data has gone through changes since it was put in the table? What we want is the text variable of that specific cell at that specific point in time. So let's add the last two lines below to our cb_cell_press function:

function cb_cell_press(mapargs)

local cell=mapargs.context_row

local data=gre.get_data("TableLayer.weekdays.text."..cell..".1")

print(data["TableLayer.weekdays.text."..cell..".1"])
end

Now we're getting meaningful data from that row that we can use elsewhere if required.


 

Playing with other data to make it your own

We're now left with this as a final callbacks.lua file:

local weekdays={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}
function
load_table(mapargs)

local data={}

for i=1,#weekdays do --The "#weekdays here returns the number of entries in the table."
--When changing table variables, you specify them by layer_name.control_name.variable_name.row.col
data["TableLayer.weekdays.text."..i..".1"] = weekdays[i]
data["TableLayer.weekdays.fill."..i..".1"] = 0x6D8F3A

end

gre.set_data(data)

local tag_table = {}
tag_table["rows"] = #weekdays
gre.set_table_attrs("TableLayer.weekdays",tag_table)
end
function
cb_cell_press(mapargs)
local cell=mapargs.context_row
local data=gre.get_data("TableLayer.weekdays.text."..cell..".1")
print(data["TableLayer.weekdays.text."..cell..".1"])
end

Now that we've play around with the different table settings to see what they do, try adding another variable and render extension, or add an image to the right of the table.

To help out further, take a look at our Lua documentation to see what other functionality can be added to tables in your user interfaces.