B4J Tutorial [ABMaterial] CRUD generation, the next step in 1.09

I added a couple of new methods to the CRUD generator that allows code generation for an overview (similar to what you see in this feedback app):

B4X:
' some new properties:
myExecutorDef.OverviewSetTheme("tbltheme")
myExecutorDef.OverviewHasEdit("Open/Edit") ' add an edit button at the end
myExecutorDef.OverviewHasDelete("Delete") ' add a delete button at the end
myExecutorDef.OverviewHasPagination(10) ' add a pagaination component
myExecutorDef.OverviewHasSearchBox("Search executor") ' add an input field and a button to search
myExecutorDef.OverviewFooter("Number of rows") ' add a footer
myExecutorDef.OverviewHasAddButton ' add an ActionButton at the bottom right to add a new record

' some new methods:
myExecutorDef.Set11OverviewVisible(      Array As Boolean(False  , True  , True  , False  ))
myExecutorDef.Set12OverviewHeaderThemes(  Array As String (""  , ""  , ""  , ""  ))
myExecutorDef.Set13OverviewCellThemes(  Array As String (""  , ""  , ""  , ""  ))
myExecutorDef.Set14OverviewIncludeInSearch( Array As Boolean(False  , True  , True  , False  ))
myExecutorDef.Set15OverviewSortable(     Array As Boolean(False  , True  , True  , False  ))
myExecutorDef.Set16OverviewHeaderHeights(  Array As Int  (0  , 0  , 0  , 0  )) '<- 0 = auto
myExecutorDef.Set17OverviewColumnWidths(  Array As Int  (0  , 0  , 0  , 0  )) '<- 0 = auto

This will generate extra code so you have a full working CRUD form (adding, viewing, deleting, editing).

For example this is the full GridGenerator code needed in a project of ours:

B4X:
public Sub RunGenerators()
    Dim Generator As ABMGenerator

    Dim myExecutorDef As ABMGeneratorCRUDDefinition
    myExecutorDef.Initialize("exID", "tExecutor", "Enter all fields for this executor", "Save", "Cancel", "Yes", "No", "Close", "Are you sure you want to delete this executionar?", "Please enter all fields first!")
    myExecutorDef.IgnoreAutoNumberInINSERT = True

    myExecutorDef.OverviewSetTheme("tbltheme")
    myExecutorDef.OverviewHasEdit("Open/Edit")
    myExecutorDef.OverviewHasDelete("Delete")
    myExecutorDef.OverviewHasPagination(10)
    myExecutorDef.OverviewHasSearchBox("Search executor")
    myExecutorDef.OverviewFooter("Number of rows")
    myExecutorDef.OverviewHasAddButton
 
    Dim cmbType As String = "SELECT extypID, extypCode FROM tExecutor_Type ORDER BY extypCode;"

    myExecutorDef.Set01FieldNames(              Array As String ("exID"            , "exCode"           , "exDescription"      , "exExTypID"            ))
    myExecutorDef.Set02RowOffsetSizes(          Array As String (""                , "1:0:12"           , "2:0:12"             , "3:0:12"               ))
    myExecutorDef.Set03LabelTexts(              Array As String (""                , "Code"             , "Description"        , "Type"                 ))
    myExecutorDef.Set04ComponentTypes(          Array As Int    (ABM.GEN_NONE      , ABM.GEN_TEXT       , ABM.GEN_TEXTAREA     , ABM.GEN_COMBOSQL        ))
    myExecutorDef.Set05DefaultValues(           Array As String (""                , ""                 , ""                   , 1                      ))
    myExecutorDef.Set06ComboQueries(            Array As String (""                , ""                 , ""                   , cmbType                ))
    myExecutorDef.Set07ComboLists(              Array As Map    (Null              , Null               , Null                 , Null                   ))
    myExecutorDef.Set08ValidationMethods(       Array As String (""                , "NotEmpty"         , "NotEempty"          , ""                     ))
    myExecutorDef.Set09Enableds(                Array As Boolean(False             , True               , True                 , True                   ))
    myExecutorDef.Set10UseInUpdates(            Array As Boolean(False             , True               , True                 , True                   ))
    myExecutorDef.Set11OverviewVisible(         Array As Boolean(False             , True               , True                 , False                  ))
    myExecutorDef.Set12OverviewHeaderThemes(    Array As String (""                , ""                 , ""                   , ""                     ))
    myExecutorDef.Set13OverviewCellThemes(      Array As String (""                , ""                , ""                  , ""                    ))
    myExecutorDef.Set14OverviewIncludeInSearch( Array As Boolean(False             , True               , True                 , False                  ))
    myExecutorDef.Set15OverviewSortable(        Array As Boolean(False             , True               , True                 , False                  ))
    myExecutorDef.Set16OverviewHeaderHeights(   Array As Int    (0                 , 0                  , 0                    , 0                      )) '<- 0 = auto
    myExecutorDef.Set17OverviewColumnWidths(    Array As Int    (0                 , 0                  , 0                    , 0                      )) '<- 0 = auto

    Generator.GenerateCRUDSheet(File.DirApp, "Executors1", myExecutorDef, ABM.MODALSHEET_SIZE_FULL)
