newTableView - how to get index of top row

I have a newTableView control that has rows inserted and deleted based upon selection by the user.  Nothing unusual there.  The “selected” or last touched row has an icon that says “On” all other rows have one that says “Off”.  Data in the system is configured based upon which row is On or Off.   For the sake of argument, lets say that all rows are visible to eliminate rendering issues.

deleting rows 2-n allows me to use newTableView:getRowAtIndex(1) to turn row 1 “On” as the “touched” row. no problems there.

deleting row 1 has the problem.  using newTableView:getRowAtIndex(1) now returns nil.  Ok, that makes sense since I just deleted it.  I originally thought that we have a threading issue that a performWithDelay would solve, but no such luck. After the delete, a file is downloaded that can take as much as 30 seconds. I dont call getRowAtIndex until the downloaded file has been finished and unzipped, so I dont believe it is a timing problem.  I rigged a loop that walked the newTableView and testing for nil, and found that the index of the deleted row properly read as nil, and the next rows showed their indexes AS BEFORE THE DELETE.  There is the key.  I had understood that the indexes go re-indexed at some point. I cant seem to figure out when and how.

the simple answer is if getRowAtIndex(1) returns a nil, then use getRowAtIndex(2).  duh.  However if multiple rows are deleted before the control re-indexes, then how do we get the index of the topmost row.

now to add some complexity, if the “top” row has scrolled off the screen - its derendered and also returns nil.

I’ve tried scrollToIndex(1,100,onComplete) to force it to the top, but all calls to scrollToIndex, regardless of index crash within the api. I’ve reported this as a bug.

I figured that the scrollToIndex would force a re-render, and hopefully, a re-index and therefore getRowAtIndex(1) would work.

Is there any way to accomplish at newTextView:getTopVisibleRow() that returns the index of the top visible row?

You can save the index number of the data table for that row but simply adding an value to the “row” object to keep track of the real index, is easy to do:

row.index = dataIndexForThisRow

Rob

Thanks for getting back on this, Rob.  I think that we’ve missed.  I understanding the adding of the variable to the row.  The docs also says that the id variable also already defaults to the index if I dont override it.  That isnt the problem.   I may be getting twisted since my results are slightly different than what the docs say.

What I understand to be the way it should work is:

   the index is a static number assigned to a row at insert

   only visible rows are rendered and return a “valid” row from getRowAtIndex

I’m looking to either: find the index of the first visible (therefore rendered) row, or force the table to the top and get the index of that row.  

I guess an easier way to ask would be: other than walking the internal newTableView table, looking for the first rendered row, and then grabbing it’s index, how can I get the widget to give me that number?

A suggestion might be: have scrollToIndex return the index scrolled to, if successful - and then - passing an index of -1 scrolls to the top and returns the valid index of that row, and passing an index of 0 “scrolls” the rows to where they are (no movement) but returns the index of the top, visible row.

then again, maybe I’m a complete dunce and this is actually staring me in the face.  :)

Dave

Maybe this will help:

row.id – the internal ID of the row in the tableView. Should not be messed with. If your table view has 10 rows, it will have id’s running 1-10. If you delete row 5, there won’t be a hole, but you will now have 9 rows with ID’s 1-9.  This has nothing to do with your data or how it’s indexed.j

row.index – a value you set. It’s arbitrary. If you use this as your data table’s index, then you have an easy way of relating your data to your tableView rows. In theory your data row 15 might be tableView row 3 depending on how you’ve sorted things.

In the programming world there is a design philosophy called “Model-View-Controller” or MVC. In this system, the “Model” is your data. The View is the code that renders the data, but the view and the model don’t know anything about each other’s state. In other words, the view (tableView’s onRowRender) doesn’t know or care about how the data is organized. That function should not have any responsibilities in managing the model (data), i.e. onRowRender() should not add or delete rows. It can have buttons to do that and the buttons logic does the work using the row.index you set. Therefore the buttons  become the controller code. They are the bridge between the model and view.  When you call tableView:insertRow() the code that calls insertRow() is the Controller part of your code.

Hope this helps!

Rob

Hi, Rob.

Thanks for trying.  I understand MVC concepts.  In short, my onRowRender() deals with the visuals.  My version of your row.index is held in row.params.index.  Where I am missing something is: both ScrollToIndex and getRowAtIndex take an index variable.  This isnt an index into my data, it is an index into the control and it’s data.  (and I understand that the row passed back is actually a display group).  The control knows the indexes of what rows are rendered, as it includes it in the onRender() call,

