Storyboard Tutorial – Creating dynamic tables with variables

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. In our last tutorial, we walked through a simple introduction to creating tables in Storyboard Suite. In this tutorial, we are going to go a little deeper and venture into table variables.

Prerequisite

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:

our-first-look

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 a full week. To create a table variable:

  1. Click the table cell
  2. Select the Text render extension
  3. Switch the render extension from a static to dynamic variable

adding-table-variables

Create 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

new-variable

Load in some data

In the Application Model, double-click callbacks.lua to open it 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."
		data["demo_layer.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)
end

let-s-load-in-some-data

Expand 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. Expand the code to make it look like this:

function load_table(mapargs)
	local data={}
	for i=1,#weekdays do --The "#weekdays here returns the number of entries in the table."
		data["demo_layer.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("demo_layer.weekdays",tag_table) 
end

Let’s run the application again and check our progress. expanding-table-rows-to-include-selected-data

Add 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

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

data["demo_layer.weekdays.fill."..i..".1"]=0x696969

Run that to see it fixed.

Add some interactivity to the table

Next we’re going to add a few actions on the 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 lostfocus will change the fill to #696969 and gotfocus will change it to to #333333. The lua function is cb_cell_press. You can add those parameters below the trigger events on the Actions tab, as you can see below: add-some-interactivity Here’s the highlighted row! highlighted-

Getting which row was pressed

Now that we’ve got cell highlighting 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 some rows getting-which-row-was-pressed

Get 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("demo_layer.weekdays.text."..cell..".1")
	print(data["demo_layer.weekdays.text."..cell..".1"])
end

Now we’re getting meanigful data from that row that we can use elsewhere if required. get-a-meaningful-response

Play with other data to make this 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."
		data["demo_layer.weekdays.text."..i..".1"]=weekdays[i] --When changing table variables, you specify them by layer_name.control_name.variable_name.row.col
		data["demo_layer.weekdays.fill."..i..".1"]=0x696969
	end
	
	gre.set_data(data)
	
	
	local tag_table={}
	tag_table["rows"]=#weekdays
	gre.set_table_attrs("demo_layer.weekdays",tag_table) 
end
function cb_cell_press(mapargs) 
	local cell=mapargs.context_row
	local data=gre.get_data("demo_layer.weekdays.text."..cell..".1")
	print(data["demo_layer.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. Perhaps add an image on the right of the table. To help you out, take a look at our lua documentation to see what else you can do to add functionality to tables in your user interfaces.