End Sub

The result is about 500 lines of B4J code, cut and paste ready:
B4X:
--------------------------------------------------------------
' Add in Sub Class_Globals()
--------------------------------------------------------------
Dim ActiveExecutors1exID As Int
Dim IsNewExecutors1 As Boolean
Dim FilterExecutors1 As String
Dim LastSortExecutors1 As String

--------------------------------------------------------------
' Note that you will have to create the themes yourself!
' e.g. the themes for the cells and header of the overview
--------------------------------------------------------------
Theme.AddTableTheme("tbltheme")
Theme.Table("tbltheme").ZDepth = ABM.ZDEPTH_1
' it is for the edit/delete header so we have to set all color properties too!
Theme.Table("tbltheme").AddCellTheme("abmgenheadercenter")
'Theme.Table("tbltheme").Cell("abmgenheadercenter").BackColor = <Set your backcolor here>
'Theme.Table("tbltheme").Cell("abmgenheadercenter").ForeColor = <Set your forecolor here>
Theme.Table("tbltheme").Cell("abmgenheadercenter").Align = ABM.TABLECELL_HORIZONTALALIGN_CENTER

' it is for the edit/delete button cell
Theme.Table("tbltheme").AddCellTheme("abmgencellcenter")
Theme.Table("tbltheme").Cell("abmgencellcenter").Align = ABM.TABLECELL_HORIZONTALALIGN_CENTER

--------------------------------------------------------------
' Add in BuildPage()
--------------------------------------------------------------
' minimum page grid needed
page.AddRowsM(1,True,0,0, "").AddCells12(1,"")
page.AddRows(1,True, "").AddCellsOS(1,0,0,0,10,10,11,"").AddCellsOSMP(1,0,0,0,2,2,1,14,0,0,0,"")
page.AddRows(2,True, "").AddCells12(1,"")
page.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

--------------------------------------------------------------
' Add in BuildPage() or ConnectPage()
--------------------------------------------------------------
page.AddModalSheetTemplate(ABMGenBuildExecutors1)
page.AddModalSheetTemplate(ABMGenBuildExecutors1Delete)
page.AddModalSheetTemplate(ABMGenBuildExecutors1BadInput)

Dim ABMGenSearchExecutors1 As ABMInput
ABMGenSearchExecutors1.Initialize(page, "ABMGenSearchExecutors1", ABM.INPUT_TEXT, "Search executor", False, "")
page.CellR(1,1).AddComponent(ABMGenSearchExecutors1)

Dim ABMGenSearchBtnExecutors1 As ABMButton
ABMGenSearchBtnExecutors1.InitializeFloating(page, "ABMGenSearchBtnExecutors1", "mdi-action-search", "")
page.CellR(0,2).AddComponent(ABMGenSearchBtnExecutors1)

Dim ABMGenPaginationExecutors1 As ABMPagination
ABMGenPaginationExecutors1.Initialize(page, "ABMGenPaginationExecutors1", 10, True, True, "")
ABMGenPaginationExecutors1.SetTotalNumberOfPages(0)
page.CellR(1,1).AddComponent(ABMGenPaginationExecutors1)

