B4J Question Understanding cell margins and padding

Rob White

Member
Licensed User
Hi all,
Here is a page which has helped me understand how margins and padding of ABM cells works.
B4X:
'Class module
Sub Class_Globals
    Private ws As WebSocket 'ignore
    ' will hold our page information
    Public page As ABMPage
    ' page theme
    Private theme As ABMTheme
    ' to access the constants
    Private ABM As ABMaterial 'ignore   
    ' name of the page, must be the same as the class name (case sensitive!)
    Public Name As String = "TstMargin"  '<-------------------------------------------------------- IMPORTANT
    ' will hold the unique browsers window id
    Private ABMPageId As String = ""
    ' your own variables
    Private Top As Int = 0   
    Private Pad As Int = 0

End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    ' build the local structure IMPORTANT!
    BuildPage       
End Sub

#Region ABM
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)   
    Log("Connected")
        
    ws = WebSocket1       
    
    ABMPageId = ABM.GetPageID(page, Name,ws)
    
    Dim session As HttpSession = ABM.GetSession(ws, ABMShared.SessionMaxInactiveIntervalSeconds)
    If session.IsNew Then
        session.Invalidate
        ABMShared.NavigateToPage(ws, "", "./")
        Return
    End If
        
    If ABMShared.NeedsAuthorization Then
        If session.GetAttribute2("IsAuthorized", "") = "" Then
            ABMShared.NavigateToPage(ws, ABMPageId, "../")
            Return
        End If
    End If       
    ABM.UpdateFromCache(Me, ABMShared.CachedPages, ABMPageId, ws)       
    If page.ComesFromPageCache Then
        ' when we have a page that is cached it doesn't matter if it comes or not from a new connection we serve the cached version.
        Log("Comes from cache")       
        page.Refresh       
        page.FinishedLoading       
    Else
        If page.WebsocketReconnected Then
            Log("Websocket reconnected")
            ' when we have a client that doesn't have the page in cache and it's websocket reconnected and also it's session is new - basically when the client had internet problems and it's session (and also cache) expired before he reconnected so the user has content in the browser but we don't have any on the server. So we need to reload the page.
            ' when a client that doesn't have the page in cache and it's websocket reconnected but it's session is not new - when the client had internet problems and when he reconnected it's session was valid but he had no cache for this page we need to reload the page as the user browser has content, reconnected but we have no content in cache
            ABMShared.NavigateToPage (ws, ABMPageId, "./" & page.PageHTMLName)
        Else
            ' when the client did not reconnected it doesn't matter if the session was new or not because this is the websockets first connection so no dynamic content in the browser ... we are going to serve the dynamic content...
            Log("Websocket first connection")
            page.Prepare
            ConnectPage           
        End If
    End If
    Log(ABMPageId)       
End Sub

Private Sub WebSocket_Disconnected
    Log("Disconnected")
End Sub

Sub Page_ParseEvent(Params As Map)
    Dim eventName As String = Params.Get("eventname")
    Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
    
    #If DEBUG
'    Log($"Evt fired --->${eventName} Number params = ${Params.Size}"$)
'    For i = 0 To Params.Size-1
'        Log($"    Key = ${Params.GetKeyAt(i)}, value = ${Params.GetValueAt(i)}"$)
'    Next
    Log("-----------------------------------------------------")
    #End if
    If eventName = "beforeunload" Then
        Log("preparing for url refresh")
        ABM.RemoveMeFromCache(ABMShared.CachedPages, ABMPageId)
        Return
    End If
    Dim caller As Object = page.GetEventHandler(Me, eventName)
    If caller = Me Then
        If SubExists(Me, eventName) Then
            Params.Remove("eventname")
            Params.Remove("eventparams")
            If eventName = "page_dropped" Then
                page.ProcessDroppedEvent(Params)
            End If
            Select Case Params.Size
                Case 0
                    CallSub(Me, eventName)
                Case 1
                    CallSub2(Me, eventName, Params.Get(eventParams(0)))
                Case 2
                    If Params.get(eventParams(0)) = "abmistable" Then
                        Dim PassedTables As List = ABM.ProcessTablesFromTargetName(Params.get(eventParams(1)))
                        CallSub2(Me, eventName, PassedTables)
                    Else
                        CallSub3(Me, eventName, Params.Get(eventParams(0)), Params.Get(eventParams(1)))
                    End If
                Case Else
                    ' cannot be called directly, to many param
                    CallSub2(Me, eventName, Params)
            End Select
        End If
    Else
        CallSubDelayed2(caller, "ParseEvent", Params) 'ignore
    End If
