B4J Library [ABMaterial] Creating ABMModalSheets at runtime: Part 2

Ola

The first post about this topic just touched the tip of the iceberg about this. I realize that I have more challenges that I need to address and I can only do justice to this if I try to cover most of the components that could be used for input. These are..

1. Email - check
2. Website - check
3. Telephone - check
4. File Input - check
5. SignaturePad - check
6. PatternLock - partial check
7. Editor - check
8. Image - check
9. RadioGroup - check
10. Buttons - check


What are we going to learn/have we learned?

1. How to create ABMComponents for our pages, container and or modal sheets and place them at various locations
2. How to get the contents of our components using ABM getter methods. Each component has its own unique getter/setter methods and save these to a map

Please note: creation of ABM components is already taking shape during runtime in the ConnectPage method of your page.

The reason for the partial check on the patternlock is i need to find a way of reading the pattern outside of the change_event. For example, the ABMFileInput has a .GetFileName method which returns the filename selected. The current implementation of the ABMPatternLock does not have a similar method to get an entered pattern, you get a pattern on the _changed event. Yes you can trap this event and save the pattern somewhere in a variable, but just like the ABMFileInput, at times, you dont want to do a fileupload on change of the file name, but only until a user confirms so, for example a button click event, which will come handy for these runtime things im trying to achieve.


Anyway, this second part talks about the controls above. I need a way to generate my wizard forms at runtime, my ABMTabs contents at runtime and some containers randomly, this deciding to extend this to include other components. Off course you can extend this to fit your needs.

Just like before, I have a button on my page to create a modal sheet and then add the controls. I want the fileupload to the server to only happen when I click the ok button on my modal sheet. This works very well and the entered signature is saved to a jpg file as expected. I will look into the pattern lock soon enough.

B4X:
Sub btnMdl1_Clicked(Target As String)
    mymdl1.Initialize(page,theme,"simplelogin1",ABM.MODALSHEET_SIZE_FULL,ABM.MODALSHEET_TYPE_NORMAL,False,"id","users","Additional Modal")
    mymdl1.IsTextSelectable = False
    mymdl1.IsDismissible = False
    mymdl1.ForceLeft = True
    mymdl1.CenterHeading = True
    mymdl1.WhiteHeading = True
    mymdl1.AddImage("img","Image","../images/sponge.png",1,2,0,0,0,12,3,3).SetImageFixedSize("img",100,100).SetImage("img",True,False,False,1,False,ABM.ZDEPTH_2)
    mymdl1.AddFileInput("upl","Select Profile Picture",1,3,0,0,0,12,3,3).SetFileInput("upl",ABM.VISIBILITY_HIDE_ALL,True)
    mymdl1.AddSignaturePad("sig",1,4,0,0,0,3,3,3,True).SetSignaturePad("sig",100,200,ABM.COLOR_WHITE,ABM.INTENSITY_NORMAL,ABM.COLOR_BLACK,ABM.INTENSITY_NORMAL,ABM.ZDEPTH_1)
    mymdl1.AddPatternLock("ptn",3,1,5,0,0,0,3,3,3,True)
    mymdl1.AddPassword("password","Password","",2,1,0,0,0,12,6,6,True).AddEmail("email","Email","",2,2,0,0,0,12,6,6,True)
    mymdl1.AddTelephone("telephone","Telephone","",3,1,0,0,0,12,6,6,True).AddWebsite("website","Website","",3,2,0,0,0,12,6,6,True)
    mymdl1.AddCheckBox("chk","ABMCheckBox","1",4,1,0,0,0,12,6,6).AddSwitch("swt","ABMSwitch","0",4,2,0,0,0,12,6,6)
    mymdl1.AddComboBox("cbo","ABMComboBox","",5,1,0,0,0,12,6,6,True).AddRadioGroup("rad","ABMRadioGroup","",5,2,0,0,0,12,6,6)
    mymdl1.AddRadioGroupItem("rad","Male",True,True).AddRadioGroupItem("rad","Female",True,True)
    'mymdl1.AddEditor("editor","Editor","Mashy",6,1,1,1,1,11,11,11,False)
    'mymdl1.AddButton("raised","Raised Button",7,1,0,0,0,4,4,4)
    'mymdl1.AddFlatButton("flat","Flat Button",7,2,0,0,0,4,4,4).SetButton("flat","","","",ABM.BUTTONSIZE_LARGE,True)
    'mymdl1.AddFloatingButton("floating","mdi-editor-mode-edit",7,3,0,0,0,4,4,4)
    mymdl1.show
End Sub

Naming Conventions

As the modal sheet name is 'simplelogin1' each component added will be prefixed by that name and also a prefix per name of the component.