' create the ABMGenTableExecutors1 table
Dim ABMGenTableExecutors1 As ABMTable
' IMPORTANT: we set usingQueriesToSort = true because we are going to handle the sorting, not the javascript sorting library
' When using Pagination, the sorting library does not know all the data
' SetColumnDataFields() is used when the user clicks on a column head to sort to return in the SortChanged() event and the GetSortColumn() And SetSortColumn() methods.
ABMGenTableExecutors1.Initialize(page, "ABMGenTableExecutors1", True, True, True, "")
ABMGenTableExecutors1.IsResponsive = True
ABMGenTableExecutors1.SetHeaders(         Array As String (""    ,"Code"  ,"Description"  ,"Type"     ,"Open/Edit","Delete"))
ABMGenTableExecutors1.SetHeaderThemes(    Array As String (""    ,""      ,""             ,""         ,"abmgenheadercenter","abmgenheadercenter"))
ABMGenTableExecutors1.SetHeaderHeights(   Array As Int    (0     ,0       ,0              ,0          ,0          ,0       ))
ABMGenTableExecutors1.SetColumnWidths(    Array As Int    (0     ,0       ,0              ,0          ,50         ,50      ))
ABMGenTableExecutors1.SetColumnVisible(   Array As Boolean(False ,True    ,True           ,False      ,True       ,True    ))
ABMGenTableExecutors1.SetColumnSortable(  Array As Boolean(False ,True    ,True           ,False      ,False      ,False   ))
ABMGenTableExecutors1.SetColumnDataFields(Array As String ("exID","exCode","exDescription","exExTypID",""         ,""      ))
ABMGenTableExecutors1.SetFooter("Number of rows", 12,"")
page.CellR(1,1).AddComponent(ABMGenTableExecutors1)

' create the add Executors1 action button
Dim ABMGenTableAddExecutors1 As ABMActionButton
ABMGenTableAddExecutors1.Initialize(page, "ABMGenTableAddExecutors1", "mdi-content-add", "")
ABMGenTableAddExecutors1.MainButton.Size = ABM.BUTTONSIZE_LARGE

' add to page
page.AddActionButton(ABMGenTableAddExecutors1)

    ' IMPORTANT: If you added the above code to BuildPage you have to put this line as the last in Websocket_Connected()
    '              If you added the above code to ConnectPage you have to put this line as the last in ConnectPage(), after page.FinishedLoading
    LoadABMGenTableExecutors1(1)
--------------------------------------------------------------
' Add in the class
--------------------------------------------------------------
#Region ABMGenTableExecutors1 table
Private Sub LoadABMGenTableExecutors1(fromPage As Int)
    Dim ABMGenTableExecutors1 As ABMTable = page.Component("ABMGenTableExecutors1")

    Dim SQL As SQL = DBM.GetSQL

    Dim numFound As Int = DBM.ABMGenSQLSelectSingleResult(SQL, "SELECT Count(exID) as IDS FROM tExecutor " & FilterExecutors1, null)
    Dim results As List = DBM.ABMGenSQLSelect(SQL, "SELECT exID, exCode, exDescription, exExTypID FROM tExecutor " & FilterExecutors1 & " " & LastSortExecutors1 & " LIMIT " & ((fromPage - 1) * 10) & ", 10", null)
    If results.Size = 0 And fromPage > 1 Then
        ' we are on a page without any lines (maybe removed by other user?)
        DBM.CloseSQL(SQL)
        fromPage = fromPage - 1
        LoadABMGenTableExecutors1(fromPage)
        Return
    End If
    ' You could for example set here the number of rows found
    ' ABMGenTableExecutors1.SetFooter("Total number of rows: " & numFound, 12,"")
    ABMGenTableExecutors1.Clear

    For i = 0 To results.Size - 1
        Dim tblFields As Map = results.Get(i)
        Dim rCellValues As List
        Dim rCellThemes As List
        rCellValues.Initialize
        rCellThemes.Initialize

        rCellValues.Add(tblFields.Get("exid"))
        rCellThemes.Add("")

        rCellValues.Add(tblFields.Get("excode"))
        rCellThemes.Add("")

        rCellValues.Add(tblFields.Get("exdescription"))
        rCellThemes.Add("")

        rCellValues.Add(tblFields.Get("exextypid"))
        rCellThemes.Add("")

        Dim ABMGenTableEditExecutors1 As ABMButton
        ABMGenTableEditExecutors1.InitializeFloating(page, "ABMGenTableEditExecutors1", "mdi-action-visibility", "")
        rCellValues.Add(ABMGenTableEditExecutors1)
        rCellThemes.Add("abmgencellcenter")

        Dim ABMGenTableDeleteExecutors1 As ABMButton
        ABMGenTableDeleteExecutors1.InitializeFloating(page, "ABMGenTableDeleteExecutors1", "mdi-action-delete", "")
        rCellValues.Add(ABMGenTableDeleteExecutors1)
        rCellThemes.Add("abmgencellcenter")

        ABMGenTableExecutors1.AddRow("uidExecutors1" & i, rCellValues)
        ABMGenTableExecutors1.SetRowThemes(rCellThemes) ' make sure you have as many items in rCellThemes as in rCellValues!  Must follow IMMEDIATELY AFTER AddRow!
    Next
    ABMGenTableExecutors1.Refresh

    DBM.CloseSQL(SQL)

    Dim ABMGenPaginationExecutors1 As ABMPagination = page.Component("ABMGenPaginationExecutors1")
    If (numFound mod 10 > 0) Or (numFound = 0) Then
        numFound = numFound/10 + 1
    Else
        numFound = numFound/10
    End If
    ABMGenPaginationExecutors1.SetTotalNumberOfPages(numFound)
    ABMGenPaginationExecutors1.SetActivePage(fromPage)
    ABMGenPaginationExecutors1.Refresh