End Sub

public Sub BuildTheme()
    ' start with the base theme defined in ABMShared
    theme.Initialize("pagetheme")
    theme.AddABMTheme(ABMShared.MyTheme)

    ' add your specific page themes
    
End Sub

public Sub BuildPage()
    ' initialize the theme
    BuildTheme
    
    ' initialize this page using our theme
    page.InitializeWithTheme(Name, "/ws/" & ABMShared.AppName & "/" & Name, False, ABMShared.SessionMaxInactiveIntervalSeconds, theme)
    page.ShowLoader=True
    page.PageHTMLName = "index.html"
    page.PageTitle = "Template"
    page.PageDescription = "Template"
    page.PageKeywords = ""
    page.PageSiteMapPriority = ""
    page.PageSiteMapFrequency = ABM.SITEMAP_FREQ_YEARLY
        
    page.ShowConnectedIndicator = True
    page.ShowGridInfo = True
                
#Region NOT SAVED: 2021-07-08T09:30:25
    'PHONE
    '╔═══════════════════════════════════════════════════════════════════════════════════╗
    '║ 1,1                                                                               ║
    '╠═══════════════════════════════════════════════════════════════════════════════════╣
    '║ 2,1                                                                               ║
    '╠═══════════════════════════════════════════════════════════════════════════════════╣
    '║ 3,1                                                                               ║
    '╠═══════════════════════════════════════════════════════════════════════════════════╣
    '║ 4,1                                                                               ║
    '╚═══════════════════════════════════════════════════════════════════════════════════╝

    'TABLET
    '╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════╗
    '║ 1,1                                                                                                       ║
    '╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════╣
    '║ 2,1                                                                                                       ║
    '╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════╣
    '║ 3,1                                                                                                       ║
    '╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════╣
    '║ 4,1                                                                                                       ║
    '╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════╝

    'DESKTOP
    '╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
    '║ 1,1                                                                                                                               ║
    '╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
    '║ 2,1                                                                                                                               ║
    '╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
    '║ 3,1                                                                                                                               ║
    '╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
    '║ 4,1                                                                                                                               ║
    '╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

    page.AddRows(5,True,"").AddCells12(1,"")
    page.BuildGrid ' IMPORTANT!
#End Region
End Sub

public Sub ConnectPage()
    
    Dim TstInp As ABMInput
    TstInp.Initialize(page,"TstInp",ABM.INPUT_TEXT,"Reference cell. Note cell(4,1) has .MarginLeft = 30px & .PaddingLeft = 30px",False,"mytheme")
    page.Cell(1,1).AddComponent(TstInp)
    
    Dim TstInp2 As ABMInput
    TstInp2.Initialize(page,"TstInp2",ABM.INPUT_TEXT,"Test cell",False,"mytheme")
    page.Cell(2,1).AddComponent(TstInp2)
    Log("TopPadding = "&page.Cell(2,1).PaddingTop)
    Log("BottomPadding = "&page.Cell(2,1).PaddingBottom)
    Dim up As ABMButton
    up.InitializeRaised(page,"Up","","","Cell.TopMargin increase","")
    page.Cell(3,1).AddComponent(up)
    
    Dim Dwn As ABMButton
    Dwn.InitializeRaised(page,"Dwn","","","Cell.TopMargin decrease","")
    page.Cell(3,1).AddComponent(Dwn)
    
    Dim Padup As ABMButton
    Padup.InitializeRaised(page,"Padup","","","Cell.TopPadding increase","")
    page.Cell(4,1).AddComponent(Padup)
    
    Dim PadDwn As ABMButton
    PadDwn.InitializeRaised(page,"PadDwn","","","Cell.TopPadding decrease","")
    page.Cell(4,1).AddComponent(PadDwn)
    ' Bottom cell has following set
    page.Cell(4,1).MarginLeft = "30px"
    page.Cell(4,1).PaddingLeft = "30px"
    
    Dim Edt As ABMEditor
    Edt.Initialize(page,"Edt",True,False,"")
    Dim Notes As String = $"<p>Notes :- </p><p>1] Padding does not change below 0</p>
    <p>2] There is a MarginLeft = 30px AND a PaddingLeft$ = 30px set on cell(4,1) </p>"$
    Edt.SetHTML(Notes)
    page.Cell(5,1).AddComponent(Edt)
    
    ' refresh the page
    page.Refresh
    
    ' Tell the browser we finished loading
    page.FinishedLoading
    ' restoring the navigation bar position
    page.RestoreNavigationBarPosition   