B4X:
private Sub ComponentPrefixInit
    ComponentPrefix.Initialize
    ComponentPrefix.put("ABMPatternLock", "ptn")
    ComponentPrefix.put("ABMSignaturePad", "sig")
    ComponentPrefix.put("ABMSocialShare", "socshare")
    ComponentPrefix.put("ABMImageSlider", "imgsld")
    ComponentPrefix.put("ABMFileInput", "file")
    ComponentPrefix.put("ABMGoogleMap", "gmap")
    ComponentPrefix.put("ABMImage", "img")
    ComponentPrefix.put("ABMRadioGroup", "rg")
    ComponentPrefix.put("ABMButton", "btn")
    ComponentPrefix.put("ABMSlider", "slider")
    ComponentPrefix.put("ABMEditor", "editor")
    ComponentPrefix.put("ABMRange", "range")
    ComponentPrefix.put("MashClock", "clock")
    ComponentPrefix.put("ABMLabel", "lbl")
    ComponentPrefix.put("ABMInput", "txt")
    ComponentPrefix.put("ABMCombo", "cbo")
    ComponentPrefix.put("ABMCheckBox", "chk")
    ComponentPrefix.put("ABMSwitch", "sw")
    ComponentPrefix.put("ABMDateTimeScroller", "ds")
    ComponentPrefix.put("ABMDateTimePicker", "dp")
    ComponentPrefix.put("ABMUpload", "up")
End Sub

If you dont want the prefixes on the names, you can turn the property UseControlPrefixes to false as by defaults its on.

Lets look at the code

ABMImage

B4X:
mymdl1.AddImage("img","Image","../images/sponge.png",1,2,0,0,0,12,3,3).SetImageFixedSize("img",100,100).SetImage("img", True,False,False,1,False,ABM.ZDEPTH_2)

The image is being added at R1C2, no offsets, and sizes 12,3,3 for small, medium and large devices respectively. I am fixing the size to be 100 width and 100 height. Im also setting other image properties like circle, clickable,responsive, materialboxed etc etc. At each stage I am passing the assigned name of 'img' as that I will use for my component id.

ABMFileInput

B4X:
mymdl1.AddFileInput("upl","Select Profile Picture",1,3,0,0,0,12,3,3).SetFileInput("upl",ABM.VISIBILITY_HIDE_ALL,True)

Next to the image is a FileInput component. This is set at R1C3 also with 12,3,3 size. The input part of the control should be hidden.

ABMSignaturePad

B4X:
mymdl1.AddSignaturePad("sig",1,4,0,0,0,3,3,3,True).SetSignaturePad("sig",100,200,ABM.COLOR_WHITE,ABM.INTENSITY_NORMAL,ABM.COLOR_BLACK,ABM.INTENSITY_NORMAL,ABM.ZDEPTH_1)

At R1C4 is a signature pad, then the width and height are set with the respective colors with a shadow equal to 1.

ABMPatternLock

B4X:
mymdl1.AddPatternLock("ptn",3,1,5,0,0,0,3,3,3,True)

At R1C5 a pattern lock is added with a matrix size of 3. The true at the end is for Required/Compulsory. For anything compulsory, the formdata should not be saved for example and I need to indicate to the end user that such is required. For example I can have two pattern locks, one for registration and nother for confirm accuracy of the entered pattern etc etc.

ABMInput - Password & Email

B4X:
mymdl1.AddPassword("password","Password","",2,1,0,0,0,12,6,6,True).AddEmail("email","Email","",2,2,0,0,0,12,6,6,True)

An input control with a password type sits at R2C1, this spans 6 columns for medium and large devices whilst for small devices it takes 12 cells span. Also in the same line is an email control sitting at R2C2.

ABMInput - Telephone & Website

B4X:
mymdl1.AddTelephone("telephone","Telephone","",3,1,0,0,0,12,6,6,True).AddWebsite("website","Website","",3,2,0,0,0,12,6,6,True)

The telephone input control is sitting at R3C1 whilst a website control sits at R3C2 also spanning 6 cells.

ABMCheckBox & ABMSwitch

B4X:
mymdl1.AddCheckBox("chk","ABMCheckBox","1",4,1,0,0,0,12,6,6).AddSwitch("swt","ABMSwitch","0",4,2,0,0,0,12,6,6)

The next line has a checkbox and a switch. These two controls when sitting on a centered on page modal needs to be nudged to the right. This can be done by setting the PaddingLeft property of both to 10 to make them sit properly. As noted these should sit in R4C1 and R4C2 respectively, spanning 6 cells each.

ABMCombo & ABMRadioGroup

B4X:
mymdl1.AddComboBox("cbo","ABMComboBox","",5,1,0,0,0,12,6,6,True).AddRadioGroup("rad","ABMRadioGroup","",5,2,0,0,0,12,6,6)

This line adds a combo and radiogroup to R5 each spanning 6 cells. The radio group items are added on the next line with..