End Sub

Sub ABMGenPaginationExecutors1_PageChanged(OldPage As Int, NewPage As Int)
    ' do your stuff
    LoadABMGenTableExecutors1(NewPage)
End Sub

Sub ABMGenTableAddExecutors1_Clicked(Target As String, SubTarget As String)
    ' reset all the values on the form
    ActiveExecutors1exID = 0
    ABMGenExecutors1New
End Sub

Sub ABMGenTableExecutors1_Clicked(PassedRowsAndColumns As List)
    ' fill with the active values
    Dim tblCellInfo As ABMTableCell = PassedRowsAndColumns.Get(0)
    Dim ABMGenTableExecutors1 As ABMTable = page.Component(tblCellInfo.TableName)
    If tblCellInfo.Column = 4 Then ' edit
        ActiveExecutors1exID = ABMGenTableExecutors1.GetString(tblCellInfo.row, 0)
        ABMGenExecutors1Edit(ActiveExecutors1exID)
    End If
    If tblCellInfo.Column = 5 Then ' delete
        ActiveExecutors1exID = ABMGenTableExecutors1.GetString(tblCellInfo.row, 0)
        ABMGenExecutors1Delete(ActiveExecutors1exID)
    End If
End Sub

Sub ABMGenTableExecutors1_SortChanged(DataField As String, Order As String)
    Select Case DataField
        Case "exCode","exDescription"
            LastSortExecutors1 = " ORDER BY " & DataField & " " & Order & " "
        Case Else
            LastSortExecutors1 = ""
    End Select
    ' reload the table
    Dim ABMGenPaginationExecutors1 As ABMPagination = page.Component("ABMGenPaginationExecutors1")
    LoadABMGenTableExecutors1(ABMGenPaginationExecutors1.GetActivePage())
End Sub

Sub ABMGenSearchBtnExecutors1_Clicked(Target As String)
    DoSearchExecutors1
End Sub

Sub ABMGenSearchExecutors1_EnterPressed()
    DoSearchExecutors1
End Sub

Sub DoSearchExecutors1()
    Dim ABMGenSearchExecutors1 As ABMInput = page.Component("ABMGenSearchExecutors1")
    FilterExecutors1 = ABMGenSearchExecutors1.Text
    If FilterExecutors1 <> "" Then
        FilterExecutors1 = " WHERE (exCode LIKE '%" & FilterExecutors1 & "%'  OR exDescription LIKE '%" & FilterExecutors1 & "%' ) "
    Else
        FilterExecutors1 = ""
    End If
    ' reload the table
    LoadABMGenTableExecutors1(1)
End Sub
#End Region