I need to essentially simulate a touch to the topmost visible row to trigger default values and then set a “state”.  With rows being, in particular, removed, based upon user action, the ability to retrieve the index of the top rendered row becomes essential as the deleted row was also the last touched and I need to establish a new default.  An actual touch or tap gives me the info needed.  If my last “touched” row gets scrolled off (and deRendered) and then another row touched, I lose public access to that previous row’s data and the ability to affect its rendering “properly” when back in view as it still thinks that it was touched.  While public access to the params of a non-rendered row would be nice, I can write around that - though I really hate referencing hidden variables.  I’m currently “deTouching” the previously touched row in the OnTouch() of the new using the GetRowAtIndex() with a module scope variable, which works great as long as both are on the screen.

In any case,  thanks for the help.  I appreciate the quick response.

Dave

You can save the index number of the data table for that row but simply adding an value to the “row” object to keep track of the real index, is easy to do:

row.index = dataIndexForThisRow

Rob

Thanks for getting back on this, Rob.  I think that we’ve missed.  I understanding the adding of the variable to the row.  The docs also says that the id variable also already defaults to the index if I dont override it.  That isnt the problem.   I may be getting twisted since my results are slightly different than what the docs say.

What I understand to be the way it should work is:

   the index is a static number assigned to a row at insert

   only visible rows are rendered and return a “valid” row from getRowAtIndex

I’m looking to either: find the index of the first visible (therefore rendered) row, or force the table to the top and get the index of that row.  

I guess an easier way to ask would be: other than walking the internal newTableView table, looking for the first rendered row, and then grabbing it’s index, how can I get the widget to give me that number?

A suggestion might be: have scrollToIndex return the index scrolled to, if successful - and then - passing an index of -1 scrolls to the top and returns the valid index of that row, and passing an index of 0 “scrolls” the rows to where they are (no movement) but returns the index of the top, visible row.

then again, maybe I’m a complete dunce and this is actually staring me in the face.  :)

Dave

Maybe this will help:

row.id – the internal ID of the row in the tableView. Should not be messed with. If your table view has 10 rows, it will have id’s running 1-10. If you delete row 5, there won’t be a hole, but you will now have 9 rows with ID’s 1-9.  This has nothing to do with your data or how it’s indexed.j

row.index – a value you set. It’s arbitrary. If you use this as your data table’s index, then you have an easy way of relating your data to your tableView rows. In theory your data row 15 might be tableView row 3 depending on how you’ve sorted things.

In the programming world there is a design philosophy called “Model-View-Controller” or MVC. In this system, the “Model” is your data. The View is the code that renders the data, but the view and the model don’t know anything about each other’s state. In other words, the view (tableView’s onRowRender) doesn’t know or care about how the data is organized. That function should not have any responsibilities in managing the model (data), i.e. onRowRender() should not add or delete rows. It can have buttons to do that and the buttons logic does the work using the row.index you set. Therefore the buttons  become the controller code. They are the bridge between the model and view.  When you call tableView:insertRow() the code that calls insertRow() is the Controller part of your code.

Hope this helps!

Rob

Hi, Rob.

Thanks for trying.  I understand MVC concepts.  In short, my onRowRender() deals with the visuals.  My version of your row.index is held in row.params.index.  Where I am missing something is: both ScrollToIndex and getRowAtIndex take an index variable.  This isnt an index into my data, it is an index into the control and it’s data.  (and I understand that the row passed back is actually a display group).  The control knows the indexes of what rows are rendered, as it includes it in the onRender() call,

I need to essentially simulate a touch to the topmost visible row to trigger default values and then set a “state”.  With rows being, in particular, removed, based upon user action, the ability to retrieve the index of the top rendered row becomes essential as the deleted row was also the last touched and I need to establish a new default.  An actual touch or tap gives me the info needed.  If my last “touched” row gets scrolled off (and deRendered) and then another row touched, I lose public access to that previous row’s data and the ability to affect its rendering “properly” when back in view as it still thinks that it was touched.  While public access to the params of a non-rendered row would be nice, I can write around that - though I really hate referencing hidden variables.  I’m currently “deTouching” the previously touched row in the OnTouch() of the new using the GetRowAtIndex() with a module scope variable, which works great as long as both are on the screen.

In any case,  thanks for the help.  I appreciate the quick response.

Dave