Tableview - Passing text from inputText to rows

Hi,

I’m trying to set up a table view that displays rows which are created once the user inputs a text in a textfield object. So far the text inputed should be shown inside of the new row created.

I am following a tutorial to do this which doesn’t explain step by step how to do this stuff and tableviews are well above my programming capabilities so I’m either missing something very obvious or making a structural mistake… Basically I am not able to pass the text inputed to the row to be displayed. Here,s the snippet in question:

 local savename = native.newTextField( 0, 0, display.contentWidth - 50, 24 )       sceneGroup:insert (savename)       savename.x = centerX       savename.y = display.screenOriginY + 140          savename.inputType = "default"       savename:setTextColor( 0, 0, 0 )       savename.align = "center" local function scrollListener (event) end local function makeRow (event, txt)   local row = event.target;     row.t = display.newText(txt,0,0,"Helvetica",18)   row.t.anchorX = 0   row.t.y = row.height \* 0.5 end local function handleRowTouch (event) end local tableView = widget.newTableView( {     top = display.contentHeight/2 + 90,     width = display.contentWidth,     height = 240,     listener = scrollListener,     onRowRender = makeRow,     onRowTouch = onRowTouch } ) sceneGroup:insert (tableView)       local savename = native.newTextField( 0, 0, display.contentWidth - 50, 24 )       sceneGroup:insert (savename)       savename.x = centerX       savename.y = display.screenOriginY + 140          savename.inputType = "default"       savename:setTextColor( 0, 0, 0 )       savename.align = "center"       function savename:userInput (event)                   local length = string.len( self.text )         if (event.phase == "began") then           print ("Began" .. event.target.text)           elseif (event.phase == "editing") then                       print ("editing" .. event.target.text)             elseif (event.phase == "ended") then                       print ("ended" .. event.target.text)             elseif (event.phase == "submitted") then                     if (length \> 0)  then                       local rowHeight = 38                       local rowColor = {default = { 1, 1, 1}}                       local lineColor = {0, 0, 0}                       local txt = self.text                             tableView:insertRow({                         onEvent = handleRowTouch,                         onRender = function (event) makeRow (event, txt) end,                                                  height = rowHeight,                         rowColor = rowColor,                         lineColor = lineColor                                               })                       self.text = ""                       setKeyboardFocus (nil)                     else                                             local alert = native.showAlert("Hey!", "Type in a save name please...\n Or dismiss this action by touching the background.", {"Ok"})                     end         end       end         savename:addEventListener ("userInput", savename)

Then it’s in the “submitted” phase of the ‘savename:userInput’  function that I’m calling the tableView:insertRow method which onRender calls the ‘makeRow’ function passing ‘event’ and ‘txt’ as params.

‘txt’ should correspond to the text input by the user as specified by ‘local txt = self.text’, but when I run the program an error is returned saying ‘a string is expected’ when creating the row text (row.t) in the makeRow function.

This seems as I’m not passing that parameter correctly but I can’t figure out where I’m making a mistake. Do you guys have any idea why???

Thanks!!!

I’m trying to solve this stuff now I get this errore which I have no idead what it means:

Bad cursor rect event, flags = 256

What it that??? Haven’t found anything about it around the web…

Thanks.

So no help here??

I’m posting the whole code (minus composer template) so that if there’s any good soul who wants ot try to run it and see what’s wrong that doesn’t let me create the table view:

local bg = display.newRect( centerX, centerY, display.contentWidth, display.contentHeight )       sceneGroup:insert(bg)       bg:setFillColor( 1, 1, 1 )       bg:addEventListener( "tap", function() native.setKeyboardFocus( nil ) end ) local savename = native.newTextField( 0, 0, display.contentWidth - 50, 24 )       sceneGroup:insert (savename)       savename.x = centerX       savename.y = display.screenOriginY + 140          savename.inputType = "default"       savename:setTextColor( 0, 0, 0 )       savename.align = "center" local function tableViewListener( event )     local phase = event.phase     print( event.phase ) end local function onRowRender( event, txt )     local row = event.target     print (txt .. "check!!!!!")     row.t = display.newText(row, " " .. txt,0,0,"Helvetica",24)   row.t.anchorX = 0   row.t.x = 12   row.t.y = row.height \* 0.5   row.t:setFillColor( 0,0,0 )   function row.t:updateText(txt)     self.text = txt;     self:setReferencePoint(display.CenterLeftReferencePoint);     self.x = 12;   end end local function onRowUpdate( event )     local row = event.row     print( "Row:", row.index, " is now visible" ) end local function onRowTouch( event )     local phase = event.phase     if "press" == phase then         print( "Touched row:", event.target.index )     end end local tableView = widget.newTableView {     top = display.contentHeight/2 + 90,     width = display.contentWidth,     height = 240,     listener = tableViewListener,     onRowRender = onRowRender,              onRowUpdate = onRowUpdate,              onRowTouch = onRowTouch,     maskFile = mask           } sceneGroup:insert( tableView )     local isCategory = false local savename = native.newTextField( 0, 0, display.contentWidth - 50, 24 )       sceneGroup:insert (savename)       savename.x = centerX       savename.y = display.screenOriginY + 140          savename.inputType = "default"       savename:setTextColor( 0, 0, 0 )       savename.align = "center"       function savename:userInput (event)                   local length = string.len( self.text )         if (event.phase == "began") then           print ("Began" .. event.target.text)           elseif (event.phase == "editing") then                       print ("editing " .. event.target.text)             elseif (event.phase == "ended") then                       print ("ended " .. event.target.text)             elseif (event.phase == "submitted") then                     if (length \> 0)  then                     print ("submitted " .. event.target.text)                       local isCategory = false                       local rowHeight = 38                       local rowColor = {default = { 1, 1, 1}}                       local lineColor = {0, 0, 0}                       local txt = self.text                       tableView:insertRow({                         onEvent = onRowTouch,                               onRender = function (event) onRowRender(event, txt) end,                            rowHeight = rowHeight,                         rowColor = rowColor,                         lineColor = lineColor,                                                                                       })                       self.text = ""                       native.setKeyboardFocus (nil)                     else                                             local alert = native.showAlert("Hey!", "Type in a save name please...\n Or dismiss this action by touching the background.", {"Ok"})                     end         end       end         savename:addEventListener ("userInput", savename)