#Region Executors1
Sub ABMGenBuildExecutors1() As ABMModalSheet
    Dim ABMGenExecutors1Modal As ABMModalSheet
    ABMGenExecutors1Modal.Initialize(page, "Executors1", True, False, "")
    ABMGenExecutors1Modal.IsDismissible = False
    ABMGenExecutors1Modal.Size = ABM.MODALSHEET_SIZE_FULL

    ABMGenExecutors1Modal.Content.AddRowsM(1, True, 0, 0, "").AddCells12(1, "")
    ABMGenExecutors1Modal.Content.AddRowsM(3, True, 0, 0, "").AddCellsOS(1, 0, 0, 0, 12, 12, 12, "")
    ABMGenExecutors1Modal.Content.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

    Dim ABMGenExecutors1TitleMessage As ABMLabel
    ABMGenExecutors1TitleMessage.Initialize(page, "ABMGenExecutors1TitleMessage", "Enter all fields for this executor" , ABM.SIZE_PARAGRAPH, False, "")
    ABMGenExecutors1TitleMessage.IsBlockQuote = True
    ABMGenExecutors1Modal.Content.CellR(0,1).AddComponent(ABMGenExecutors1TitleMessage)

    Dim ABMGenExecutors1exCode As ABMInput
    ABMGenExecutors1exCode.Initialize(page, "ABMGenExecutors1exCode", ABM.INPUT_TEXT, "Code", False, "")
    ABMGenExecutors1Modal.Content.CellR(1,1).AddComponent(ABMGenExecutors1exCode)
    ABMGenExecutors1exCode.Text = ""

    Dim ABMGenExecutors1exDescription As ABMInput
    ABMGenExecutors1exDescription.Initialize(page, "ABMGenExecutors1exDescription", ABM.INPUT_TEXT, "Description", True, "")
    ABMGenExecutors1Modal.Content.CellR(1,1).AddComponent(ABMGenExecutors1exDescription)
    ABMGenExecutors1exDescription.Text = ""

    Dim ABMGenExecutors1exExTypID As ABMCombo
    ABMGenExecutors1exExTypID.Initialize(page, "ABMGenExecutors1exExTypID", "Type", 500, "")
    Dim SQL as SQL = DBM.GetSQL
    Dim SQL_Str as String = "SELECT extypID, extypCode FROM tExecutor_Type ORDER BY extypCode;"
    Dim results As List = DBM.ABMGenSQLSelect(SQL, SQL_Str, null)
    For l = 0 To results.Size - 1
        Dim res As Map = results.Get(l)
        ABMGenExecutors1exExTypID.AddItem(res.GetValueAt(0), res.GetValueAt(1), ABMGenBuildExecutors1ComboItem("ABMGenExecutors1exExTypID" & (l+1), res.GetValueAt(1)))
    Next
    DBM.CloseSQL(SQL)
    ABMGenExecutors1Modal.Content.CellR(1,1).AddComponent(ABMGenExecutors1exExTypID)
    ABMGenExecutors1exExTypID.SetActiveItemId("1")

    ABMGenExecutors1Modal.Footer.AddRowsM(1,True,0,0, "").AddCells12(1,"")
    ABMGenExecutors1Modal.Footer.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

    ' create the buttons for the footer, create in opposite order as aligned right in a footer
    Dim ABMGenExecutors1Cancel As ABMButton
    ABMGenExecutors1Cancel.InitializeFlat(page, "ABMGenExecutors1Cancel", "", "", "Cancel", "transparent")
    ABMGenExecutors1Modal.Footer.Cell(1,1).AddComponent(ABMGenExecutors1Cancel)

    Dim ABMGenExecutors1Save As ABMButton
    ABMGenExecutors1Save.InitializeFlat(page, "ABMGenExecutors1Save", "", "", "Save", "transparent")
    ABMGenExecutors1Modal.Footer.Cell(1,1).AddComponent(ABMGenExecutors1Save)

    Return ABMGenExecutors1Modal
End Sub

' method you can call when the user wants to add a new record
Sub ABMGenExecutors1New()
    Dim ABMGenExecutors1Modal As ABMModalSheet = page.ModalSheet("Executors1")
    ActiveExecutors1exID = 0

    Dim NewDate As Long = DateTime.Now 'ignore
    Dim ABMGenExecutors1exCode As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exCode")
    Dim ABMGenExecutors1exDescription As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exDescription")
    Dim ABMGenExecutors1exExTypID As ABMCombo = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exExTypID")

    ABMGenExecutors1exCode.Text = ""
    ABMGenExecutors1exDescription.Text = ""
    ABMGenExecutors1exExTypID.SetActiveItemId("1")
    IsNewExecutors1=true
    page.ShowModalSheet("Executors1")