B4X:
mymdl1.AddRadioGroupItem("rad","Male",True,True).AddRadioGroupItem("rad","Female",True,True)

and these are both enabled and no line breaks inbetween.

ABMEditor

B4X:
mymdl1.AddEditor("editor","Editor","Mashy",6,1,1,1,1,11,11,11,False)

For the editor, I have specified a padding of 1 unit/cell for all the devices, meaning that the size should be 11 for each of the devices.

ABMButton

To add the three types of buttons, I have defined simple methods..

B4X:
mymdl1.AddButton("raised","Raised Button",7,1,0,0,0,4,4,4)
    mymdl1.AddFlatButton("flat","Flat Button",7,2,0,0,0,4,4,4).SetButton("flat","","","",ABM.BUTTONSIZE_LARGE,True)
    mymdl1.AddFloatingButton("floating","mdi-editor-mode-edit",7,3,0,0,0,4,4,4)

This will add a normal raised button, a flat button and a floating button respectively. These are sitting in R7 at cell positions 1,2 and 3.

When complete the modal sheet looks like this..

Part2.png


The flat button using UseFullCellWidth took the complete width of the cell and the button size was set to be larger..

So, when the save button is clicked, a couple of things should happen.

1. If there is a file selected, this should be imported to the server
2. For the signature, this should also be imported to the server.
3. The pattern should also be saved (this to be addressed easily)
4. The data to be returned as a map.

This is achieved by this method here. This uses the specified unique field named for each of the controls and returns the entered data.

B4X:
' get data from any container
Sub GetContainerData(mdlc As ABMContainer) As Map
    Dim m As Map: m.initialize
    Dim controlKey As String
    Dim controlPrefix As String
    Dim controlType As String
    ' we will add the controls in sequence
    For Each rc As String In sortItL
        ' get the component definition
         Dim ec As EachComponent = sortitM.Get(rc)
         ' get the control type
         controlType = ComponentLinks.Getdefault(ec.TypeOf,"")
         ' get the control prefix
         controlPrefix = ComponentPrefix.getdefault(controlType,"")
         If UseControlPrefixes = False Then controlPrefix = ""
         controlKey = $"${ModalSheetName}${controlPrefix}${ec.FieldName}"$
         ' get the component type
         Select Case ec.TypeOf
         Case "ABM.GEN_EDITOR"
             Dim edt As ABMEditor = mdlc.Component(controlKey)
            m.Put(ec.FieldName,edt.GetHTML)
         Case "ABM.GEN_IMG"
             Dim img As ABMImage = mdlc.Component(controlKey)
            m.Put(ec.FieldName,img.Tag)
         Case "ABM.GEN_RADIO"
             Dim rad As ABMRadioGroup = mdlc.Component(controlKey)
            m.Put(ec.FieldName,rad.GetActive)
         Case "ABM.GEN_CHECKBOX"
             Dim chkcomponent As ABMCheckbox = mdlc.Component(controlKey)
            m.Put(ec.FieldName,chkcomponent.State)
         Case "ABM.GEN_COMBOSQL"
             Dim cbocomponent As ABMCombo = mdlc.Component(controlKey)
            m.Put(ec.FieldName,cbocomponent.GetActiveItemId)
         Case "ABM.GEN_DATE_PICK"
             Dim dp As ABMDateTimePicker = mdlc.Component(controlKey)
            m.Put(ec.FieldName,dp.GetDate)
         Case "ABM.GEN_DATE_SCROLL"
             Dim ds As ABMDateTimeScroller = mdlc.Component(controlKey)
            m.Put(ec.FieldName,ds.GetDate)
         Case "ABM.GEN_DATETIME_PICK"
             Dim dtp As ABMDateTimePicker = mdlc.Component(controlKey)
            m.Put(ec.FieldName,dtp.GetDate)
         Case "ABM.GEN_DATETIME_SCROLL"
             Dim dts As ABMDateTimeScroller = mdlc.Component(controlKey)
            m.Put(ec.FieldName,dts.GetDate)
         Case "ABM.GEN_DOUBLE","ABM.GEN_INTEGER","ABM.GEN_TEXT","ABM.GEN_NONE","ABM.GEN_TEXTAREA","ABM.GEN_TEL","ABM.GEN_EMAIL","ABM.GEN_PASSWORD","ABM.GEN_WEBSITE"
             Dim txt As ABMInput = mdlc.Component(controlKey)
            m.Put(ec.FieldName,txt.Text)
         Case "ABM.GEN_SWITCH"
             Dim swt As ABMSwitch = mdlc.Component(controlKey)
            m.Put(ec.FieldName,swt.State)
        Case "ABM.GEN_TIME_PICK"
             Dim dtp As ABMDateTimePicker = mdlc.Component(controlKey)
            m.Put(ec.FieldName,dtp.GetDate)
        Case "ABM.GEN_TIME_SCROLL"
             Dim dts As ABMDateTimeScroller = mdlc.Component(controlKey)
            m.Put(ec.FieldName,dts.GetDate)
        Case "ABM.GEN_FILEINPUT"
            Dim inp As ABMFileInput = mdlc.Component(controlKey)
            'save the file name
            m.Put(ec.FieldName,inp.GetFileName)
            'upload to the server
            If inp.GetFileName.Length > 0 Then
                inp.UploadToServer
            End If
        Case "ABM.GEN_SIGNATURE"
            'save the signature
            m.Put(ec.FieldName,IDFieldName & ".jpg")  
            Dim sig As ABMSignaturePad = mdlc.Component(controlKey)
            sig.GetDrawingURI(IDFieldName & ".jpg")
        Case "ABM.GEN_PATTERNLOCK"
            Dim pl As ABMPatternLock = mdlc.Component(controlKey)
           
        End Select
    Next
    Return m