Please notice that if I comment out ‘onRowRender = onRowRender’ when defining the tableView object options, it doesn’t return the ‘txt is nil’ error, but still rows get created without any text inside them as if the onRowRender function is not working properly, in fact if I put a ‘print check’  ( (print (txt … “check!!!”) ) inside of it doesn’t get executed.

Pls help to go on with my project…

Thanks!

      

 

What you’re struggling with causes problems to people new to Corona SDK.  This frustrated me to know end when I was first learning.  Here’s the issue:

When a event handler is triggered, like the tableView’s onRowRender() function, you cannot pass your own parameters to it without using something called closures.  Normally onRowRender() will only  have one parameter passed to it and that’s the “event” table.

Historically speaking, you would have a table with your data in it indexed by the row number.  Then in your onRowRender() function you would get the row number and look up your data from your data table.  However we added the ability to use the tableView:insertRow() function to pass data in as part of that call.

There is an example on how to do this in our Business App sample:  https://github.com/coronalabs/business-app-sample

Rob

Hi Rob,

Thank you for the empathy… it is frustrating.

It seems to me that the example code about tablieviews only represents a case of preset-rows, my problem here is rows would be generated on user input and filled with said user input data.

I resolved this thing just an hour ago by passing the paramters I want from withi n the tableView:insertRow method, using a ‘params’ table as you illustrate in this tutorial: http://coronalabs.com/blog/2014/03/04/tutorial-advanced-tableview-tactics/

Only I don’t know if it’s a proper approach since later on I’d want to store persistently the data passed to and contained in the rows… You think this way I’ll be able to acess and save the data??

Thanks also for the explanation (which I still limp about understanding…)

It really helps to understand the MVC programming pattern.  MVC stands for Model-View-Controller.  Model is the dataset.  The view is how it’s displayed and the controller is a bridge between the two.  Ideally the model or the view can change without impacting the other because the controller handles that.   Obviously if you add a new data field like say a phone number to a contact list, you would want to change the view to handle inputting and showing that number, but adding a phone number to the dataset shouldn’t break the view.

In your example, the tableView is just that, a view.  You really shouldn’t have any programming logic in there regarding saving the data.  You would have independent code that manages your dataset and the tableView just shows it.

Rob

Hey Rob,

I read your tutorial on enclosures and it seems to me like I applied the method properly but the error still persists.

The matter of the question regards the ‘txt’ variable I am trying to pass to the ‘onRowRender’ function. As you can see at bottom of the code I posted, inside of the tableView.insertRow method onRender is set to an anonymous function that encloses onRowRender( ) so that this latter can pass event AND txt,( as you can see in the actual function arguments above). But when it fires it just returns the same txt=nil error as txt isn’t passed.

Why is that??

Thanks…

I’m trying to solve this stuff now I get this errore which I have no idead what it means:

Bad cursor rect event, flags = 256

What it that??? Haven’t found anything about it around the web…

Thanks.

So no help here??

I’m posting the whole code (minus composer template) so that if there’s any good soul who wants ot try to run it and see what’s wrong that doesn’t let me create the table view:

local bg = display.newRect( centerX, centerY, display.contentWidth, display.contentHeight )       sceneGroup:insert(bg)       bg:setFillColor( 1, 1, 1 )       bg:addEventListener( "tap", function() native.setKeyboardFocus( nil ) end ) local savename = native.newTextField( 0, 0, display.contentWidth - 50, 24 )       sceneGroup:insert (savename)       savename.x = centerX       savename.y = display.screenOriginY + 140          savename.inputType = "default"       savename:setTextColor( 0, 0, 0 )       savename.align = "center" local function tableViewListener( event )     local phase = event.phase     print( event.phase ) end local function onRowRender( event, txt )     local row = event.target     print (txt .. "check!!!!!")     row.t = display.newText(row, " " .. txt,0,0,"Helvetica",24)   row.t.anchorX = 0   row.t.x = 12   row.t.y = row.height \* 0.5   row.t:setFillColor( 0,0,0 )   function row.t:updateText(txt)     self.text = txt;     self:setReferencePoint(display.CenterLeftReferencePoint);     self.x = 12;   end end local function onRowUpdate( event )     local row = event.row     print( "Row:", row.index, " is now visible" ) end local function onRowTouch( event )     local phase = event.phase     if "press" == phase then         print( "Touched row:", event.target.index )     end end local tableView = widget.newTableView {     top = display.contentHeight/2 + 90,     width = display.contentWidth,     height = 240,     listener = tableViewListener,     onRowRender = onRowRender,              onRowUpdate = onRowUpdate,              onRowTouch = onRowTouch,     maskFile = mask           } sceneGroup:insert( tableView )     local isCategory = false local savename = native.newTextField( 0, 0, display.contentWidth - 50, 24 )       sceneGroup:insert (savename)       savename.x = centerX       savename.y = display.screenOriginY + 140          savename.inputType = "default"       savename:setTextColor( 0, 0, 0 )       savename.align = "center"       function savename:userInput (event)                   local length = string.len( self.text )         if (event.phase == "began") then           print ("Began" .. event.target.text)           elseif (event.phase == "editing") then                       print ("editing " .. event.target.text)             elseif (event.phase == "ended") then                       print ("ended " .. event.target.text)             elseif (event.phase == "submitted") then                     if (length \> 0)  then                     print ("submitted " .. event.target.text)                       local isCategory = false                       local rowHeight = 38                       local rowColor = {default = { 1, 1, 1}}                       local lineColor = {0, 0, 0}                       local txt = self.text                       tableView:insertRow({                         onEvent = onRowTouch,                               onRender = function (event) onRowRender(event, txt) end,                            rowHeight = rowHeight,                         rowColor = rowColor,                         lineColor = lineColor,                                                                                       })                       self.text = ""                       native.setKeyboardFocus (nil)                     else                                             local alert = native.showAlert("Hey!", "Type in a save name please...\n Or dismiss this action by touching the background.", {"Ok"})                     end         end       end         savename:addEventListener ("userInput", savename)

Please notice that if I comment out ‘onRowRender = onRowRender’ when defining the tableView object options, it doesn’t return the ‘txt is nil’ error, but still rows get created without any text inside them as if the onRowRender function is not working properly, in fact if I put a ‘print check’  ( (print (txt … “check!!!”) ) inside of it doesn’t get executed.

Pls help to go on with my project…

Thanks!

      

 

What you’re struggling with causes problems to people new to Corona SDK.  This frustrated me to know end when I was first learning.  Here’s the issue:

When a event handler is triggered, like the tableView’s onRowRender() function, you cannot pass your own parameters to it without using something called closures.  Normally onRowRender() will only  have one parameter passed to it and that’s the “event” table.

Historically speaking, you would have a table with your data in it indexed by the row number.  Then in your onRowRender() function you would get the row number and look up your data from your data table.  However we added the ability to use the tableView:insertRow() function to pass data in as part of that call.

There is an example on how to do this in our Business App sample:  https://github.com/coronalabs/business-app-sample

Rob

Hi Rob,

Thank you for the empathy… it is frustrating.

It seems to me that the example code about tablieviews only represents a case of preset-rows, my problem here is rows would be generated on user input and filled with said user input data.

I resolved this thing just an hour ago by passing the paramters I want from withi n the tableView:insertRow method, using a ‘params’ table as you illustrate in this tutorial: http://coronalabs.com/blog/2014/03/04/tutorial-advanced-tableview-tactics/

Only I don’t know if it’s a proper approach since later on I’d want to store persistently the data passed to and contained in the rows… You think this way I’ll be able to acess and save the data??

Thanks also for the explanation (which I still limp about understanding…)

It really helps to understand the MVC programming pattern.  MVC stands for Model-View-Controller.  Model is the dataset.  The view is how it’s displayed and the controller is a bridge between the two.  Ideally the model or the view can change without impacting the other because the controller handles that.   Obviously if you add a new data field like say a phone number to a contact list, you would want to change the view to handle inputting and showing that number, but adding a phone number to the dataset shouldn’t break the view.

In your example, the tableView is just that, a view.  You really shouldn’t have any programming logic in there regarding saving the data.  You would have independent code that manages your dataset and the tableView just shows it.

Rob

Hey Rob,

I read your tutorial on enclosures and it seems to me like I applied the method properly but the error still persists.

The matter of the question regards the ‘txt’ variable I am trying to pass to the ‘onRowRender’ function. As you can see at bottom of the code I posted, inside of the tableView.insertRow method onRender is set to an anonymous function that encloses onRowRender( ) so that this latter can pass event AND txt,( as you can see in the actual function arguments above). But when it fires it just returns the same txt=nil error as txt isn’t passed.

Why is that??

Thanks…