End Sub

' method you can call when the user wants to edit an existing record
Sub ABMGenExecutors1Edit(openId As int)
    Dim ABMGenExecutors1Modal As ABMModalSheet = page.ModalSheet("Executors1")
    ActiveExecutors1exID = openId
    Dim NewDate As long = DateTime.Now 'ignore
    Dim SQL As SQL = DBM.GetSQL
    Dim SQL_str As String = "SELECT exID, exCode, exDescription, exExTypID FROM tExecutor WHERE exID = ? "
    Dim results As List = DBM.ABMGenSQLSelect(SQL, SQL_Str, Array As Int(ActiveExecutors1exID))
    If results.Size>0 Then
        Dim m as Map = results.Get(0)
        Dim ABMGenExecutors1exCode As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exCode")
        Dim ABMGenExecutors1exDescription As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exDescription")
        Dim ABMGenExecutors1exExTypID As ABMCombo = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exExTypID")

        If m.GetDefault("excode", null) = null Then
            ABMGenExecutors1exCode.Text = ""
        Else
            ABMGenExecutors1exCode.Text = m.Get("excode")
        End If

        If m.GetDefault("exdescription", null) = null Then
            ABMGenExecutors1exDescription.Text = ""
        Else
            ABMGenExecutors1exDescription.Text = m.Get("exdescription")
        End If

        If m.GetDefault("exextypid", null) = null Then
            ABMGenExecutors1exExTypID.SetActiveItemId("1")
        Else
            ABMGenExecutors1exExTypID.SetActiveItemId(m.Get("exextypid"))
        End If

        IsNewExecutors1=false
        page.ShowModalSheet("Executors1")
    Else
        log("No record found")
    End If
    DBM.CloseSQL(SQL)
End Sub

' the user clicked save the form
Sub ABMGenExecutors1Save_Clicked(Target As String)
    Dim ABMGenExecutors1Modal As ABMModalSheet = page.ModalSheet("Executors1")

    Dim Variables as List
    Variables.Initialize
    Dim NewDate as Long = DateTime.Now 'ignore

    Dim SQL as SQL = DBM.GetSQL
    Dim valueDouble as Double 'ignore
    Dim valueString as String 'ignore
    Dim valueInt as Int 'ignore
    Dim valueBoolean as Boolean 'ignore
    Dim valueLong as Long 'ignore
    Dim ret as int 'ignore

    If IsNewExecutors1 = false Then ' check if still exists
        Dim SQL_chk As String = "SELECT exID FROM tExecutor WHERE exID = ? "
        IsNewExecutors1 = (DBM.ABMGenSQLSelectSingleResult(SQL, SQL_chk, Array As Int(ActiveExecutors1exID))<=DBM.DBOK)
    End If

    If IsNewExecutors1 Then
        Dim ABMGenExecutors1exCode As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exCode")
        Dim ABMGenExecutors1exDescription As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exDescription")
        Dim ABMGenExecutors1exExTypID As ABMCombo = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exExTypID")

        valueString = ABMGenExecutors1exCode.Text
        If ABMGenNotEmpty(valueString) = false Then
            page.ShowModalSheet("Executors1BadInput")
            Return
        End If
        Variables.Add(valueString)

        valueString = ABMGenExecutors1exDescription.Text
        If ABMGenNotEempty(valueString) = false Then
            page.ShowModalSheet("Executors1BadInput")
            Return
        End If
        Variables.Add(valueString)

        valueInt = ABMGenExecutors1exExTypID.GetActiveItemId
        Variables.Add(valueInt)

        ret = DBM.ABMGenSQLInsert(SQL, "INSERT INTO tExecutor(exCode, exDescription, exExTypID) VALUES(?, ?, ?)", Variables)
    Else
        Dim ABMGenExecutors1exCode As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exCode")
        Dim ABMGenExecutors1exDescription As ABMInput = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exDescription")
        Dim ABMGenExecutors1exExTypID As ABMCombo = ABMGenExecutors1Modal.Content.Component("ABMGenExecutors1exExTypID")

        valueString = ABMGenExecutors1exCode.Text
        If ABMGenNotEmpty(valueString) = false Then
            page.ShowModalSheet("Executors1BadInput")
            Return
        End If
        Variables.Add(valueString)

        valueString = ABMGenExecutors1exDescription.Text
        If ABMGenNotEempty(valueString) = false Then
            page.ShowModalSheet("Executors1BadInput")
            Return
        End If
        Variables.Add(valueString)

        valueInt = ABMGenExecutors1exExTypID.GetActiveItemId
        Variables.Add(valueInt)

        ret = DBM.ABMGenSQLUpdate(SQL, "UPDATE tExecutor SET exCode=?, exDescription=?, exExTypID=? WHERE exID=" & ActiveExecutors1exID, Variables)
    End If
    DBM.CloseSQL(SQL)
    page.CloseModalSheet("Executors1")

    ActiveExecutors1exID = 0

    Dim ABMGenPaginationExecutors1 As ABMPagination = page.Component("ABMGenPaginationExecutors1")
    LoadABMGenTableExecutors1(ABMGenPaginationExecutors1.GetActivePage())