End Sub


The code to build each component during runtime has followed the normal specs of how ABM works when one is defining controls.

B4X:
' use already sorted components
private Sub BuildControls(mdl As ABMContainer)
    Dim controlKey As String
    Dim controlPrefix As String
    Dim controlType As String
    ' we will add the controls in sequence
    For Each rc As String In sortItL
        ' get the component definition
         Dim ec As EachComponent = sortitM.Get(rc)
         ' get the control type
         controlType = ComponentLinks.Getdefault(ec.TypeOf,"")
         ' get the control prefix
         controlPrefix = ComponentPrefix.getdefault(controlType,"")
         If UseControlPrefixes = False Then controlPrefix = ""
         controlKey = $"${ModalSheetName}${controlPrefix}${ec.FieldName}"$
         'check if we have a fixed height
         If ec.SetFixedHeight Then
             mdl.Cell(ec.Row,ec.Cell).SetFixedHeight(ec.Height,ec.ScrollIfBigger)
        End If
         ' get the component type
         Select Case ec.TypeOf
         Case "ABM.GEN_PATTERNLOCK"
             Dim pl As ABMPatternLock
            pl.Initialize(pg,controlKey, ec.Label,"")
            pl.Visibility = ec.Visibility
            mdl.Cell(ec.row,ec.cell).AddComponent(pl)
         Case "ABM.GEN_SIGNATURE"
             Dim sig As ABMSignaturePad
            sig.Initialize(pg,controlKey,ec.Width,ec.Height,ec.clearColor,ec.clearColorIntensity,ec.penColor,ec.penColorIntensity,ec.ZDepth)
            sig.Visibility = ec.Visibility
            mdl.Cell(ec.row,ec.cell).AddComponent(sig)
         Case "ABM.GEN_FILEINPUT"
             Dim finp As ABMFileInput
            finp.Initialize(pg,controlKey,"",ec.Label,True,"","")
            finp.Visibility = ec.Visibility
            finp.InputFieldVisibility = ec.InputFieldVisibility
            If ec.UseFullCellWidth Then
                '***
            End If
            mdl.Cell(ec.row,ec.cell).AddComponent(finp)
          Case "ABM.GEN_FLAT"
             Dim btnFlat As ABMButton
            btnFlat.InitializeFlat(pg,controlKey,"","",ec.Label,"")
            btnFlat.Enabled = ec.Enabled
            btnFlat.Visibility = ec.Visibility
            btnFlat.IconName = ec.IconName
            btnFlat.IconAwesomeExtra = ec.IconAwesomeExtra
            btnFlat.IconAlign = ec.IconAlign
            btnFlat.Size = ec.Size
            btnFlat.UseFullCellWidth = ec.UseFullCellWidth
            mdl.Cell(ec.row,ec.cell).AddComponent(btnFlat)
         Case "ABM.GEN_RAISED"
            Dim btnRaised As ABMButton
            btnRaised.InitializeRaised(pg,controlKey,"","",ec.Label,"")
            btnRaised.Enabled = ec.Enabled
            btnRaised.Visibility = ec.Visibility
            btnRaised.IconName = ec.IconName
            btnRaised.IconAwesomeExtra = ec.IconAwesomeExtra
            btnRaised.IconAlign = ec.IconAlign
            btnRaised.Size = ec.Size
             btnRaised.UseFullCellWidth = ec.UseFullCellWidth
            mdl.Cell(ec.row,ec.cell).AddComponent(btnRaised)
         Case "ABM.GEN_FLOATING"
            Dim btnFloating As ABMButton
            btnFloating.InitializeFloating(pg,controlKey,ec.Label,"")
            btnFloating.Enabled = ec.Enabled
            btnFloating.Visibility = ec.Visibility
            btnFloating.IconName = ec.label
            If ec.bUpdated Then btnFloating.IconName = ec.iconname
            btnFloating.IconAwesomeExtra = ec.IconAwesomeExtra
            btnFloating.IconAlign = ec.IconAlign
            btnFloating.Size = ec.Size
             mdl.Cell(ec.row,ec.cell).AddComponent(btnFloating)
         Case "ABM.GEN_IMG"
             Dim ctl As ABMImage
            ctl.Initialize(pg,controlKey,ec.DefaultValue,ec.Opacity)
            ctl.Visibility = ec.Visibility
            ctl.Caption = ec.Label
            ctl.Alt = ec.Label
            ctl.Tag = ec.label
            If ec.SetFixedSize Then
                ctl.SetFixedSize(ec.Width,ec.Height)
            End If
            ctl.IsCircular = ec.IsCircular
            ctl.IsClickable = ec.IsClickable
            ctl.IsMaterialBoxed = ec.IsMaterialBoxed
            ctl.IsResponsive = ec.IsResponsive
            ctl.ZDepth = ec.zdepth    
            mdl.Cell(ec.row,ec.cell).AddComponent(ctl)
         Case "ABM.GEN_EDITOR"
             Dim edt As ABMEditor
            edt.Initialize(pg,controlKey,True,True,"")
            edt.Enabled = ec.Enabled
            'edt.ForceMinimalInitialHeight = True
            edt.Visibility = ec.Visibility
            edt.SetHTML(ec.DefaultValue)
            mdl.Cell(ec.row,ec.cell).AddComponent(edt)
         Case "ABM.GEN_RADIO"
             Dim rad As ABMRadioGroup
            rad.Initialize(pg,controlKey,"")
            rad.Enabled = ec.Enabled
            rad.Title = ec.Label
            rad.Visibility = ec.visibility
            'add each of the items
            For Each rgi As Map In ec.RadioOptions
                Dim icap As String = rgi.Get("caption")
                Dim ben As Boolean = rgi.Get("enabled")
                Dim nlb As Boolean = rgi.Get("nolinebreaks")
                If nlb = False Then
                    rad.AddRadioButton(icap,ben)
                Else
                    rad.AddRadioButtonNoLineBreak(icap,ben)
                End If
            Next
            mdl.Cell(ec.row,ec.cell).AddComponent(rad)
         Case "ABM.GEN_CHECKBOX"
             Dim chkcomponent As ABMCheckbox
            chkcomponent.Initialize(pg,controlKey,ec.Label,False,"")
            chkcomponent.Enabled = ec.Enabled
            chkcomponent.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(chkcomponent)
         Case "ABM.GEN_COMBOSQL"
             Dim cbocomponent As ABMCombo
            cbocomponent.Initialize(pg,controlKey,ec.Label,650,"")
            cbocomponent.Enabled = ec.Enabled
            cbocomponent.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(cbocomponent)
         Case "ABM.GEN_DATE_PICK"
             Dim dp As ABMDateTimePicker
            dp.Initialize(pg,controlKey,ABM.DATETIMEPICKER_TYPE_DATE,DateTime.Now,ec.Label,"")
            dp.Enabled = ec.Enabled
            dp.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(dp)
         Case "ABM.GEN_DATE_SCROLL"
             Dim ds As ABMDateTimeScroller
            ds.Initialize(pg,controlKey,ABM.DATETIMESCROLLER_TYPE_DATE,ABM.DATETIMESCROLLER_MODE_MIXED,DateTime.Now,ec.Label,"")
            ds.Enabled = ec.Enabled
            ds.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(ds)
         Case "ABM.GEN_DATETIME_PICK"
             Dim dtp As ABMDateTimePicker
            dtp.Initialize(pg,controlKey,ABM.DATETIMEPICKER_TYPE_DATETIME,DateTime.Now,ec.Label,"")
            dtp.Enabled = ec.Enabled
            dtp.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(dtp)
         Case "ABM.GEN_DATETIME_SCROLL"
             Dim dts As ABMDateTimeScroller
            dts.Initialize(pg,controlKey,ABM.DATETIMESCROLLER_TYPE_DATETIME,ABM.DATETIMESCROLLER_MODE_MIXED,DateTime.Now,ec.Label,"")
            dts.Enabled = ec.Enabled
            dts.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(dts)
         Case "ABM.GEN_DOUBLE","ABM.GEN_INTEGER"
             Dim txt As ABMInput
            txt.Initialize(pg,controlKey,ABM.INPUT_NUMBER,ec.Label,False,"")
            txt.Enabled = ec.enabled
            txt.Visibility = ec.Visibility
            mdl.Cell(ec.row,ec.cell).AddComponent(txt)
         Case "ABM.GEN_NONE"
             Dim txt As ABMInput
            txt.Initialize(pg,controlKey,ABM.INPUT_NUMBER,ec.Label,False,"")
            txt.Enabled = ec.enabled
            txt.Visibility = ec.Visibility
            mdl.Cell(ec.row,ec.cell).AddComponent(txt)
         Case "ABM.GEN_SWITCH"
             Dim swt As ABMSwitch
            swt.Initialize(pg,controlKey,ec.ontext,ec.offtext,False,"")
            swt.Enabled = ec.enabled
            swt.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(swt)
         Case "ABM.GEN_TEXT","ABM.GEN_TEL","ABM.GEN_WEBSITE","ABM.GEN_PASSWORD","ABM.GEN_EMAIL"
             Dim txtcomponent As ABMInput
            Select Case ec.TypeOf
            Case "ABM.GEN_TEXT"
                txtcomponent.Initialize(pg,controlKey,ABM.INPUT_TEXT,ec.Label,False,"")
            Case "ABM.GEN_TEL"
                txtcomponent.Initialize(pg,controlKey,ABM.INPUT_TEL,ec.Label,False,"")
            Case "ABM.GEN_WEBSITE"
                txtcomponent.Initialize(pg,controlKey,ABM.INPUT_URL,ec.Label,False,"")
            Case "ABM.GEN_PASSWORD"
                txtcomponent.Initialize(pg,controlKey,ABM.INPUT_PASSWORD,ec.Label,False,"")
            Case "ABM.GEN_EMAIL"
                txtcomponent.Initialize(pg,controlKey,ABM.INPUT_EMAIL,ec.Label,False,"")
            End Select
            txtcomponent.Enabled = ec.enabled
            txtcomponent.Visibility = ec.Visibility
            mdl.Cell(ec.row,ec.cell).AddComponent(txtcomponent)
         Case "ABM.GEN_TEXTAREA"
             Dim txtarea As ABMInput
            txtarea.Initialize(pg,controlKey,ABM.INPUT_TEXT,ec.Label,True,"")
            txtarea.Enabled = ec.enabled
            txtarea.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(txtarea)
         Case "ABM.GEN_TIME_PICK"
             Dim dtp As ABMDateTimePicker
            dtp.Initialize(pg,controlKey,ABM.DATETIMEPICKER_TYPE_TIME,DateTime.Now,ec.Label,"")
            dtp.Enabled = ec.Enabled
            dtp.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(dtp)
         Case "ABM.GEN_TIME_SCROLL"
             Dim dts As ABMDateTimeScroller
            dts.Initialize(pg,controlKey,ABM.DATETIMESCROLLER_TYPE_TIME,ABM.DATETIMESCROLLER_MODE_MIXED,DateTime.Now,ec.Label,"")
            dts.Enabled = ec.Enabled
            dts.Visibility = ec.Visibility
             mdl.Cell(ec.row,ec.cell).AddComponent(dts)
        End Select
    Next
