B4J Tutorial [ABMaterial] Theming the Framework - ModalSheets

Discussion in 'B4J Tutorials' started by Cableguy, May 4, 2019.

  1. Cableguy

    Cableguy Expert Licensed User


    what are they and what are they for?
    From ABMaterial Demo we can read:

    An ABMModalSheet component is like a mini ABMPage helper, but it pops up over the existing page. It has two ABMContainers, one that makes up the header and one for the footer section, so you can use everyting an ABMContainer can.
    ABMModalSheets and itscomponents have to be added to the page in the PageBuild() method. You can the later load the sheet and modify the content before you open it.

    In my "simpler" way of seeing ABMaterial components, an ABMModalSheet is pretty much like a Dialog that we use to get the user attention to Something we rekon important.

    Anathomy of a ModalSheet


    1 - Container 2 - Header 3 - Content 4 - Footer

    Lets take as an example the unthemed Login ModalSheet from ABMTemplate:

    Here we have, according to our ModalSheet Anathomy, a ModalSheet composed of a Content and a Footer. Each section can hold any ABM Componets, although some may be impracticle.
    In This series I will NOT go over HOW the component in hands works, but only try to deepen the how to change the way it looks. Remember, ABMaterial tries as much as possible to follow the Google Material Guidelines, so "The sky IS NOT the limit"!

    Theming (BASIC)
    Most Theming is done in the Shared Module, Under the BuildTheme Sub.

    The ModalSheet Theming options are:

    .Colorize as string - by using this parameter we can set the complete set of colors to use in the component… How?

    In our BuildTheme we define ALL the colors and ColorShades we plan to use:

    MyTheme.Page.AddColorDefinition("dragonfly", ABM.INTENSITY_DARKEN4, "#263A4C"1.0)
    "dragonfly", ABM.INTENSITY_DARKEN3, "#354A5E"1.0)
    "dragonfly", ABM.INTENSITY_DARKEN2, "#455B71"1.0)
    "dragonfly", ABM.INTENSITY_DARKEN1, "#566D84"1.0)
    "dragonfly", ABM.INTENSITY_NORMAL, "#6A8096"1.0)
    "dragonfly", ABM.INTENSITY_LIGHTEN1, "#8094A9"1.0)
    "dragonfly", ABM.INTENSITY_LIGHTEN2, "#97A9BC"1.0)
    "dragonfly", ABM.INTENSITY_LIGHTEN3, "#B0BFCE"1.0)
    "dragonfly", ABM.INTENSITY_LIGHTEN4, "#CBD6E1"1.0)
    "dragonfly", ABM.INTENSITY_LIGHTEN5, "#E8EEF4"1.0)
    And when we Apply our color definition, we also specify which color intensity we want to use.

    MyTheme.NavigationBar("nav1theme").TopBarBackColor = "dragonfly"
    "nav1theme").TopBarBackColorIntensity = ABM.INTENSITY_DARKEN4
    .HeaderBackColor as String - Header Back Color
    .HeaderBackColorIntensity as String - Header Back Color Intensity
    .ContentBackColor as String - Content Back Color
    .ContentBackColorIntensity as String - Content Back Color Intensity
    .FooterBackColor as String - Footer Back Color
    .ContentBackColorIntensity as String - Footer Back Color Intensity

    The ModalSheet Theme (as in ABMTheme ) are just these few, and focus mainly in the "Container" visual aspect, targeting its 3 regions. But there is a lot more that can be adjusted to get the ModalSheet to look the way we wish it to look. So next we take a look at some more Advanced Theming Options.

    Last edited: May 10, 2019
  2. Cableguy

    Cableguy Expert Licensed User


    Theming (Advanced)

    In order to use a modal sheet in your project, you need to first add the modal sheet to your page.
    This is done in the BuilPage() sub and, in the case of our LogIn form, it looks Something like


    BuildLoginSheet is the sub where we put together the bits and pieces that make up our modal sheet.
    In this case, no particular size is defined and so, the Normal size is used.

    A ModalSheet has 3 predifined sizes:


    For a long time there were no other size définitions, but in recent versions, Alain has introduced a few new methods that allow us to have diferent sized modal sheets.

    AppPage.ShowModalSheetAbsolute(ModalSheetId as String, Left as String, Top as String, Width as String, Height as String) - Shows the modal sheet at the absolute coordinates of the screen. The values can be percentages or pixel values ( ex; "20%", "100px")

    AppPage.ShowModalSheetRelativeCell(ModalSheetId as String, Row as Int, Cell as Int, CellWidth as Int, FixedWidth as Int) - Shows the modal sheet relatively to the specified row/cell. If FixedWidth is used, then CellWidth is overruled.

    AppPage.ShowModalSheetRelativeComponent(ModalSheetId as String, Component as ABMComponent, FixedWidth as String) - Shows the modal sheet relatively to the specified Component.

    So with these methods, we can better position our modal sheet to be almost anything we want, but we can also use a new set of properties to better fine tune the size.

    .MaxHeight as String - This sets the max size for the height.
    .MaxWidth as String - This sets the max size for the Width.

    Keep in mind that ABMaterial is a responsive Framework. This means that in some devices/screen sizes, our components may assume a diferent position and size on screen.

    Extra Properties
    Untill now we have only been dealing with the sizing and coloring of the modal sheet, but each region can be further customized.

    myModal.Content.SetBackgroundImage(Color as String, ColorIntensity as String, Source as String, Repeat as String, Position as String) - Color and ColorIntensity are by now old friends, Source is the relative path to the Image, Repeat is one of the ContainerImage_Repeat_ constants, Position is ContainerImage_Position_ or any valid CSS position string.

    Each region or section of a modal sheet can have extra properties too, like:

    Padding and Margins.

    If you're like me, you Always mix up margins and padding, never knowing exactly wich should we change to get the value we desire.

    Margins can have negative values, but padding can't… why? let see exactly what we are talking about:

    "an image can be Worth a thousand words"... and this is Worth a few hours of trial/error saving!

    .Header.PaddingTop .Header.PaddingLeft .Header.PaddingRight .HeaderPaddingBottom
    .Content.PaddingTop .Content.PaddingLeft .Content.PaddingRight .Content.PaddingBottom
    .Footer.PaddingTop .Footer.PaddingLeft .Footer.PaddingRight .Footer.PaddingBottom

    .Header.MarginTop .Header.MarginLeft .Header.MarginRight .Header.MarginBottom
    .Content.MarginTop .Content.MarginLeft .Content.MarginRight .Content.MarginBottom
    .Footer.MarginTop .Footer.MarginLeft .Footer.MarginRight .Footer.MarginBottom

    SetBorder and SetBorderEx

    .SetBorder(Color as String, ColorIntensity as String, WidthPx as Int, BorderStyle as String)
    .SetBorderEx(Color as String, ColorIntensity as String, Width as Int, BorderSTyle as String, BorderRadius as String)

    Again we see our old friends color and color intensity. WidthPx sets the width of our border, and the BorderStyle sets…(drumroll)… its style.
    In BorderEx we find an extra setting, BorderRadius, that allows us to set the… hum.. Border… Radius of the … Border. This is set as a String so it expects Something like "20px".


    .SetExtraStyle(ExtraStyle as String) - This is not for the faint of heart… This propertie expects a CSS string to be aplied to the concerned region. Results may not be exactly what you expect, since this is done BEFORE rendering and there may be some overruling by the underlying Framework.

    I come to get to know ModalSheets a bit better than I anticipated, mainly because I needed to achiev a look that was…. unconventional.
    I'll show you what I mean in the 3rd part of this, already too loooong post.
    Last edited: May 10, 2019
  3. Cableguy

    Cableguy Expert Licensed User


    SO, how diferent of a ModalSheet and mostly what limitations are we to expect when trying to theme them?

    In my endeavours, I got to a point were I was almos happy with my theming of my LogIn form.
    I had gone from this


    To this

    And Believe me, it was not easy to get here.
    So, what have I done to get this look?

    My modal has no header and no footer.
    I set the size of my modal using
    myModal.MaxHeight = "100%"
    myModal.MaxWidth = 
    I then set the Border using
    myModal.Content.SetBorderex(ABMShared.AppMainColor, ABM.INTENSITY_DARKEN2, 2, ABM.BORDER_GROOVE, "20px")
    This took care of MOST of the looks, BUT a I had a BIG issue… The round corners weren't transparent.

    SO, how could I get thos pesky round corner to look right?
    I turned to Alain, and his first answer was, basicaly, "sorry, no can do!"... this is not how Materialize works, and I started losing hope, but kept trying… I had almost given up when Alain asked me for my code so that he could take a look at it and try to find a solution...
    A few days later he got back to me with … you guessed it: A WORKING SOLUTION!

    Basically, according to his explanation, we had to wait for the page to fully load before even trying to overrule the Container CSS...
    In PageConnect() AFTER PageHasFinishedLoading we add


    Dim CSS As String = $"$('#login').css({'background-color': 'transparent', 'outline': 'none', 'box-shadow': 'unset'});

    As we can see, this is some serious mambo-jambo stuff, and only the Great Masters CSS Wizards can achieve such enlightment!

    And that got me my Login ModalSheet based Form just the way I dreamed it!

    Hope this helps you guys in your endeavours to better theme your ABMaterial WebApps!


    This is based on the "template" provided in the ABMaterial bundle, all that I changed was as follows:

    in the "ABMAplication" Module:
    public Sub ConnectPage()
    ' you dynamic stuff
    ' Tell the browser we finished loading
     AppPage.FinishedLoading 'IMPORTANT
     Dim CSS As String = $"$('#login').css({'background-color': 'transparent', 'outline': 'none', 'box-shadow': 'unset'});

    End Sub

    Sub BuildLoginSheet() As ABMModalSheet

    Dim myModal As ABMModalSheet
    "login"False, ABM.MODALSHEET_TYPE_NORMAL,"loginform")
        myModal.IsDismissible = 
        myModal.MaxHeight = 
        myModal.MaxWidth = 

    1,1).AddComponent(ABMShared.BuildParagraph(AppPage,"par1","Please login:"))
    Dim inp1 As ABMInput
    "inp1", ABM.INPUT_TEXT, "UserName"False"")
    Dim inp2 As ABMInput
    "inp2", ABM.INPUT_PASSWORD, "Password"False"")
    Dim msbtn1 As ABMButton
        myModal.Content.SetBorderex(ABM.COLOR_BLACK, ABM.INTENSITY_DARKEN2, 
    2, ABM.BORDER_GROOVE, "20px")
    Return myModal
    End Sub
    In the "ABMShared" Module
    Sub BuildTheme(themeName As String)
    ' the page theme
        MyTheme.Page.BackColor = ABM.COLOR_WHITE
    "loginform").Align = ABM.CELL_ALIGN_CENTER   
    End Sub
    This will produce the same basic LogIn form with the same basic fields… to get a more advanced look...

    Last edited: Aug 19, 2019
  4. Peter Simpson

    Peter Simpson Expert Licensed User

    This is excellent and made for some interesting reading @Cableguy.

    Enjoy your 2 weeks away and thank you for the great educational thread.

    Johan Hormaza likes this.
  5. Mashiane

    Mashiane Expert Licensed User

    Please share the code if you dont mind.
    f0raster0 and Johan Hormaza like this.
  6. Bothwell

    Bothwell Member Licensed User

    Any chance the tutorial can come with code so we learn ?
  7. Johan Hormaza

    Johan Hormaza Active Member Licensed User

    Plis the code
  8. Bothwell

    Bothwell Member Licensed User

    @Johan Hormaza for some reason don't think the author is willing to share or assist any further. ABMaterial is a good tool, unfortunately lacks proper documentation, we saw this a risk for our client and unfortunatley we had to move to a PHP tool for thier web frontend (https://www.agiletoolkit.org/ui ). Maybe if this was part of the core langauge we could have had a vedio on ETP. challenge is libraries are developed part-time and developers don't have time to come up with tutorials
    f0raster0 likes this.
  9. alwaysbusy

    alwaysbusy Expert Licensed User

    Just take into account @Cableguy has announced in July he was going to take a leave for a couple of weeks because he was getting married. So at least give the guy a break. ;) This is a very good tutorial which goes way further than what I originaly had in mind when I made ABM. I'm very grateful he made this.
  10. Bothwell

    Bothwell Member Licensed User

    all the best @Cableguy
    alwaysbusy likes this.
  11. Mashiane

    Mashiane Expert Licensed User

    joulongleu likes this.
  12. Cableguy

    Cableguy Expert Licensed User

    I am back, but been working overtime in my day job, which gives me much less free time to all the "other little things".
    Give just a couple of weeks more and I will have enough to share my code.
    Peter Simpson and Johan Hormaza like this.
  13. Toley

    Toley Active Member Licensed User

  14. Cableguy

    Cableguy Expert Licensed User

    I hope to release a freshly modified Template project in which the default LogIn modal-sheet (form) is replaced by this alternative version.
    I am available to answer any questions regarding this tutorial, but, basically, this was not meant as an "alternative solution proposal" but as a guide on how one could change a modal-sheet appearance.

    As usual, most devs here are more interested on having a piece of code to copy/paste than to have guide lines to help them get the look they want, and content themselves with already available ones.


    This said, the framework, in my opinion, has come to a mature and stable enough state, where one can finally start the gigantic endeavour that it will be to properly document it, not fearing that any new release would break the existing documentation.
    Erel, Mashiane, Johan Hormaza and 2 others like this.
  15. Cableguy

    Cableguy Expert Licensed User

    As requested, a Code Sample has been provided in the 3rd post of this Tutorial, any questions should be properly preceded by your own trials and errors, and a sample of YOUR CODE!
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice