B4J Tutorial [ABMaterial] Inline table editing

alwaysbusy

Expert
Licensed User
I've had some questions about inline editing of tables in ABMaterial. There is one way to do this, however it has its limitations and will only work in certain cases. It only works for 'String' values and you have to define your table as a scrollable one.

This is the table in question that needs to be build:


The bottom (white row) should be editable.

So what do we need to do:

1. We need to define a theme for a cell to be editable (isEditable=true):
B4X:
public Sub BuildTheme()
    ' start with the base theme defined in ABMShared
    theme.Initialize("pagetheme")
    theme.AddABMTheme(ABMShared.MyTheme) 
 
    ' add additional themes specific for this page
    theme.AddTableTheme("tbl1theme")
    theme.Table("tbl1theme").ZDepth = ABM.ZDEPTH_1
 
    theme.Table("tbl1theme").AddCellTheme("noteditable1")
    theme.Table("tbl1theme").Cell("noteditable1").BackColor = ABM.COLOR_ORANGE
    theme.Table("tbl1theme").Cell("noteditable1").BorderColor = ABM.COLOR_BLACK
    theme.Table("tbl1theme").Cell("noteditable1").BorderWidth = 1
    theme.Table("tbl1theme").Cell("noteditable1").Align = ABM.TABLECELL_HORIZONTALALIGN_CENTER
 
    theme.Table("tbl1theme").AddCellTheme("noteditable2")
    theme.Table("tbl1theme").Cell("noteditable2").BackColor = ABM.COLOR_YELLOW
    theme.Table("tbl1theme").Cell("noteditable2").BorderColor = ABM.COLOR_BLACK
    theme.Table("tbl1theme").Cell("noteditable2").BorderWidth = 1
    theme.Table("tbl1theme").Cell("noteditable2").Align = ABM.TABLECELL_HORIZONTALALIGN_CENTER
 
    theme.Table("tbl1theme").AddCellTheme("editable")
    theme.Table("tbl1theme").Cell("editable").ActiveBackColor = ABM.COLOR_WHITE
    theme.Table("tbl1theme").Cell("editable").BorderColor = ABM.COLOR_BLACK
    theme.Table("tbl1theme").Cell("editable").BorderWidth = 1
    theme.Table("tbl1theme").Cell("editable").Align = ABM.TABLECELL_HORIZONTALALIGN_CENTER
    theme.Table("tbl1theme").Cell("editable").IsEditable = True
 
    ' bluegray button
    theme.AddButtonTheme("bluegrey")
    theme.Button("bluegrey").BackColor = ABM.COLOR_BLUEGREY
    theme.Button("bluegrey").BackColorIntensity = ABM.INTENSITY_DARKEN1
End Sub
2. Second, as said, the table MUST be a scrollable one with fixed column widths (code from BuildPage()).
B4X:
' create the page grid
    page.AddRowsM(2,True,0,0, "").AddCells12(1,"") 
    page.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components 
 
    Dim Widths As List
    Widths.Initialize
    For i = 1 To 31
        Widths.Add(40) ' the column widths
    Next
    Dim tbl1 As ABMTable
    tbl1.InitializeScrollable(page, "tbl1", False, False, True, Widths, "tbl1theme")
    page.Cell(1,1).SetFixedHeight(360) ' IMPORTANT
3. We create the header row 1 (the orange one). We MUST have a header row to make this work.
B4X:
Dim rH1 As List
    Dim rH1CellThemes As List
    rH1.Initialize
    rH1CellThemes.Initialize
    For i = 1 To 31
        rH1.Add("" & i) ' make sure it is a string!
        rH1CellThemes.Add("noteditable1")
    Next 
    tbl1.SetHeaders(rH1)
    tbl1.SetHeaderThemes(rH1CellThemes)
4. We insert the second row (yellow days) as a normal row, not editable.
B4X:
Dim Days As List
    Days.Initialize2(Array As String("F", "S", "S", "M", "T", "W", "T"))
    Dim Daycounter As Int
 
    Dim rH2 As List
    Dim rH2CellThemes As List
    rH2.Initialize
    rH2CellThemes.Initialize
    For i = 1 To 31
        rH2.Add(Days.Get(Daycounter))
        Daycounter = Daycounter + 1
        If Daycounter = 7 Then
            Daycounter = 0
        End If
        rH2CellThemes.Add("noteditable2")
    Next
    tbl1.AddRow("uid" & "H2", rH2)
    tbl1.SetRowThemes(rH2CellThemes) ' make sure you have as many items in rCellThemes as in r!
5. Last, we add an 'editable' row (white), add the tbl to the page.cell() and add button (see further):
B4X:
Dim rD As List
    Dim rDCellThemes As List
    rD.Initialize
    rDCellThemes.Initialize
    For i = 1 To 31
        rD.Add("0")
        rDCellThemes.Add("editable")
    Next
    tbl1.AddRow("uid" & "1", rD)
    tbl1.SetRowThemes(rDCellThemes) ' make sure you have as many items in rCellThemes as in r!
     
    page.Cell(1,1).AddComponent(tbl1)
 
    ' add buttons
    Dim btn1 As ABMButton
    btn1.InitializeRaised(page, "btn1", "", "", "Get values", "bluegrey") 
    page.Cell(2,1).AddComponent(btn1)
6. So now we have one event tbl1_changed() that we can use to track if the user changed a value in the white row.
B4X:
Sub tbl1_Changed(Params As Map)
    Dim row As String = Params.Get("row")
    Dim column As String = Params.Get("column")
    Dim Value As String = Params.Get("value")
    Log("[" & row & " " & column & "] = " & Value)
End Sub
7. A better way may be just, if the user presses a button to say he has finished editing, retrieve all values.
B4X:
Sub btn1_Clicked(Target As String)
    Dim tbl1 As ABMTable = page.Component("tbl1")
    tbl1.PrepareTableForRetrieval
    For i = 0 To 30
        Log(tbl1.GetString(1, i))
    Next
End Sub
So, this is a bit of a (late) easter egg hidden in the ABMTable component ;)

The result in ABMaterial:
upload_2016-4-26_12-13-2.png



Alain
 
Last edited:
Top