End Sub

' the user clicked on cancel on the save form
Sub ABMGenExecutors1Cancel_Clicked(Target As String)
    ActiveExecutors1exID = 0
    page.CloseModalSheet("Executors1")
End Sub

' method to check if a certain field is valid
Sub ABMGenNotEmpty(value As String) As Boolean
    ' TODO by the programmer!
    Return true
End Sub

' method to check if a certain field is valid
Sub ABMGenNotEempty(value As String) As Boolean
    ' TODO by the programmer!
    Return true
End Sub

Sub ABMGenBuildExecutors1Delete() As ABMModalSheet
    Dim ABMGenExecutors1DeleteModal As ABMModalSheet
    ABMGenExecutors1DeleteModal.Initialize(page, "Executors1Delete", False, False, "")
    ABMGenExecutors1DeleteModal.IsDismissible = False

    ' Build the content grid
    ABMGenExecutors1DeleteModal.Content.AddRowsM(1, True,0,0, "").AddCells12(1, "")
    ABMGenExecutors1DeleteModal.Content.BuildGrid  'IMPORTANT once you loaded the complete grid AND before you start adding components

    ' add message label
    Dim ABMGenExecutors1DeleteMessage As ABMLabel
    ABMGenExecutors1DeleteMessage.Initialize(page, "ABMGenExecutors1DeleteMessage", "Are you sure you want to delete this executionar?" , ABM.SIZE_PARAGRAPH, False, "")
    ABMGenExecutors1DeleteModal.Content.CellR(0,1).AddComponent(ABMGenExecutors1DeleteMessage)

    ' Build the footer grid
    ABMGenExecutors1DeleteModal.Footer.AddRowsM(1,True,0,0, "").AddCellsOS(1,6,6,6,3,3,3,"").AddCellsOS(1,0,0,0,3,3,3, "")
    ABMGenExecutors1DeleteModal.Footer.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

    ' create the buttons for the footer
    Dim ABMGenExecutors1DeleteYes As ABMButton
    ABMGenExecutors1DeleteYes.InitializeFlat(page, "ABMGenExecutors1DeleteYes", "", "", "Yes", "transparent")
    ABMGenExecutors1DeleteModal.Footer.Cell(1,1).AddComponent(ABMGenExecutors1DeleteYes)

    Dim ABMGenExecutors1DeleteNo As ABMButton
    ABMGenExecutors1DeleteNo.InitializeFlat(page, "ABMGenExecutors1DeleteNo", "", "", "No", "transparent")
    ABMGenExecutors1DeleteModal.Footer.Cell(1,2).AddComponent(ABMGenExecutors1DeleteNo)

    Return ABMGenExecutors1DeleteModal
End Sub

' method you can call when the user wants to delete a record
Sub ABMGenExecutors1Delete(deleteId As int)
    ActiveExecutors1exID = deleteId
    page.ShowModalSheet("Executors1Delete")
End Sub

' the user clicked yes on the delete messagebox
Sub ABMGenExecutors1DeleteYes_Clicked(Target As String)
    Dim SQL as SQL = DBM.GetSQL
    DBM.ABMGenSQLDelete(SQL, "DELETE FROM tExecutor WHERE exID = ? ", Array as Int(ActiveExecutors1exID))
    DBM.CloseSQL(SQL)
    page.CloseModalSheet("Executors1Delete")
    ActiveExecutors1exID = 0

    Dim ABMGenPaginationExecutors1 As ABMPagination = page.Component("ABMGenPaginationExecutors1")
    LoadABMGenTableExecutors1(ABMGenPaginationExecutors1.GetActivePage())