End Sub

So when all the controls are added, the class .Show method is called. This executes this code..

B4X:
'show the modal sheet
Sub Show
    pg.AddModalSheetTemplate(BuildModalSheet)
    pg.refresh
    pg.ShowModalSheet(ModalSheetName)
End Sub

This adds the template we built, refreshes the page and shows the modal sheet.

When the save button is clicked, I return the modal sheet contents as a map that I can manipulate.

B4X:
(MyMap) {id=, img=Image, upl=96-usersthink-stock-image.jpg, sig=id.jpg, password=kjahsdhkHK, email=anele@mbangas.com, telephone=88189, website=http, chk=true, swt=true, cbo=-1, rad=1, editor=<div>Mashy<br></div>}


B4X:
Sub simplelogin1save_Clicked(Target As String)
    page.pause
    Dim record As Map = mymdl1.GetFormData
    page.resume
    Log(record)
End Sub

The method to hide the modal sheet is..

B4X:
Sub simplelogin1cancel_Clicked(Target As String)
    mymdl1.hide
End Sub

One could also trap the file input upload method by calling.

B4X:
Sub simplelogin1fileupl_Changed(value As String)
    Dim inp1 As ABMFileInput  = mymdl1.GetModalSheetFileInput("upl")
    If inp1.IsInitialized Then
        page.pause
        inp1.UploadToServer
        page.resume
    End If