End Sub
#end region

Sub up_clicked(target As String)
    Dim inp As ABMInput = page.Component("TstInp2")
    Top = Top + 1
    page.Cell(2,1).MarginTop= Top&"px"
    page.Refresh
    inp.Text=$"Top margin = ${Top} Top padding = ${Pad}"$
    Log("Top = "&Top)
End Sub

Sub padup_clicked(target As String)
    Dim inp As ABMInput = page.Component("TstInp2")
    Pad = Pad + 1
    page.Cell(2,1).PaddingTop= Pad&"px"
    inp.Text=$"Top margin = ${Top} Top padding = ${Pad}"$
    page.Refresh
    Log("Pad = "&Pad)
End Sub

Sub dwn_clicked(target As String)
    Dim inp As ABMInput = page.Component("TstInp2")
    Top = Top - 1
    page.Cell(2,1).MarginTop= Top&"px"
    page.Refresh
    inp.Text=$"Top margin = ${Top} Top padding = ${Pad}"$
    Log("Top = "&Top)
End Sub

Sub paddwn_clicked(target As String)
    Dim inp As ABMInput = page.Component("TstInp2")
    Pad = Pad - 1
    page.Cell(2,1).PaddingTop= Pad&"px"
    inp.Text=$"Top margin = ${Top} Top padding = ${Pad}"$
    page.Refresh
    Log("Pad = "&Pad)
End Sub

#Region ABMPage
' clicked on the navigation bar
Sub Page_NavigationbarClicked(Action As String, Value As String)
    ' saving the navigation bar position
    page.SaveNavigationBarPosition
    If Action = "LogOff" Then
        ABMShared.LogOff(page)
        Return
    End If

    ABMShared.NavigateToPage(ws, ABMPageId, Value)
End Sub

Sub Page_DebugConsole(message As String)
    Log("---> " & message)
End Sub
#end region

It has also made me think about a tool which would allow me to "drive" these settings by buttons. It would make things so much faster to format.
Does anyone know if such a tool exists? I was thinking of a ABMModalSheet but I am not sure if it can be made dragable so you could see all cells. There may also be issues with using page.ShowGridInfo = True.
Output of tool could be a list similar to:-
page.Cell(4,1).MarginLeft = "30px"
page.Cell(4,1).PaddingLeft = "30px" etc.

Any comments?
 

Harris

Expert
Licensed User
Longtime User
Prefix issue with [ABMaterial]... for more results...
Have you used the grid tool Alain built (I have never)? Looked at it but can't recall if contains margin and padding attributes...
 
Upvote 0

Rob White

Member
Licensed User
Yes I have used it and there are settings to the left of the main layout.
I have to admit not having played with these. I will but it is a very slow turn around.

I was thinking of inserting some code into the page so you could see the effects immediately.
No expert here but I do not think it would be too intrusive.
As I said above it would need to be a movable window and I do not know how to do that.
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
I was thinking of inserting some code into the page so you could see the effects immediately.
You may, but you would probably have to re-init it and refresh to see results...
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Modalsheets are fixed to the specified demensions, they dont float, that i know of.
Maybe refresh the page?
What is the purpose of adjusting margins and padding after page had been built? Could not these values be determined before a connectpage? We are essentially working with javascript here and it wants to know ur intentions prior to a render... otherwise, as i understand, in many cases, rebuild the whole page from scratch so it can act properly and accordingly....
Thanks
 
Upvote 0

Rob White

Member
Licensed User
At this stage of my experience with ABM I seem to spend alot of time getting screens to "look nice" (not sure I am convinced about Google's layouts probably old eyes).
- Change a padding(s) or margin(s) recompile, refresh the browser and repeat.

I saw this concept as putting some controls on a floating "sheet" so it could be dragged away from the area need attention. The controls would allow you to select a control, select padding... or margin...
and then move the control.
When all looked Ok the cell(x,y).Margin.... and Padding..... would be saved to the clipboard and pasted into the routine. Then the sheet removed / commented out.

Jumping or slowness can be tolerated as it would not be for the production version.

When I get some time I will do some experimenting but at the moment it is back to CRUD!
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
CRUD is what attracted me to ABM - following the examples @alwaysbusy used in the DBM module for adding or updating the MySQL record.
The ABMTable works great on large desktop screens but becomes troublesome on phones. That's where I switch to CustomCards - (both with pagination).

The modalsheet to mod/view the selected record requires little modification since the (small, medium, large) properties handle the various device screen layouts.
 
Upvote 0
Top