End Sub

Sub ABMGenExecutors1DeleteNo_Clicked(Target As String)
    page.CloseModalSheet("Executors1Delete")
End Sub

Sub ABMGenBuildExecutors1BadInput() As ABMModalSheet
    Dim ABMGenExecutors1BadInputModal As ABMModalSheet
    ABMGenExecutors1BadInputModal.Initialize(page, "Executors1BadInput", False, False, "")
    ABMGenExecutors1BadInputModal.IsDismissible = False

    ' Build the content grid
    ABMGenExecutors1BadInputModal.Content.AddRowsM(1, True,0,0, "").AddCells12(1, "")
    ABMGenExecutors1BadInputModal.Content.BuildGrid  'IMPORTANT once you loaded the complete grid AND before you start adding components

    ' add message label
    Dim ABMGenExecutors1BadInputMessage As ABMLabel
    ABMGenExecutors1BadInputMessage.Initialize(page, "ABMGenExecutors1BadInputMessage", "Please enter all fields first!" , ABM.SIZE_PARAGRAPH, False, "")
    ABMGenExecutors1BadInputModal.Content.CellR(0,1).AddComponent(ABMGenExecutors1BadInputMessage)

    ' Build the footer grid
    ABMGenExecutors1BadInputModal.Footer.AddRowsM(1,True,0,0, "").AddCellsOS(1,6,6,6,3,3,3,"").AddCellsOS(1,0,0,0,3,3,3, "")
    ABMGenExecutors1BadInputModal.Footer.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

    ' create the buttons for the footer
    Dim ABMGenExecutors1BadInputCancel As ABMButton
    ABMGenExecutors1BadInputCancel.InitializeFlat(page, "ABMGenExecutors1BadInputCancel", "", "", "Close", "transparent")
    ABMGenExecutors1BadInputModal.Footer.Cell(1,2).AddComponent(ABMGenExecutors1BadInputCancel)

    Return ABMGenExecutors1BadInputModal
End Sub

' the user clicked ok on the Bad Input messagebox
Sub ABMGenExecutors1BadInputCancel_Clicked(Target As String)
    page.CloseModalSheet("Executors1BadInput")
End Sub

Sub ABMGenBuildExecutors1ComboItem(id As String, title as String) as ABMLabel 'ignore
    Dim ABMGenLabel As ABMLabel
    ABMGenLabel.Initialize(page, id, "{NBSP}" & title, ABM.SIZE_H6, True, "")
    ABMGenLabel.VerticalAlign = True
    return ABMGenLabel
End Sub
#End Region

With a nice overview looking like this:
CRUD2.png
 
Last edited:

Harris

Expert
Licensed User
Longtime User
I added a couple of new methods to the CRUD generator that allows code generation for an overview (similar to what you see in this feedback app):

Sorry @alwaysbusy
I am very dense here...

I was under the impression (and used) that CRUD Gen was for modal sheets.
Here you show a grid??

I must be missing something? Been busy trying to advance (debug) my project.

No need for long text explanation, just point to thread. Seems I need to catch up with your (never ending and wonderful) advancements.

Thanks
 

alwaysbusy

Expert
Licensed User
Longtime User
@Harris This is an extension of the existing generator that also creates the code for a table view. It kind of closes the code generator full circle. Pressing the '+' button uses the code for the generated modal sheet, edit and delete buttons the other modal sheets. It may give you a base to start with. It creates a basic table view (with search and pagination capabilities) for the database record you defined to generate the modal sheets. It uses the same fields.
 

Harris

Expert
Licensed User
Longtime User
Sweet..., table and modal sheets. I shall definitely check it out.

Like many; if no one ever proposes a feature - how are we to know the ways to improve our product?
CRUD Gen is a case in point. You have taken a vague suggestion to a VERY powerful addition.

Less code I write, less mistakes and debugging.
I was most happy with modal sheets but how can I argue with table creation as well (just can't)?

Continue to amaze us...

Quite frankly, without AMB (and B4J / B4A), my project (and income) would be no-where.
I still pinch myself to realize how easy this is to create real world apps with these frameworks.

Thanks
 
Top