End Sub

However this is built in to enable file uploads on click of the Save button.

I made changes to the class so that I can pass it a container. This will enable flexibility to create flexible footers and headers at some stage.
 

Attachments

  • MashForm.bas
    67.1 KB · Views: 472

Mashiane

Expert
Licensed User
Longtime User
Part2.gif


The next attempt is to create a container and add it to the modal sheet. The ABMRange and ABMSlider, dont have a title, so do make them appear they have, I have added them to a container. I also explored adding items to the ABMCombo. We also want to save the entered pattern.

'lets save the patternLock whenever it changes. We do this with .SetValue, that assigns the returned value of the PatternLock
B4X:
Sub simplelogin1ptn_Changed(target As String, value As String)
    mymdl1.Setvalue("ptn",value)
End Sub

We can also do this with the fileinput component and save the value to a class structure.. This saves the file name returned by the control.

B4X:
Sub simplelogin1upl_Changed(value As String)
    mymdl1.SetValue("upl",value)
End Sub

Let's also add items to the combo box, assuming they are coming from a database. These can be defined as a list of map records specifying the id and title fields.

B4X:
'set items for the combobox
    Dim lst As List
    lst.Initialize
    lst.add(CreateMap("id":-1,"title":""))
    lst.add(CreateMap("id":1,"title":"A"))
    lst.add(CreateMap("id":2,"title":"B"))
    lst.add(CreateMap("id":3,"title":"C"))
    lst.add(CreateMap("id":4,"title":"D"))
    lst.add(CreateMap("id":5,"title":"E"))
    mymdl1.SetCombo("cbo","id","title",lst,"-1")

