B4J Question B4XTable

Guenter Becker

Active Member
Licensed User
Longtime User
Hello, hope youre well.

I know that the data of a B4XTable is shown by pages and their rows.
I like to know how to jump to row named by rowid by code but i didn't found any help in the forum. Anyone here to have an answer?
B4J snipped will be welcome.

Thank you in advance.
 

Magma

Expert
Licensed User
Longtime User
Hello, hope youre well.

I know that the data of a B4XTable is shown by pages and their rows.
I like to know how to jump to row named by rowid by code but i didn't found any help in the forum. Anyone here to have an answer?
B4J snipped will be welcome.

Thank you in advance.
Hi there...

you mean when the user select a rowid ?
or programmatically - because programmatically you can do it with 2 ways SQL and List (you must have a list to set the data, so getting index of it - is the row) ?

edit: or you mean go at page 3 (because b4xtable using paging) and select 2nd item (example) ?
 
Upvote 0

Guenter Becker

Active Member
Licensed User
Longtime User
For example.
  1. I loaded Data in the B4XTable.
  2. User clicks on a row an I save RowId and ColumnId by code.
  3. After that for some reason I reload the Data in the B4XTable, insert a new row or whatever.
  4. If done I like to jump of the page/row by code using the prior save RowId. Don'want to iterate over all rows/pages to find it. Seraching for a solution to jump direct.
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
If you added a new row, I suppose it will appear in the last row.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
If you added a new row, I suppose it will appear in the last row.
no... i understand @Guenter Becker what he means...

If you edit row, col... you must reload list to b4xtable...

@Guenter Becker - so need to keep the page, row, to set again the selection... but yes need to reload all the data, so if have many data - will see all the progress

edit: also if you add a new row/index at list/sql you must check if will be at a new page of b4xtable
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
If you edit row, col... you must reload list to b4xtable...
No, we don't need to reload the list if it is not necessary. However, most of the time, reloading the list is easier.
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
how you can do it... without reloading ?
Short answer is here:
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Short answer is here:
Yes, i see (in line editing) but this get a little complicate if need to save also in db...
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Here is a sample project to demonstrate go to last page after inserting a new row.
GitHub: https://github.com/pyhoon/B4XTableSample-B4J

The relevant code is as follow:
B4X:
' Code adapted from B4XTable's lblLast_Click
Private Sub GotoLastPage
    Dim CurrentCount As Int = B4XTable1.mCurrentCount
    Dim RowsPerPage As Int = B4XTable1.RowsPerPage
    Dim NumberOfPages As Int = Ceil(CurrentCount / RowsPerPage)
    B4XTable1.FirstRowIndex = (NumberOfPages - 1) * RowsPerPage
End Sub

1755696931077.png
 
Last edited:
Upvote 0

Guenter Becker

Active Member
Licensed User
Longtime User
Hi thank you for your replies.
I'm a little bit astonished about the discussion about inserting an new row. That was not the basic of my question!! Again I like to know how to jump to special row named by the rowid by code even it is a part of the current grid page or not. Aerics example is close to what I want it shows how to jump to the last row. May be the code from him can be modified to to jump to any named row,. I think the solution is to calculate the needed page and than the row to be adressed in that page. But I'm to stupid to come to the solution.
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
B4XTable1.CreateDataView("rowid = " & rowid)
This will create a "WHERE" query in the in-memory db and filtered out all the rows.
Only 1 row is show.

I suggest adding the following code:
B4X:
Private Sub BtnJump_Click
    If TxtRowId.Text.Length = 0 Then Return
    LastSelectedRowId = TxtRowId.Text
    B4XTable1.FirstRowIndex = LastSelectedRowId - 1
End Sub

Private Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
    LastSelectedRowId = RowId
    TxtRowId.Text = LastSelectedRowId
End Sub
This will remember the last clicked row and jump to the LastSelectedRowId when click the Jump button on top right.

1755767469401.png
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
It is correct that only one row is shown. The OP can tell us if that is what he wants.
B4XTable1.FirstRowIndex = LastSelectedRowId - 1
The B4XTable1.FirstRowIndex refers to the index in the B4XTable.clvdata custom list view.
The LastSelectedRowId refers to the rowid in the internal SQL data table.
The second row in the B4XTable can have a rowid of 5 for instance after deleting some rows.
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
It is correct that only one row is shown. The OP can tell us if that is what he wants.

The B4XTable1.FirstRowIndex refers to the index in the B4XTable.clvdata custom list view.
The LastSelectedRowId refers to the rowid in the internal SQL data table.
The second row in the B4XTable can have a rowid of 5 for instance after deleting some rows.
Correct.
The header is having index 0.

It depends on use case.
In your solution, user need to click the Clear data button to reset the table view.
In my solution, user can continue to use the paging control.
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
Maybe i'm missing something... can you set an index of a custom list view (int) equal to a rowid in a table (long)?
Are they not of a different type?
The second row in the B4XTable can have a rowid of 5 for instance after deleting some rows !!!
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Maybe i'm missing something... can you set an index of a custom list view (int) equal to a rowid in a table (long)?
Are they not of a different type?
If I understand your concern, the RowId returned from CellClicked is a type of Long.
When I assign the value to a Int variable, it may cause out of range if the value is too big that it can be larger than the Int upper bound.
I may be wrong but I see the size of items B4XTable can handle is in Int.
So I make an assumption the RowId will not larger than the Int upper bound.
When assigning to the variable of Int type, it will automatically casting to Int.

The second row in the B4XTable can have a rowid of 5 for instance after deleting some rows !!!
My textbox that accept "Row Id" is jumping to the row id on CLV as you referring to.
Yes, I may have made a confusion here because I am showing the column Id in the B4XTable.
This Id is referring to column Id in sqlite db, not the in-memory db of B4XTable or CLV's row index.
Meaning, jumping to Row Id 2 is not jumping to Id = 2.
Instead it is "jumping" to the 2nd row of "data" rows, or 3rd item row of CLV where 1st item is the header.

If you mean deleting a row in B4XTable may affect the rowid of in-memory db of B4XTable, this one I cannot confirm.
I assume the rowids in the in-memory db will be reconstructed when adding or deleting row.
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
Maybe i also need to clarify a few things. In my example the indexes of the B4XTable.clvdata list start with 1,2,3,4,5,6 and so on.
The OP clicks on the row with index 5 and rowid 5 (which is saved).
Then he decides to delete rows with indexes 2,3 and 4.
If he then click on the row with index 2 then that row has a rowid of 5 !
Clicking on the goto button will then show the row with rowid 5 (in the index 1).
If you change the where clause from CreateDataView("rowid = " & rowid) to for instance CreateDataView("rowid >= " & rowid) then
the view will also show the rows after the saved rowid.

Yes, B4X will automatically cast the long rowid to an int index. It's like comparing apples and pears, they are both fruits but don't look the same.
Source code from the B4XTable library:
B4X:
Public Sub CreateDataView (WhereClause As String)
    sql1.ExecNonQuery("DROP VIEW IF EXISTS TempView")
    sql1.ExecNonQuery("CREATE VIEW TempView AS SELECT *, rowid FROM data WHERE " & WhereClause)
    CountAll = sql1.ExecQuerySingleResult("SELECT count(*) FROM TempView")
    mFirstRowIndex = 0
    SQLTableName = "TempView"
    UpdateData (False)
End Sub
 
Upvote 0
Top