We add an ABMSlider and an ABMRange control to our modalsheet.

B4X:
mymdl1.AddRange("range1","ABMRange",6,1,0,0,0,12,6,6).SetPadding("range1",0,0,10,10)
    mymdl1.AddSlider("slider1",6,2,0,0,0,12,6,6).SetPadding("slider1",0,0,20,20)

After a couple of changes, creating a container component that sits inside another is rather easy, this is with the slider and range components that we want to have titles. One should note that with these controls the padding becomes a little tricky due to CenterInPage when adding rows. To do this we can define as MashForm, add a range / slider to it then add this MashForm into another MashForm.

B4X:
Dim mfrange As MashForm
    mfrange.Initialize(page,"msrange","ABMRange")
    mfrange.CenterInPage = False
    mfrange.AddRange("range","ABMRange",2,1,0,0,0,12,12,12).SetPadding("range",0,0,10,10)
    
    Dim crange As ABMContainer = mfrange.BuildContainer("Loan Amount")
    mymdl1.AddContainer("range",crange,7,1,0,0,0,12,6,6).SetPadding("range",0,0,10,10)


I have defined a mfrange as a MashForm, I indicate that everything in it should not be CenteredInPage i.e. CenterInPage = false, then I add a range control to it.

The next step is defining the container that will house the mfrange MashForm. The ABMRange control is being added at R2C1 of the form / container. as we want some space between the container title and the control. I then build the container by calling BuildContainer with title 'Loan Amount" and then add this container to the parent modal sheet.

The same is with the slider..

B4X:
Dim mfslider As MashForm
    mfslider.Initialize(page,"msslider","ABMSlider")
    mfslider.CenterInPage = False
    mfslider.AddSlider("slider",2,1,0,0,0,12,12,12).SetPadding("slider",0,0,10,10)
    
    Dim cslider As ABMContainer = mfslider.BuildContainer("Payment Period")
    mymdl1.AddContainer("slider",cslider,7,2,0,0,0,12,6,6)
    mymdl1.SetPadding("slider",0,0,20,20)

From this above, it is clear that for the MashForm class to work, it needs to be flexible enough to build containers that can he housed by other components.

In Part 3, we will look at creating more complex components using containers.
 

Mashiane

Expert
Licensed User
Longtime User
The above two methods to add a titled range / slider have shortcuts. These are

B4X:
mymdl1.AddRange1("loanamount","Loan Amount",5,50,0,100,5,True,8,1,0,0,0,12,6,6)
    mymdl1.AddSlider1("paymentperiod","Payment Period",6,0,100,2,True,8,2,0,0,0,12,6,6)

As a result, adding them like this ensures that their values are returned as part of the map when the form results are being read.

shortcut.png


The final code for the new modal sheet is..

B4X:
Sub btnMdl1_Clicked(Target As String)
    mymdl1.Initialize(page,"simplelogin1","Additional Modal").SetModalSheet(theme,ABM.MODALSHEET_SIZE_FULL,ABM.MODALSHEET_TYPE_NORMAL,False,"id","users")
    mymdl1.IsTextSelectable = False
    mymdl1.IsDismissible = False
    mymdl1.ForceLeft = True
    mymdl1.CenterHeading = True
    mymdl1.WhiteHeading = True
    mymdl1.UseControlPrefixes = False
    'mymdl1.CenterInPage = False
    mymdl1.AddImage("img","Image","../images/sponge.png",1,2,0,0,0,12,3,3).SetImageFixedSize("img",100,100).SetImage("img", True, False,False,1,False,ABM.ZDEPTH_2).SetPadding("img",0,0,10,0)
    mymdl1.AddFileInput("upl","Select Profile Picture",1,3,0,0,0,12,3,3).SetFileInput("upl",ABM.VISIBILITY_HIDE_ALL,True)
    mymdl1.AddSignaturePad("sig",1,4,0,0,0,3,3,3,True).SetSignaturePad("sig",100,200,ABM.COLOR_WHITE,ABM.INTENSITY_NORMAL,ABM.COLOR_BLACK,ABM.INTENSITY_NORMAL,ABM.ZDEPTH_1)
    mymdl1.AddPatternLock("ptn",3,1,5,0,0,0,3,3,3,True)
    mymdl1.AddPassword("password","Password","",2,1,0,0,0,12,6,6,True).AddEmail("email","Email","",2,2,0,0,0,12,6,6,True)
    mymdl1.AddTelephone("telephone","Telephone","",3,1,0,0,0,12,6,6,True).AddWebsite("website","Website","",3,2,0,0,0,12,6,6,True)
    mymdl1.AddCheckBox("chk","ABMCheckBox","1",4,1,0,0,0,12,6,6).SetPadding("chk",0,0,10,0)
    mymdl1.AddSwitch("swt","ABMSwitch","0",4,2,0,0,0,12,6,6).SetPadding("swt",0,0,10,0)
    mymdl1.AddComboBox("cbo","ABMComboBox","",5,1,0,0,0,12,6,6,True).AddRadioGroup("rad","ABMRadioGroup","",5,2,0,0,0,12,6,6)
    mymdl1.AddRadioGroupItem("rad","Male",True,True).AddRadioGroupItem("rad","Female", True,True)
  
    'set items for the combobox
    Dim lst As List
    lst.Initialize
    lst.add(CreateMap("id":-1,"title":""))
    lst.add(CreateMap("id":1,"title":"A"))
    lst.add(CreateMap("id":2,"title":"B"))
    lst.add(CreateMap("id":3,"title":"C"))
    lst.add(CreateMap("id":4,"title":"D"))
    lst.add(CreateMap("id":5,"title":"E"))
    mymdl1.SetCombo("cbo","id","title",lst,"-1")
  
    mymdl1.AddRange("range1",6,1,0,0,0,12,6,6).SetPadding("range1",0,0,10,10)
    mymdl1.AddSlider("slider1",6,2,0,0,0,12,6,6).SetPadding("slider1",0,0,20,20)
  
    Dim mfrange As MashForm
    mfrange.Initialize(page,"range","ABMRange")
    mfrange.CenterInPage = False
    mfrange.AddRange("range",2,1,0,0,0,12,12,12).SetPadding("range",0,0,10,10) 
    Dim crange As ABMContainer = mfrange.BuildContainer("Loan Amount")
    mymdl1.AddContainer(mfrange.id,crange,7,1,0,0,0,12,6,6).SetPadding(mfrange.id,0,0,10,10)

    Dim mfslider As MashForm
    mfslider.Initialize(page,"slider","ABMSlider")
    mfslider.CenterInPage = False
    mfslider.AddSlider("slider",2,1,0,0,0,12,12,12).SetPadding("slider",0,0,10,10)
    Dim cslider As ABMContainer = mfslider.BuildContainer("Payment Period")
    mymdl1.AddContainer(mfslider.id,cslider,7,2,0,0,0,12,6,6).SetPadding(mfslider.id,0,0,20,20)
  
    mymdl1.AddRange1("loanamount","Loan Amount",5,50,0,100,5,True,8,1,0,0,0,12,6,6)
    mymdl1.AddSlider1("paymentperiod","Payment Period",6,0,100,2,True,8,2,0,0,0,12,6,6)
  

  
    'mymdl1.AddEditor("editor","Editor","Mashy",6,1,1,1,1,11,11,11,False)
    'mymdl1.AddButton("raised","Raised Button",7,1,0,0,0,4,4,4)
    'mymdl1.AddFlatButton("flat","Flat Button",7,2,0,0,0,4,4,4).SetButton("flat","","","",ABM.BUTTONSIZE_LARGE,True)
    'mymdl1.AddFloatingButton("floating","mdi-editor-mode-edit",7,3,0,0,0,4,4,4)
    mymdl1.show
End Sub


The Initialize method for the MashForm has been shortedned. This is due to the fact this the class should now work with both ABMContainers / ABMModalSheets components.

If a modal sheet will be used, ensure the .SetModalSheet method is called for the class. When building ABMContainers, the .BuildContainer method should be used to build the container based on the items added to the MashForm and this should be assigned to an ABMContainer component.

Returned map

B4X:
{
    "": "",
    "slider": com.ab.abmaterial.ABMContainer@5b239d7d,
    "img": "Image",
    "website": "",
    "range1": "0.0-100.0",
    "chk": false,
    "range": com.ab.abmaterial.ABMContainer@6572421,
    "loanamount": "5.0-50.0",
    "telephone": "",
    "ptn": null,
    "upl": "",
    "sig": "id.jpg",
    "paymentperiod": 6,
    "swt": false,
    "cbo": "-1",
    "password": "",
    "rad": 0,
    "email": "",
    "slider1": 0
}
 

Attachments

  • MashForm.bas
    81.6 KB · Views: 402
Top