B4J Tutorial [ABMaterial] For Dummies (beginner lessons)

ABMaterial For Dummies

This has often been asked for - so it is high time to produce a simple set of guidelines to help get you across the short learning curve. Take your time and see what you have been missing in simplifying web app creation with ABMaterial!

IMPORTANT UPDATE
------------------------------------------------------------------------------------------------------------------
@alwaysbusy created THIS wonderful and simple tutorial on May 3rd, 2020.
[ABMaterial] Mini Template for absolute beginners
------------------------------------------------------------------------------------------------------------------

*************************************************************
Having problems with your great understanding ABM?
Check the links with lessons 8 and 9 below for solutions..

*************************************************************

PLEASE - DO NOT Post QUESTIONS here!
It only serves to muddy the waters of a clean flow.


PLEASE
- Post any questions / comments in the B4J Questions forum (title - ABM for dummies).

If you have a request for something not covered here - please post it. We shall try to accomodate.

Lesson 1 - Master Template Project (covers Grids, BuildPage and ConnectPage). Required! - Contains all files for ABMaterial projects
Lesson 1a - More on ABM Grids ( Rows and Cells )

Lesson 2 - Simple ABMLogin with Public / Private Pages

Lesson 3 - MySQL and CRUD / ABMTables
Lesson 3a - More about ABMTables

Lesson 4 - Working With Containers

Lesson 5 - ABMGenerator
Lesson 5a - Report Setup

Lesson 6 - Sample Next Reports

Lesson 7 - ABMGenerator revisited (includes ABMTable)

Lesson 8 - Deployment Problems (Local Development vs Server Differences)
https://www.b4x.com/android/forum/threads/abmaterial-for-dummies-beginner-lessons.88346/#post-609895

Lesson 9 - Tips and Tricks
https://www.b4x.com/android/forum/threads/abmaterial-for-dummies-beginner-lessons.88346/page-2#post-611983

On the surface, ABMaterial appears to be a complex framework - which in fact, it is. However, through the series of specific topics (new posts), we will expose how easy it is to use - and construct beautiful / functional web apps.

The first post in this series (ok, the second) will have a complete project based on @alwaysbusy (empty) Template project included in each version he releases. It shall use ABM version 4.03 which is available to everyone. This well documented example will expose the Template page (populated with controls), a simple About page and the ABMShared code module containing the navigation bar and component themes. This is generally enough to get a newcomer started - since it actually does something!

We encourage others who are proficient with ABM to contribute well documented examples to this tutorial. Usually, this will be in the form of a stand alone "page" that can be added to the project, and any support methods needed which should go into the ABMShared code module.
For the pupil, he/she will download your .bas and add it to the project, create a menu item in the nav bar, add requirements in Main to initialize and any methods for ABMShared.

Many lessons (new posts) will be added with simple sections - as not to over-complicate matters.

Here is a small sample of what to expect:
B4X:
public Sub ConnectPage()
    ' connecting the navigation bar - now that we have built one above...
    ' examine the code in ABMShared to see how this works...
    ABMShared.ConnectNavigationBar(page)


    ' Let's add some components to the page - labels (with text), buttons and other controls...
    ' page.Cell(1,1).AddComponent(ABMShared.BuildLabel - here we add a label component to Row 1 / Cell 1, using a single statement
    ' and a method found in ABMShared Code Module.
    ' page.Cell(1,1).AddComponent(ABMShared.BuildLabel(page, "basic1",  - each component MUST have a Unique ID ("basic1" in this case)
    ' Notice that the text is right-justified...  How???  Using a theme - "lbltheme1"
    ' I will let you discover what the other parameters are for this method...
    page.Cell(1,1).AddComponent(ABMShared.BuildLabel(page, "basic1",   "See the faint green dot above in title bar?  This means your websocket is connected! {BR} All of this page's code is explained in the source file! {BR}{NBSP}",  ABM.SIZE_H4, "lbltheme1", 0, "25px"))

    ' Here we add another component in Row 2, Cell 1 - It is essentially a label with block quote
    page.Cell(2,1).AddComponent(ABMShared.BuildParagraphBQWithZDepth(page, "basic13",   "Hi There!  I am in Row 2 of this page!   {BR}{BR} I Have 'Flow Text' Applied. What does that mean? Resize this browser window and watch THIS text size shrink and grow accordingly!" ))

    ' Lets do something different in Row 3...
'.............................................

templatepage.jpg


The second post will have a link to download the base project - since it is much too large to attach here.


Thanks
 

Attachments

  • about.jpg
    399.4 KB · Views: 1,532
Last edited:

Harris

Expert
Licensed User
Longtime User
Master Template Project.

Lesson 1

Download the linked project and unzip to a folder of your choosing anywhere on your drive.
You MUST be using ABMaterial 4.03 and B4J 5.90 (minimum).

In the Template folder, double click on the Template.b4j file to open the project in B4J.
Compile the app.

In your web browser address bar, go to:
http://localhost:51045/template

Read the attached ABMaterial For Dummies.pdf

Study the ABMPageTemplate.bas which is commented. This is the template page from the menu selection.

All other files in this project make up a foundation of any typical ABMaterial application.
They shall be examined in greater detail in future sessions.

download links....
http://gorgeousapps.com/ABMaterialForDummies.zip
or
https://www.dropbox.com/s/88klwrt918ccral/ABMaterialForDummies.zip?dl=1

(above sites provided by yours truly - @alwaysbusy )

PLEASE - Post any questions / comments in the B4J Questions forum (title - ABM for dummies).

Thank you.
 

Attachments

  • ABMaterial For Dummies.pdf
    26.1 KB · Views: 2,389
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 1a

Because the concept of the Grid is so important, let us review the brief introduction from Lesson 1.

********************************************************************************
I hope everyone caught this error in my comments from the template page - Sorry!

' Now the cells part of adding rows... - .AddCellsOSMP( 1,0,0,0,12,12,12, 0, 0, 0, 0,"")
The above line is correct. I was explaining how to use AddCellsOSMP properly.

' AddCellsOS( 1, - add one cell to this row...
This line is incorrect. I forgot to add the MP to AddCellsOS!
The actual compiled code is correct thou...
********************************************************************************

There are many ways to add rows and cells.
They all do the same thing essentially, with additional control for various types.

Add Rows
These are the current methods to add rows to a grid:
page.AddRow( Adds 1 row with cells of equal size (possible values: 1,2,3,4,6,12) , center in page, row theme, cell theme )
page.AddRows( Adds 'x' rows, center in page, row theme )
page.AddRowsM( Same as above with top and bottom margin )
page.AddRowsM2( Same as above with left and right margin )
page.AddRowsMV( top and bottom margins with visibility set for desired device - ABM.VISIBILITY_ALL - implies all devices)
page.AddRowsMV2( all margins with visibility set )
page.AddRowsV( Same as AddRows with visibility set )

If you want (or need) the most flexibility when creating rows, always use page.AddRowsMV2().
This will allow you to set any property (number of rows, all margins, visibility) - and then tweek it later if need be.

Note: The link below explains the importance of understanding the proper use of AddRows (AddRowsM in this case...). @alwaysbusy does an excellent job of helping us understand what happens, when and why.

https://www.b4x.com/android/forum/threads/abmaterial-modalsheet-scrollbar-issue.88870/

Add Cells
page.AddRows().AddCells12( number of cells , theme )
page.AddRows().AddCells12MP( #, margins (top, bottom) / padding (left/right) and themes )
page.AddRows().AddCells12MPV( Same as above with visibility )
page.AddRows().AddCells12V(#, visibility and themes )
Note: Number of cells example for above: Creating 3 x 12 Cells will 'wrap' them to the next line!

page.AddRows().AddCellsOS( number of cells, device offset (s,m,l), size (s,m,l), theme )
page.AddRows().AddCellsOSMP( number of cells, margins (top, bottom), padding (left, right), theme )
page.AddRows().AddCellsOSMPV( Same as above with visibility set )
page.AddRows().AddCellsOSV( Same as AddCellsOS with visibility set )

If you want (or need) the most flexibility when creating cells, always use AddCellsOSMPV().
This will allow you to set any property (number of cells, all offsets, all margins, visibility) - and then tweek it later if need be.

You really can't see nor clearly understand all these effects until you run them in browsers on different device sizes.
Try and adjust your desktop browser window width to emulate these effects.

Something new about adding rows/ cells...

Adding Row/Cell Components - .Content.CellR(0,1)
CellR() stands for row Relative - to the current row...

In the example below, we add components to a row (and cell) NOT by row number, but by how far to move down the grid relative to the current row.

Let's assume the current row is Row 1 (start/top of grid).

The next line of code states the component to be placed in current row + 0 ( ie. row 1 / cell 1).
ABMGentiZonesModal.Content.CellR(0,1).AddComponent(ABMShared.BuildParagraphBQWithZDepth(page,"par1"," Note: Vehicle Types.") )

This, the next line of code states to place component in current row + 1 (ie. row 2 / cell 1).
ABMGentiZonesModal.Content.CellR(1,1).AddComponent(ABMGentiZonesmastpk)

This, the next line of code states to place component in current row + 0 (ie. row 2 / cell 2).
ABMGentiZonesModal.Content.CellR(0,2).AddComponent(ABMGentiZonesname)

This, the next line of code states to place component in current row + 0 (ie. row 2 / cell 3).
ABMGentiZonesModal.Content.CellR(0,3).AddComponent(ABMGentiZonesspeed)

This functionality may prove useful at times....


http://prd.one-two.com:51042/demo/ThemesPage/abmaterial-theme-color.html
http://prd.one-two.com:51042/demo/GridsPage/abmaterial-grid-layout.html

The above page links describes themes and grids. By now, I hope you have a good understanding of how to apply both.
AB also has a Grid Builder to make this process extra simple.
This excellent tool lets you build grids and visualize how each row / cell in the entire grid will look on various devices. How cool is that!

Thanks
 
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 2 - Simple ABMLogin with Public / Private Pages

Simple because we are not using a database table (this time) to validate username and password.

Most "membership only" websites begin with a public access page(s). Here they introduce prospects to what they have to offer before clients "sign-up".
Once registered, users will then Login to the private pages with a username and password.

The key to determining if login is required is by setting a NeedsAuthorization variable.

On Public pages, NeedsAuthorization = False.
On Private Pages, NeedsAuthorization = True

During a successful login, a session variable (cookie) is set:
Page.ws.Session.SetAttribute("IsAuthorized", "true" )
' ( Name, Value )

B4X:
' Each page looks at this attribute to determine it's state:
    If ABMShared.NeedsAuthorization Then   ' Does this page need Authorization?
        If session.GetAttribute2("IsAuthorized", "") = "" Then   '  Check for Authorization status.  If "" then direct user to Login process.
            ABMShared.NavigateToPage(ws, ABMPageId, "../")
            Return
        End If
    End If
You will find this code block in the WebSocket_Connected of each page.

This lesson includes two new files: HomePage.bas and ABMLoginHandler.bas. Over-write all files in the project since some other files have new / changed content.
The home page is your public "store front" and the login handler will process a user to gain access to the private pages.

The Home Page also provides new navigation menu options. These are only visible when viewing the public pages.

B4X:
public Sub BuildPage() ' HomePage.bas
' ...............
    ' builds the public nav bar as a top menu items
    ABMShared.BuildNavigationBarextra(page,  "Home","../images/logo.png", "Home", "Home", "Home")
 
' ...............  
    ' builds the login sheets for user login process
    ABMLoginHandler.BuildModalSheets(page)

End Sub

Sub ConnectPage()
   ' ConnectNavigationBar2 is purposely built for public pages... It does not require a login to view
 '........
    ABMShared.ConnectNavigationBar2(page,  "Home", "Home", "Home",  Not(ws.Session.GetAttribute2("IsAuthorized", "") = ""))
 '.......
End Sub





'**  Home Page  ************************************************
' handle the login and cancel buttons from the login sheet.
Sub loginbtn_Clicked(Target As String)
    ABMLoginHandler.HandleLogin("Home", page)
End Sub

Sub logincancelbtn_Clicked(Target As String)
    ABMLoginHandler.CancelLogin(page)
End Sub

'*************************************************************

' ABMShared module...
Sub BuildNavigationBarextra(page As ABMPage, Title As String, logo As String, ActiveTopReturnName As String, ActiveSideReturnName As String, ActiveSideSubReturnName As String)

' ...............

     ' Init the top bar navigation for public pages - use a new theme to style it....
    page.NavigationBar.Initialize(page, "nav1", ABM.SIDEBAR_AUTO, Title, True, True, 330, 54, sbtopimg, ABM.COLLAPSE_ACCORDION, "nav1theme")

' ...............  
End Sub

' ABMLoginHandler.bas - The Default User Name and Password...

' username password
If (logininp1.Text = "dumb") And (logininp2.Text = "dumber") Then ' username and password for dummies after all...
' do your thing
end if


Included are the complete set files including project and .bas files.
Replace all the existing files
If you are familiar with B4J, then this lesson should be easy.

The login introduces a ModalSheet. The creation structure is just like a page with rows and cells.
The sheet is first built and then called using:
page.ShowModalSheet("login") - from the HomePage.

The sheet is closed using:
page.CloseModalSheet("login")

You should be able to read / follow the code and understand the logic.
A little explanation can go a long way. If you get stuck, ask a question in the B4J Questions section.

Thanks
 

Attachments

  • lesson2.zip
    32.9 KB · Views: 1,330
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 3 - MySQL and CRUD / ABMTables

Sure, you could use Wix, Go-Daddy or any one of the other so called web-site development systems to create your picture based site (in about an hour...).
However, these systems don't support a database that you can add and manage. I guess that's why they are site development and not web-app systems.
Database support is what really makes a web-app. You can use any database (MSSQL, Oracle, postgres, etc) since JDBC drivers exist for all of them.

This lesson provides a basic, yet interesting example of how to work with database tables and records in your ABM projects.

The attached zip has everything (code) included.
You will need a WAMP (Windows version) to continue with this lesson (see below for a nice light one...).
Also, import the attached users.sql (users.zip) into your database - using your favorite DB manager. I use phpmyadmin.


Adding MySQL Support Drivers

In the Main of our project, we must add the driver for MySQL. This driver file will be placed in our Libraries folder.
The required jar is too large to attach to this post.
' #AdditionalJar: mysql-connector-java-5.1.37-bin
' #AdditionalJar: mysql-connector-java-5.1.44-bin ' latest jar file...

Now you must init this driver.
' you will need YOUR database name, user name (login), password and pool size

' DB Name username password pool size
' DBM.InitializeMySQL("jdbc:mysql://localhost/ harris ?characterEncoding=utf8", "harris", "b12xw3455", 100 )
' or...
' DBM.InitializeMySQL("jdbc:mysql://localhost/database_name?characterEncoding=utf8", "username", "password", 100)

The Main also explains how the apps pages are inited and added.


Login - Uses a database lookup.

In ABMShared, UsingDB is set to True. This forces the login system to use a table for user authorization.
Public UsingDB As Boolean = True ' Using a table to check username and password
Check out the code in ABMLoginHandler - the HandleLogin method.

UsersPage.bas - The CRUD page

The table system (ABMTable) in ABMaterial is second to none.
Study the ConnectPage, LoadUsers and tblUsers_Clicked methods carefully.
These explain how to create ABMTables, populate and work with them.
Also, @alwaysbusy created a CRUD code generator. It can easily create the crud code for you - but you should know how this code works just the same.

http://downloadbull.com/portable-usb-webserver-8-6-free-download/
Web server link (if you don't have one already). I use this for my day to day development on my local pc.
I use an industrial LAMP on my Linux remote production servers.

Thanks
 

Attachments

  • lesson3.zip
    42.8 KB · Views: 1,154
  • users.zip
    109.2 KB · Views: 1,072
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 3a - More about ABMTables

Since we had so much fun in Lesson 3 learning about ABMTables, I have added more content along the same lines....
In this section we will add ABMLabel, ABMImage, and ABMSwitch to our ABMTable - all quite easily!

Attached are 2 files:
UsersPage.zip - the .bas file reworked for this lesson...
dumb.zip - Place the folder in this zip in your: www/template/images folder. (result: "www/template/images/dumb")

Here is a snap shot of the new ABM Users Table... The Edit (modalSheet) has changed as well...
Read comments in the .bas file for instructions - as per usual...

Thanks

abmtables.jpg
 

Attachments

  • dumb.zip
    252.5 KB · Views: 1,044
  • UsersPage.zip
    10.8 KB · Views: 1,106
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 4 - Working With Containers

Question: What are containers?
Answer: A place to put your stuff...

Or more specifically, "another" place to put your stuff (components) - aside from the page.

Containers are special and powerful components useful in creating wonderful apps.
In this example, we will use 1/3 of the page to hold a container and the rest to show container actions.

I shall supply the .bas file. It is now up to you to:
1) add it to the project,
2) init it in Main,
3) add the page name to the navigation menu in ABMShared (or replace an existing item - like
page.NavigationBar.AddSideBarSubItem("Config", "Company", "Test Containers", "mdi-action-home", "../ContPage") )


More on this subject by @alwaysbusy
http://prd.one-two.com:51042/demo/HelperContainerPage/abmaterial-container.html

Good luck and enjoy this simple lesson.
When the lessons are completed, perhaps you will create the advanced - "ABMaterial for Experts" !!!
 

Attachments

  • ContPage.zip
    5 KB · Views: 975

Harris

Expert
Licensed User
Longtime User
Lesson 5 - ABMGenerator (Part A)

This handy tool was mentioned previously and really deserves a closer look.
In part A of this section (one of many), we shall look at what it (simply) takes to generate modal sheet code for CRUD.
I think that once you see the power of this, you won't bother writing these by hand any longer (or copy/paste as I have done previously).

History
Back when ABMaterial was first introduced, I asked @alwaysbusy if it was possible to create a code generator that would reduce the drudgery of writing ABMTables and Modal Sheets code - since each time the result was practically identical. Initially, he had some reservations about this yet 2 days later - ABMGenerator appeared!
The result was much more than I could ever image possible. I swear he has a team of clever elves coding somewhere, like in Erel's basement - next room over from Erel's group. :) What do you feed elf coders? (Bits and Bites!).

The attached About.bas contains the generator sections. For now, all we shall do is let it generate the code (lot's of it) - then view it.
Each line is documented as to its' function in the generation process.

Read (study) the output result. Be amazed (as I was) of the code design. Only a true professional could think of creating such well structured code.
Look how updates and inserts are handled. This sure beats (by 1000 fold) the ultimate mess I would have written left to my own sparse knowledge of proper design.
I have personally learned so much from ABM code examples - from his supplied projects. Now you can too since you will have a good idea of what you are looking at.


In the next segment of this multi-part lesson, we shall use the generated output on a table I shall supply. We will also fill in some of the "blanks" of this result - since a generator can't do everything - but darn near! Also, we shall build the required ABMTable since the generator doesn't do this currently (easy enough for us however). We will look at a template for the "LoadTable" method - required and similar in each case where you will build new pages containing new (different) DB tables.

The end result of our efforts in this series will introduce us to Next Reports - and how we shall use what we have built to drive / configure a simple reporting system (also based on the previous use of containers lesson).

Again, ABM is essentially just your GUI. Let's put it to work directing B4J code, ABM complete components / helpers and other important web app things.

We take things slowly around here - like Bill Murray in the movie "What About Bob" - baby steps....

 

Attachments

  • AboutPage.zip
    6.6 KB · Views: 980
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 5a - Report Setup (Part B)

In this session we shall put our generated code to good use. We shall make the Report Setup form.
Invariably, we may find our initial design (that we asked the generator to create) was slightly off the mark... No problem, we can fix it.
The point was - it created a bunch of clean code we didn't have to write.

Here is a list of things we must do / provide with the generated code:
1) Create your ABMTable construct. We covered this previously.
2) Provide the table name and where clause field name in SELECT, INSERT and UPDATE statements. I've shown where these go...
3) Correct the modal sheet footer in the ABMGenBuildreport (or whatever the name is)... Add the button Text Name (Save and Cancel) and remove the transparent theme.
4) Add margins for each row in the build sheet.
5) Add titles to the Switch Components (when required).
6) Re-order our input fields in our sheet.

Note: All above has been corrected in the attached...

Report Setup
The Report Setup form is a simple helper that defines what reports our application provides and what parameters are required to run each.
We can add new reports as they become available - and update our application with little effort.

Reports Page
This is where we will put our setup to use. Each report we choose may have various and different parameters shown to allow proper configuration.
This section also introduces the use of ABMSideBar. This cool component keeps our main page clean while allowing our configuration container to slide in/out when required.

Unzip the files to your template project (overwrite where asked).
Add the two new .bas files to your project (reportPage, setup_paramPage)

Import the report1.sql into your db. This is required to drive our reporting system.

Add the following into Main, where shown...

B4X:
    Dim reportp As reportPage
    reportp.Initialize

    Dim reportset As setup_paramPage
    reportset.Initialize

    '****** End Init pages **********************************************
       
    ' add each of the pages to the app
    '***** Start Add pages ***********************************************

    myApp.AddPage(reportp.page)
    myApp.AddPage(reportset.page)

Under Configure App - see Setup Reports

Under Applications - see Reports Page

In the next lesson of this series, we shall add some actual reports. This requires the Next Reports framework.
I will supply some report files based on our data for the next lesson.
Creating reports can be entertaining - when you don't have to fight with a reporting framework. Each has it's quirks and features.
I have found that the more you pre-process your reporting data - the easier the process is.
We shall create temp tables for our data - add blobs to support image printing and other fun stuff...

If you are not familiar with NR, I suggest you download it and study how it works.
You will need the engine files for the next lesson. Like B4J - it's all FREE...

Get the NR designer...
http://www.next-reports.com/products/nextreports-designer.html

And the NR engine...
http://www.next-reports.com/products/nextreports-engine.html

We won't need the server - however it is nice to know there is one with NR (just like the expensive big boys).

Finally, I shall have to assume that the lack of questions in the B4J Questions form concerning ABM for Dummies means that I am accomplishing the task of keeping this simple - for all us dummies.... As you can see - this stuff isn't difficult - when shown how easy...

Thanks
 

Attachments

  • lesson5b.zip
    24 KB · Views: 904
Last edited:

Harris

Expert
Licensed User
Longtime User
Lesson 6 - Sample Next Reports

This lesson requires Next Report jar files as defined in the previous lesson.
It also requires the jNxtReportsB4J library.

This example has very little to do with ABMaterial. The ABMPDFViewer is used to show the NR pdf generated reports.
We shall also show reports, in a new tab, when generated using the NR html output format.

In the Main.bas, include the following lines in the project attributes section...

B4X:
#AdditionalJar:nextreports-engine-9.1
    ' Don't forget to add jNxtReportsB4J in the B4J IDE Libraries tab
 
'    Download these jar files to the B4J Libraries folder
'    All these jar files are available from http://www.next-reports.com/download.html
    #AdditionalJar:commons-jexl-2.1.1
    #AdditionalJar:commons-logging-1.1.3
    #AdditionalJar:itext-2.1.7
    #AdditionalJar:itext-rtf-2.1.7
    #AdditionalJar:itextpdf-5.0.6
    #AdditionalJar:xstream-1.3.1
    #AdditionalJar:xstream-1.4.7
    #AdditionalJar:poi-3.7

Supplied files:
Replace the reportPage.bas with this new file attached.
Place the pics folder into the template\images folder. (result -> template\images\pics )
Place the reports folder into the the Objects folder. (result -> Objects\reports)

Import the sql files into your database. Note: replace existing report1 with supplied file. Add insptype.

The reports folder contains the NR report templates. These were created with Next Reports 9.1
You can open these with your installed copy of Next Reports.

The reportsPage.bas is well commented. Make sure you supply the correct url for the jdbc database definition - since the supplied code won't work in your environment.
Next Reports will not generate a report when in Debug mode (use release mode).

Good luck and remember to post comments or questions in the B4J Questions forum.

Edit: The users.zip in lesson 3 has been updated to include images (pics) in case your example does not include it. This may happen if you did not follow these lessons from the beginning (lesson 1).

Thanks
 

Attachments

  • pics.zip
    479.9 KB · Views: 867
  • reports.zip
    4 KB · Views: 860
  • reportPage.bas
    26.2 KB · Views: 789
  • sql_imports.zip
    2.1 KB · Views: 823
Last edited:

Mashiane

Expert
Licensed User
Longtime User
If you wish, could you define the "empty" template project?Thanks

After careful thoughts, I decided to work on Part 1 of this very big task. With this video, before I delve into the code and what to change, we look at what ABMaterial is, its structure (blank template), the Demo project and various other elements that we use to create our web apps. I hope you will enjoy the video as much as I enjoyed creating it. Ta!

Watch in HD.

 

Mashiane

Expert
Licensed User
Longtime User
Templating & Your Next ABM WebAPP

Hi there...

This is a continuation about the template video I added here..

I have been thinking about the next section of the 'Template' and would really like to do my contributions here a lot of justice. In my post, above, I back-tracked a little to give an overview of everything this seeks to address, as a result, rather took a slow approach. Reason being, as a creator, the question of what you want to achieve with ABM and the understanding of how everything fits in together, becomes extremely crucial. So my two cents resulted in this diagram below.

NB: Click the image to expand it and see it nicely...

ABMBeast.png


Before one writes even a single line of code, a pure understanding of how everything ABM is knitted together is necessary. I believe you are here because you are interested and also want to develop beautiful things with ABM. You have made a very good decision. This is a very beautiful framework and above I just did an overview of how I understand it, I'm still learning like everyone else and still make mistakes.

An ABM project is made up of components that can be categorized into Input Controls (user has to enter/select something), Buttons, Media (display something, play music), Layouts (contain other components), Navigation (move around the page), Events related components e.g. calendar, planner etc, Reporting & Other things like the XTR (translating your app), Conzole (debug your app), ABMGenerator (Lesson 5a above) and Security (captchas, social-auth) etc.

I have tried to remember as much as I can referencing the Demo ABM app also. Please if there is anything I have left out, kindly shout!

All of the components indicated above will help one using the ABMPageTemplate to create beautiful UXs for their apps.

When all the components that you want to use for your app are built into each of the pages you will have, these compile into a WebApp that you can then deploy to VPS. There are some developments towards publishing on GCE (Google Cloud Environment).

In summary, the components feed into your ABM WebApp, you code each component you need to sit inside any of the layouts, especially the ABMPage (ABMPageTemplate class), these using B4J are compiled to into a WebApp, they you deploy this to a VPS.

In my next post and hopefully last post about the template, I will conclude about the three most important 'blank template' classes that you need to be up and running with your ABM WebApp.

I hope you found this informative just like I also found it.

PS: This diagram is created using a custom component. See here
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Your ABM WebApp Design: Part 1

Now that you have an idea of what your next ABM will contain as per components discussed above. You need to look at the design, the look and feel and how everything will work together to make your perfect app. This answers the question of where the components will be placed?

The starting point for that is the ABMGrid. The grid helps you place the components/controls you want on your containers, i.e. ABMPage, ABMContainer, ABMSmartWizard, ABMTabs etc etc.

Let's just do a quick refresher based on Lesson 1A above.

NB: Most of the ABM component needs to sit in a row/cell co-ordinate in a Grid.

The ABMGridDesigner is a tool to help you create the grid that will host your components. Basically it helps you create something like Figure 1 below without typing the code. AB started the grid concept in 2016 and it has matured a great deal after that.

Figure 1

ABMGrid.png


1. You need to add rows to the grid. Each row should have a cell or a couple of cells. The various methods to add rows as discussed by Harris, are AddRow, AddRows, AddRowsM etc. Each cell is added using any of the methods like AddCells12, AddCellOS, AddCellOSMP etc.

2. You can add 1 row at a time or add multiple rows at the same time. The cells added will apply on all the rows being added. In the above Figure, 1 row was added to demonstrate each of the various methods of adding the rows.

3. Each row as 12 cells / columns. This is depicted by the faint gray lines in each row.

Let's explain Figure 1 above.

I have created a grid with 12 rows and 12 columns/cells across. The sizes e.g. 111,999,222 indicate the span of each cell/column. For example, AddCells12(1,"") will add 1 single cell in that row spanning 12 spaces.

3.1 AddCellOS(2,0,0,0,6,6,6,"") - adds 2 cells in that row spanning 6 spaces. This can be also done with .AddCellOS(1,0,0,0,6,6,6,"").AddCellOS(1,0,0,0,6,6,6,"")
3.2 The example with cells 1,1,1:9,9,9:2:2:2 adds 1 cell, 9 cells and 2 cells as depicted above respectively.

4. In all the rows in Figure 2 except the first row we have 2 cells/columns. The first row will be referenced with...

B4X:
page.Cell(1,1).AddComponent(xxx)

The 2nd row

B4X:
page.Cell(2,1).AddComponent(xx1)
page.cell(2,2).AddComponent(xx2)

The 7th row has 3 cells, thus to add anything in each of them one will use...

B4X:
page.Cell(7,1).AddComponent(xx1)
page.Cell(7,2).AddComponent(xx2)
page.Cell(7,3).AddComponent(xx3)

NB: Each time you execute an AddRow method, ABM increments the existing row counters with the number of rows to add. In the Figure above, AddRows(1...) was used for all the row:cell system. The ABM framework then does the magic of referencing the RCs for you and allocates the correct RC co-ordinates for you.

What about the MP (margins and padding) in the methods?

I have left that out because this is basically related to something called the CSS Box model. Let me explain. In the video, I indicated that ABM generates HTML and CSS code for your WebApp, with you not having to write that. That was AB's good intentions.

Each element that you see on your ABM webapp is an HTML element, meaning that it can be considered as a box. In CSS terms, when talking about designs and layouts, the term, "box model" is used. This box model wraps around it every HTML element. It's made up of margins, padding, border, and the actual content. So as an example, an ABMInput control will have padding, a border and a margin around it etc etc.

Explanation of the different parts:

Content - The content of the box, where text and images appear
Padding - Clears an area around the content. The padding is transparent
Border - A border that goes around the padding and content
Margin - Clears an area outside the border. The margin is transparent

cssbox.png


As noted, this padding and margins can be set for the rows and cells by specifying the M and P variables when adding the rows and columns. That should cover the MPs.

V - Visibility

Each component/row/cell that you add can have a visibility set. This visibility indicates how your HTML element should be displayed within the various devices that you are designing for. Remember, when working with the grid-designer, you are designing for small, medium and large devices at the same time. The ABMWebAppViewer shows the output of your app perfectly when you run it. You can then tweak it.

The enumeration for the visibility is..

B4X:
ABM.VISIBILITY_ALL
ABM.VISIBILITY_HIDE_ALL
ABM.VISIBILITY_HIDE_ON_SMALL_ONLY
ABM.VISIBILITY_HIDE_ON_MEDIUM_ONLY
ABM.VISIBILITY_HIDE_ON_MEDIUM_AND_BELOW
ABM.VISIBILITY_HIDE_ON_MEDIUM_AND_ABOVE
ABM.VISIBILITY_HIDE_ON_LARGE_ONLY
ABM.VISIBILITY_SHOW_ON_LARGE_ONLY
ABM.VISIBILITY_SHOW_ON_MEDIUM_ONLY
ABM.VISIBILITY_SHOW_ON_SMALL_ONLY
ABM.VISIBILITY_SHOW_ON_MEDIUM_AND_ABOVE
ABM.VISIBILITY_SHOW_ON_MEDIUM_AND_BELOW

This then allows flexible design for your apps as you can hide/show components depending on your device.

As you have picked up, there are Offset properties when adding cells to a row. We will touch on that in Part 2 of this intro.

Thanks.
 

Mashiane

Expert
Licensed User
Longtime User
Your ABM WebApp Design: Part 2

This part of the design talks about Offsets. One of the users asked the other day how he can have buttons on either side of his row? AB answered him by pointing him to offsets.

When creating Cells in your rows, there are variables for small, medium and large devices that are usually indicated with 0,0,0 then followed by the size of each cell for each device.

To put it simply, offsets indent / nudge to the right your cells for each of the device specifications. With ABM, you specify how much this indentation/nudging should be as it takes space.

Figure 1

offsets.png


1. In figure 1 above, as we are aware, each ABMRow has 12 imaginary ABMCells, i.e. 1R=12C.
2. If we want to nudge/indent something, we need to offset it by the number of spaces that it needs to take. In row 2, we have used an offset of 1 (1 space to the right) and 11 spanning spaces for the cell.
3. In row 3, same story, we nudged the cell to the right it taking 2 spaces. 2 offsets + 10 spaces = 12 cells
4. Now the fourth row is rather interesting. We want to have a component on either side of the row. We add 1 cell spanning 2 cells and another cell spanning 2 cells with an offset of 8, making the cell complete with 12 cells.
5. In all the rows except row 4, each row has just one cell, thus, referencing it when adding components, one would use .Cell(x,1).AddComponent. With the 4th row, its .Cell(4,1).AddComponent(c1) and .Cell(4,2).AddComponent(c2).

This is due to the fact that we cannot use TAB to indent our layouts, so a smart way was created, Offsets.

Please note: One last thing I would like to touch on, time allowing, before we delve on actual coding of the 'blank template' to create a new ABM project is 'Theming'. Please just bear a little while.

PS: And this was so hard to grasp when I started ABM. It's a marvel that we have the grid-designer to help us through this, however before you even start with that, you need to have an idea of how you want your pages to look like and where your components should be placed.

I hope so far this thread is helping you achieving that.

Enjoy.
 

Harris

Expert
Licensed User
Longtime User
Lesson 7 - ABMGenerator revisited...

In a previous lesson we looked at the first version of the ABM Code Generator.
I was reminded of a newer release of the generator that produces much more than ABMSheets.

This lesson is a stand alone Template project (backup your old project or use a new folder if required).
It will create a simple page populated with the code from the generator. The nice thing about this lesson is the creation of an ABMTable (a grid with records).
ABMTables generally require support methods to use them effectively. The generator writes all the code for you!
Simply modify certain sections - mostly to make it look pretty / apply themes - and enjoy all the code you DID NOT have to write!

This example uses MySQL as the database - and a users table for the example. Rename your existing users table if you have one prior to importing this one.
Modify the Init method in the Main.bas to your requirements.

The "ABMPageTemplate" is well commented and includes the code from the generator - some modified slightly.

Thanks
 

Attachments

  • users.zip
    75.1 KB · Views: 840
  • Template.zip
    31.3 KB · Views: 869
  • USER_GenCode.zip
    4.4 KB · Views: 799

Mashiane

Expert
Licensed User
Longtime User
Explaining the Template Folder - Part 1 : The ABMApplication.bas file

This module is like the server part of the application where you specify things needed to make the app work. Its like the index.html part of your application, however you call it from the Main module. You start the webserver from this page after you have added your app pages. Adding pages and starting the server is done in the Main module. When creating a new ABM project, you need a variety of files, these are in the Template folder and you copy the contents of that folder to a new folder with the name of your app and then do some renaming across the files to make your app work.

The Demo app does a lot of justice in terms of explaining how ABM works. The purpose here is just to explain a few things based on what I've learned so far. Any time you create a new application, there are a variety of things to consider.

1. The port your app will run on. This port should be opened in the firewall for both incoming & outgoing traffic.
2. If your app will use Google Maps, create a map key from google and update ABMShared with the key, the GoogleMapsAPIExtras property
3. If your app will use Chat functionality, ensure you initialize the Chat module in Main.
4. To link your app pages to the app, add these to your application in the Main module

B4X:
Dim myApp As ABMApplication
myApp.Initialize
...
Dim myjobs As jobs
myjobs.Initialize
myApp.AddPage(myjobs.Page)
...

5. What backend database will you use, this needs to be opened when the AppStart, usually done in Main or when needed.
6. To compress your images with the build in GZip, you need a Donator key
7. To use ABM's CDN, you need a donator key
8. The page your app will start on needs to be clearly defined, page names are case sensitive, preferably just use lower case. This creates some issues on windows vps servers where filenames are different. ABM is case sensitive with file names.
9. ABMShared is a very valuable module where your shared code can be placed that will be available across the app.
10. Most development of your app happens on each instance of ABMPageTemplate, there is very little to change on ABMApplication and ABMShared.
11. Your app name should not contain spaces (recommended). Update ABMShared with the app name, the AppName property
12. Ensure that the cache scavenger settings for refreshes and your connection pool for database connections is sufficient (see demo apps for settings)
13. The viewer is very handy to see your app across the various devices.
14. You can also have a TrackingID for your app for google stats purposes.
15. You can build themes for the app in ABMShared and you can also build themes for your components in each page. ABMShared.BuildTheme is useful for that.
16. If your app needs Sign In features, you can turn ABMShared.NeedsAuthorization to true. Ensure you use the Login functionality discussed in ABMFeedback.
17. If you app will use the ABMFileManager, this needs to be linked to a particular folder on start. This is changeable via code though. Additional code is needed to complete the installation of this file manager, see the post here in the forum.
18. If your pages will share the same navigation system e.g. SideBar and TopNav, you can define this structure in ABMShared using BuildNavigationBar and ConnectNavigationBar and just call these methods when building your pages
19. You can define any component in ABMShared e.g. ABMContainer, ABMModalSheet etc, however trapping events should be done at page_level for those to work in your page.
20. If your app will have a shared footer, you can define its structure in ABMShared and then call this on your page.
21. If your app will use Social Media sharing, you need to have the respective apps created e.g. facebook or else have links pointing to those social pages. Yes, you can link a component to be posted to social networks.
22. If you run in SSL environment, the method to start the server is different, its StartServerHTTP2
23. Should there be a component (JavaScript based) component that you need that does not exist in the current package, the ABMCustomComponent exists to create such components. Knowledge of JQuery, JavaScript, CSS is necessary for such things.
24. The default these for ABM apps is light blue, you can customize your app by building themes specific to each component that you need to enhance the look and feel of your app.
25. Some components have more that one Initialize method to create them for your pages depending on what you need.
26. You can have SQLite as a backend and activate multi-user on it. With the SQL library you can use both MySQL and MSSQL. The DBM module has been created by AB for database connections and manipulations. The ABMGenerator discussed above and other parts of this thread touched on this.
27. If your images shown via ABMImage etc will be changing and thus dynamic, append DateTime.Now timestamp on them, this will ensure that the latest images are displayed in the server. If not, the images from the cache will be used.
28. You can have different loading methods on your app and these can be shown with .Pause and .Resume methods but however are activated automatically when a page is loading.
29. You can define HTML for your error pages in ABMErrorHandler
30. You can leave out the app name when opening your app via a web browser by using the ABMFilter in your app.
31. A file upload handler exists where file management is concerned, this can be tweaked to replace existing files when uploads happen.

Method: ABMApplication.Class_Globals

Property: InitialPage – here specify the name of the page the application will start on. This name is case sensitive and must match the class name of your page. This should be the complete path of your page e.g. frmIndex/frmIndex.html

Method: ABMApplication.Initialize

  • Here define the apple touch icon, tile icons, fav icon to use for your application. You can also specify the Thresholds for the small and medium devices.
  • If you want the CreatedWith to be obfuscated, you can also specify this here by passing it the donation key
  • If your app will have a manifest, also add the line specifying that here.
  • You can also call the method to set the font sizes here, including the expiry times for your pages.
  • If you have a donation key, provide it where it is needed e.g. for GZip or ActivateCDN.

This module also has BuildPage and ConnectPage, which means you can run code that will run in your “index.html” here. You can see the Demo app and other attached ABM demos about how these are defined.

For my BuildPage method, I indicate the PageTitle, the PageHTMLName etc. For PageHTMLName you need to add the .html extension to the name.

The ABMFeedback app has additional methods here to create a login page for the app, explore that for more details.

Ta!

PS: Should anyone notice an error, please indicate. Thanks. ;)
 

Harris

Expert
Licensed User
Longtime User
Lesson 8 - Deployment Problems (Local Development vs Remote Server Differences)

We see this issue often:

"Everything works great on my development platform - but I get different results when I deploy it to my remote server!"

There are four (and possibly more) reasons for this.

1) "copymewithjar.needs" file...
Each time you update your "myapp".JAR file on your remote server, make sure you also copy this file as well - to the same location.
It contains the required class names that are required to execute your app properly - and will ensure they are linked (magically).
IMPORTANT! Run your app in debug mode to generate / update this file before releasing your app!!!!!

2) The www folder:
Make sure the js, font, and css folders are current. Every time alwaysbusy releases a new ABM version upgrade (ie. 4.15 to 4.20), certain files in these folders will change to support the (bug) fix or new features.

3) Custom / js folder
If you have any custom js files (from custom components you made), make sure you update the appropriate folder with the required files. Only you will know where these need to be placed.

4) Java version. This is typically a B4J issue. Does your dev system use the same java as the server?

These are the most common issues. If you have exposed other areas where one can get tripped up using ABM - PM me with your solutions and I shall add them to this section (easiest method to keep it all together).

Thanks
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
ABMaterial Component Events Quick Reference: For more details explore the XML document.

Each ABM component can have one or more events. Events happen when a button is clicked, a radiogroup item is changed, a checkbox is checked etc etc. Below is a collection of events in component order for a quick reference. Each component is prefixed by the class name. When inserting the code in your page, you can replace the component class name with the actual name that you used when Initializing the component.

Where there is a 'Target' name, this is the actual html id of the component as defined by ABM.

In summary, if you have an action button on your page, you can copy the code related to the action button and then replace ABMActionButton with your component id e.g.

B4X:
Sub mib_Clicked(Target As String, SubTarget As String)
End Sub

Below are all the events that you can use for all the components.

B4X:
Sub ABMActionButton_Clicked(Target As String, SubTarget As String)
End Sub

Sub ABMAudioPlayer_Done()
End Sub

Sub ABMButton_Clicked(Target As String)
End Sub

Sub ABMButton_MenuClicked(Target As String, returnName As String)
End Sub

Sub ABMCalendar_DayClicked(date as String)
End Sub

Sub ABMCalendar_EventClicked(eventId as String)
End Sub

Sub ABMCalendar_EventEndChanged(eventId as String, NewEnd as String)
End Sub

Sub ABMCalendar_EventStartChanged(params as Map)
End Sub

Sub ABMCalendar_FetchData(dateStart as String, dateEnd as String)
End Sub

Sub ABMCanvas_CanvasDown(x as int, y as int)
End Sub

Sub ABMCanvas_CanvasUp(x as int, y as int)
End Sub

Sub ABMCanvas_ObjectClicked(objectId as String)
End Sub

Sub ABMCanvas_ObjectDown(objectId as String)
End Sub

Sub ABMCanvas_ObjectUp(objectId as String)
End Sub

Sub ABMCard_LinkClicked(Card as String, Action as String)
End Sub

Sub ABMCheckbox_Clicked(Target As String)
End Sub

Sub ABMChip_Clicked(Target As String)
End Sub

Sub ABMChip_Closed(Target As String)
End Sub

Sub ABMCombo_Changed(value As String)
End Sub

Sub ABMCombo_Clicked(itemId as String)
End Sub

Sub ABMCombo_GotFocus()
End Sub

Sub ABMCombo_LostFocus()
End Sub

Sub ABMComposer_Add(blockID as String)
End Sub

Sub ABMComposer_Edit(blockID as String)
End Sub

Sub ABMComposer_Remove(blockID as String)
End Sub

Sub ABMContainer_AnimationFinished(Target as String, lastAnimation As String)
End Sub

Sub ABMContainer_NextContent(TriggerComponent As String)
End Sub

Sub ABMCustomComponent_Build(internalPage as ABMPage, internalID as String) as String)
End Sub

Sub ABMCustomComponent_CleanUp(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMCustomComponent_FirstRun(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMCustomComponent_Refresh(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMDateTimePicker_Changed(Target as String, dateMilliseconds as String)
End Sub

Sub ABMDateTimePicker_ChangedISO(Target as String, dateISO as String)
End Sub

Sub ABMDateTimePicker_ChangedWeek(Target as String, WeekString as String)
End Sub

Sub ABMDateTimePicker_ChangedWeekISO(Target as String, WeekString as String)
End Sub

Sub ABMDateTimeScroller_Changed(dateMilliseconds as String)
End Sub

Sub ABMDateTimeScroller_ChangedISO(dateISO as String)
End Sub

Sub ABMEditor_Loaded(Target as String)
End Sub

Sub ABMFileInput_Changed(value As String)
End Sub

Sub ABMFileManager_Downloaded(jobcode as String)
End Sub

Sub ABMFileManager_FolderChange(folder As String)
End Sub

Sub ABMFileManager_RequestForCopyPaste(fromFolder as String, jsonList as String)
End Sub

Sub ABMFileManager_RequestForCreateFolder()
End Sub

Sub ABMFileManager_RequestForCutPaste(fromFolder as String, jsonList as String)
End Sub

Sub ABMFileManager_RequestForDelete(jsonList as String)
End Sub

Sub ABMFileManager_RequestForDownload(jsonList as String)
End Sub

Sub ABMFileManager_RequestForRename(oldFileName as String)
End Sub

Sub ABMFileManager_UploadFailed(status As String, message as String)
End Sub

Sub ABMFileManager_UploadStarted()
End Sub

Sub ABMFileManager_Uploaded()
End Sub

Sub ABMGoogleMap_Clicked(Latitude as Double, Longitude as Double)
End Sub

Sub ABMGoogleMap_CurrentLocation(Latitude as Double, Longitude as Double)
End Sub

Sub ABMGoogleMap_Error(ErrorMessage as String)
End Sub

Sub ABMGoogleMap_GeoCodeResult(Latitude as Double, Longitude as Double)
End Sub

Sub ABMGoogleMap_MarkerClicked(MarkerId as String)
End Sub

Sub ABMGoogleMap_MarkerDragEnd(Latitude as Double, Longitude as Double)
End Sub

Sub ABMGoogleMap_MarkerDragStart(MarkerId as String)
End Sub

Sub ABMGoogleMap_Ready()
End Sub

Sub ABMGoogleMap_ReverseGeoCodeResult(Address as String)
End Sub

Sub ABMImage_Clicked(Target As String)
End Sub

Sub ABMInput_AutoCompleteClicked(uniqueId as String)
End Sub

Sub ABMInput_Changed(value As String)
End Sub

Sub ABMInput_EnterPressed(value As String)
End Sub

Sub ABMInput_GotFocus()
End Sub

Sub ABMInput_LostFocus()
End Sub

Sub ABMInput_TabPressed(target As String, value As String)
End Sub

Sub ABMLabel_Clicked(Target As String)
End Sub

Sub ABMList_Clicked(ItemId as String)
End Sub

Sub ABMPage_AjaxError(uniqueId as String, error as String)
End Sub

Sub ABMPage_AjaxResult(uniqueId as String, result as String)
End Sub

Sub ABMPage_Authenticated(Params As Map)
End Sub

Sub ABMPage_B4JSAjaxError(uniqueId as String, error as String)
End Sub

Sub ABMPage_B4JSAjaxResult(uniqueId as String, result as String)
End Sub

Sub ABMPage_B4JSInputboxResult(returnName As String, result As String)
End Sub

Sub ABMPage_B4JSMsgboxResult(returnName As String, result As String)
End Sub

Sub ABMPage_CellClicked(Target as String, RowCell as String)
End Sub

Sub ABMPage_DebugConsole(message As String)
End Sub

Sub ABMPage_DragCancelled(component as String, source as String)
End Sub

Sub ABMPage_DragStart(component as String, source as String)
End Sub

Sub ABMPage_Dropped(Params as Map)
End Sub

Sub ABMPage_FileUploaded(FileName as String, success as Boolean)
End Sub

Sub ABMPage_FirebaseAuthError(extra As String)
End Sub

Sub ABMPage_FirebaseAuthStateChanged(IsLoggedIn as boolean)
End Sub

Sub ABMPage_FirebaseStorageError(jobID As String, extra As String)
End Sub

Sub ABMPage_FirebaseStorageResult(jobID As String, extra As String)
End Sub

Sub ABMPage_InputboxResult(returnName As String, result As String)
End Sub

Sub ABMPage_ModalSheetDismissed(ModalSheetName as String)
End Sub

Sub ABMPage_ModalSheetReady(ModalSheetName as String)
End Sub

Sub ABMPage_MsgboxResult(returnName As String, result As String)
End Sub

Sub ABMPage_MultiCellFinished(Params As Map)
End Sub

Sub ABMPage_NativeResponse(jsonMessage As String)
End Sub

Sub ABMPage_NavigationbarClicked(Action As String, Value As String)
End Sub

Sub ABMPage_NavigationbarSearch(search as String)
End Sub

Sub ABMPage_NextContent(TriggerComponent As String)
End Sub

Sub ABMPage_ParseEvent(Params As Map)
End Sub

Sub ABMPage_RowClicked(Target as String, Row as String)
End Sub

Sub ABMPage_SignedOffSocialNetwork(Network as String, Extra as String)
End Sub

Sub ABMPage_SizeChanged(previous as String, current as String)
End Sub

Sub ABMPage_ToastClicked(ToastId As String, Action As String)
End Sub

Sub ABMPage_ToastDismissed(ToastId As String)
End Sub

Sub ABMPage_VisibilityState(State as String)
End Sub

Sub ABMPagination_PageChanged(OldPage as int, NewPage as int)
End Sub

Sub ABMPatternLock_Changed(target as String, value as String)
End Sub

Sub ABMPivotTable_Loaded(Success As Boolean)
End Sub

Sub ABMPivotTable_RendererChanged(newRenderer As String)
End Sub

Sub ABMPlanner_ActiveDayChanged(day As Int)
End Sub

Sub ABMPlanner_MenuClicked(MenuType As String, Value as String)
End Sub

Sub ABMPlanner_MinutesClicked(Value As String)
End Sub

Sub ABMPlanner_Refreshed()
End Sub

Sub ABMRadioGroup_Clicked(Target As String)
End Sub

Sub ABMRange_Changed(start as String, stop as String)
End Sub

Sub ABMReport_Build(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMReport_CleanUp(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMReport_FirstRun(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMReport_Refresh(internalPage as ABMPage, internalID as String)
End Sub

Sub ABMSVGSurface_SVGClicked(elementID as String)
End Sub

Sub ABMSVGSurface_SVGTicked(timerID as String, extra as String)
End Sub

Sub ABMSlider_Changed(value as String)
End Sub

Sub ABMSmartWizard_NavigationFinished(ReturnName as String)
End Sub

Sub ABMSmartWizard_NavigationToStep(fromReturnName As String, toReturnName as String)
End Sub

Sub ABMSwitch_Clicked(Target As String)
End Sub

Sub ABMTable_Changed(Params as Map)
End Sub

Sub ABMTable_Clicked(PassedRowsAndColumns as List)
End Sub

Sub ABMTable_SortChanged(DataField as String, Order as String)
End Sub

Sub ABMTableMutable_Changed(Params as Map)
End Sub

Sub ABMTableMutable_Clicked(PassedRowsAndColumns as List)
End Sub

Sub ABMTableMutable_SortChanged(DataField as String, Order as String)
End Sub

Sub ABMTabs_Clicked(TabReturnName as String)
End Sub

Sub ABMTimeLine_Added(uniqueID as String)
End Sub

Sub ABMTimeLine_BackToStart()
End Sub

Sub ABMTimeLine_DataLoaded()
End Sub

Sub ABMTimeLine_MovedToSlide(uniqueID as String)
End Sub

Sub ABMTimeLine_Removed(uniqueID as String)
End Sub

Sub ABMTreeTable_Clicked(TreeRowId as String, TreeCellId as String)
End Sub

Sub ABMTreeTable_Dropped(Params as Map)
End Sub

Sub ABMTreeTable_NeedsRefreshChildren(rowId As String)
End Sub

Sub ABMVideo_YouTubeStateChanged(State As Int)
End Sub

Enjoy...
 

Mashiane

Expert
Licensed User
Longtime User
ABMaterial Component Creation (Initialization) Quick Reference: For more details explore the XML document.

Just like in B4X, to create a component/control in ABM, one used the Initialize statement. Some controls through have more than one Initialize statements to perform initialize the control differently. Below is a quick reference of how one can create any of the components in ABM.

One should also note that in some of the Initialize variables, one needs to pass ABM Enumeration Constants. The listing below is based on the component class name for ease of reference. When initializing a component, you can use the variable name you have defined it to be and replace the class name. Some of the components are children of other components. For more details explore the ABM Website.

B4X:
'*****
ABMActionButton.Initialize(page As ABMPage,id As String,iconName As String,iconAwesomeExtra As String,themeName As String)
'*****
ABMActionButton.Initialize2(page As ABMPage,id As String,iconName As String,iconAwesomeExtra As String,openDirection As String,positionMainButton As String,positionTopBottomPx As int,positionLeftRightPx As int,themeName As String)
'*****
ABMAnimation.Initialize(name As String,durationMs As int,tween As String)
'*****
ABMAudioPlayer.Initialize(page As ABMPage,id As String,narrow As boolean,autoPlay As boolean,showLyrics As boolean,themeName As String)
'*****
ABMAudioPlayerSong.Initialize(audioUrl As String)
'*****
ABMBadge.Initialize(page As ABMPage,id As String,text As String,isNew As boolean,themeName As String)
'*****
ABMButton.InitializeFlat(page As ABMPage,id As String,iconName As String,iconAlign As String,Text As String,themeName As String)
'*****
ABMButton.InitializeFloating(page As ABMPage,id As String,iconName As String,themeName As String)
'*****
ABMButton.InitializeRaised(page As ABMPage,id As String,iconName As String,iconAlign As String,Text As String,themeName As String)
'*****
ABMCalendar.Initialize(page As ABMPage,id As String,defaultDate As String,firstDayOfWeek As int,language As String,defaultView As String,themeName As String)
'*****
ABMCalendarEvent.Initialize(eventId As String,title As String,startTime As String)
'*****
ABMCanvas.Initialize(page As ABMPage,id As String,backColor As String,backColorIntensity As String,widthPx As int,heightPx As int,scaleToFit As boolean)
'*****
ABMCanvasObject.InitializeAsCircle(page As ABMPage,id As String,centerX As int,centerY As int,radius As int,raiseMouseDownUp As boolean)
'*****
ABMCanvasObject.InitializeAsRectangle(page As ABMPage,id As String,x As int,y As int,width As int,height As int,raiseMouseDownUp As boolean)
'*****
ABMCard.InitializeAsCard(page As ABMPage,id As String,title As String,content As String,size As String,themeName As String)
'*****
ABMCard.InitializeAsPanel(page As ABMPage,id As String,content As String,themeName As String)
'*****
ABMChart.Initialize(page As ABMPage,id As String,chartType As String,chartRatio As String,themeName As String)
'*****
ABMChartSerie.InitializeForBar()
'*****
ABMChartSerie.InitializeForLine(serieIndex As String)
'*****
ABMChartSerie.InitializeForPie()
'*****
ABMChat.Initialize(page As ABMPage,id As String,heightPx As int,maxWidthPx As int,maxBubbleWidthPx As int,themeName As String)
'*****
ABMChat.Initialize2(page As ABMPage,id As String,maxWidthPx As int,maxBubbleWidthPx As int,themeName As String)
'*****
ABMChatBubble.Initialize(isFrom As String,text As String,extraInfo As String,forMeThemeName As String,forThemThemeName As String)
'*****
ABMCheckbox.Initialize(page As ABMPage,id As String,text As String,state As boolean,themeName As String)
'*****
ABMChip.Initialize(page As ABMPage,id As String,text As String,canBeClosed As boolean,themeName As String)
'*****
ABMChronologyList.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMCodeLabel.Initialize(page As ABMPage,id As String,text As String,language As String)
'*****
ABMCombo.Initialize(page As ABMPage,id As String,title As String,maxHeightPx As int,themeName As String)
'*****
ABMCombo.InitializeWithSize(page As ABMPage,id As String,title As String,maxHeightPx As int,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,themeName As String)
'*****
ABMComposer.Initialize(page As ABMPage,id As String,marginLeft As String,themeName As String)
'*****
ABMComposerBlock.Initialize(page As ABMPage,ID As String,blockTheme As String)
'*****
ABMContainer.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMContainer.InitializeAnimated(page As ABMPage,id As String,initialAnimationName As String,themeName As String)
'*****
ABMContainer.InitializeCollapsable(page As ABMPage,id As String,themeName As String,headingThemeName As String,bodyThemeName As String,collapsed As boolean)
'*****
ABMCustomCard.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMCustomComponent.Initialize(ba As BA,eventName As String,callObject As Object,page As ABMPage,id As String,css As String)
'*****
ABMDateTimePicker.Initialize(page As ABMPage,id As String,dtsType As String,date As long,title As String,themeName As String)
'*****
ABMDateTimePicker.InitializeISO(page As ABMPage,id As String,dtsType As String,date As String,title As String,themeName As String)
'*****
ABMDateTimePicker.InitializeWithSize(page As ABMPage,id As String,dtsType As String,date As long,title As String,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,themeName As String)
'*****
ABMDateTimePicker.InitializeWithSizeISO(page As ABMPage,id As String,dtpType As String,date As String,title As String,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,themeName As String)
'*****
ABMDateTimeScroller.Initialize(page As ABMPage,id As String,dtsType As String,dtsMode As String,date As long,title As String,themeName As String)
'*****
ABMDateTimeScroller.InitializeISO(page As ABMPage,id As String,dtsType As String,dtsMode As String,date As String,title As String,themeName As String)
'*****
ABMDateTimeScroller.InitializeWithSize(page As ABMPage,id As String,dtsType As String,dtsMode As String,date As long,title As String,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,themeName As String)
'*****
ABMDateTimeScroller.InitializeWithSizeISO(page As ABMPage,id As String,dtsType As String,dtsMode As String,date As String,title As String,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,themeName As String)
'*****
ABMDivider.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMEditor.Initialize(page As ABMPage,id As String,isEnabled As boolean,hasToolbar As boolean,themeName As String)
'*****
ABMFileInput.Initialize(page As ABMPage,id As String,pathPlaceholderText As String,buttonText As String,doValidation As boolean,pathThemeName As String,buttonThemeName As String)
'*****
ABMFileInput.InitializeWithSize(page As ABMPage,id As String,pathPlaceholderText As String,buttonText As String,doValidation As boolean,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,pathThemeName As String,buttonThemeName As String)
'*****
ABMFileManager.Initialize(page As ABMPage,id As String,root As String,themeName As String)
'*****
ABMFlexWall.Initialize(page As ABMPage,id As String,rowHeightPx As int)
'*****
ABMGeneratorCRUDDefinition.Initialize(IDFieldName As String,tableName As String,title As String,saveButtonText As String,cancelButtonText As String,YesButtonText As String,NoButtonText As String,closeButtonText As String,deleteMessage As String,invalidInputMessage As String)
'*****
ABMGoogleMap.Initialize(page As ABMPage,id As String,Latitude As double,Longitude As double,zoom As int,heightPx As int,mapType As String,clusterSize As int)
'*****
ABMGoogleMap.InitializeAsPanorama(page As ABMPage,id As String,Latitude As double,Longitude As double,zoom As int,heightPx As int,headingDegrees As int,pitchDegrees As int)
'*****
ABMHtmlUtils.Initialize()
'*****
ABMImage.Initialize(page As ABMPage,id As String,source As String,opacity As double)
'*****
ABMImage.InitializeAsToggle(page As ABMPage,id As String,source1 As String,source2 As String,initialShowFirst As boolean,opacity As double)
'*****
ABMImageSlider.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMInput.Initialize(page As ABMPage,id As String,inputType As String,title As String,isTextArea As boolean,themeName As String)
'*****
ABMInput.InitializeWithSize(page As ABMPage,id As String,inputType As String,title As String,offsetSmall As int,offsetMedium As int,offsetLarge As int,sizeSmall As int,sizeMedium As int,sizeLarge As int,isTextArea As boolean,themeName As String)
'*****
ABMItemList.Initialize(page As ABMPage,id As String,labelListType As String)
'*****
ABMLabel.Initialize(page As ABMPage,id As String,text As String,size As String,withPadding As boolean,themeName As String)
'*****
ABMList.Initialize(page As ABMPage,id As String,listCollapseType As String,themeName As String)
'*****
ABMList.InitializeWithMaxHeight(page As ABMPage,id As String,listCollapseType As String,maxHeight As int,themeName As String)
'*****
ABMModalSheet.Initialize(page As ABMPage,id As String,fixedFooter As boolean,modalsheetType As String,themeName As String)
'*****
ABMNavigationBar.Initialize(page As ABMPage,id As String,barType As String,title As String,topBarDropDownBelow As boolean,topBarFixed As boolean,sideBarWidthPx As int,sideBarItemHeightPx As int,sideBarTopComponent As ABMComponent,sideBarCollapseType As String,themeName As String)
'*****
ABMNavigationBar.InitializeExtraContent(id As String,open As boolean,themeName As String)
'*****
ABMNavigationBar.InitializeExtraHalfButton(id As String,iconName As String,size As String,position As String,themeName As String)
'*****
ABMNavigationBar.InitializeSearchButton(smallWidthPx As int,mediumWidthPx As int,largeWidthPx As int,visibility As String)
'*****
ABMPDFViewer.Initialize(page As ABMPage,id As String,heightPx As int,documentURL As String,themeName As String)
'*****
ABMPage.Initialize(ba As BA,name As String,handler As String,centerInPageWithPadding As boolean,SessionMaxInactiveIntervalSeconds As int)
'*****
ABMPage.InitializeWithTheme(name As String,handler As String,centerInPageWithPadding As boolean,SessionMaxInactiveIntervalSeconds As int,theme As ABMTheme)
'*****
ABMPage.InitializeWithThemes(name As String,handler As String,centerInPageWithPadding As boolean,SessionMaxInactiveIntervalSeconds As int,themes As List)
'*****
ABMPagination.Initialize(page As ABMPage,id As String,maxNumberOfPages As int,hasFirstLast As boolean,hasPreviousNext As boolean,themeName As String)
'*****
ABMParallax.Initialize(page As ABMPage,id As String,imageName As String,height As int)
'*****
ABMParallax.InitializeScaled(page As ABMPage,id As String,imageName As String,heightSmall As int,heightMedium As int,heightLarge As int)
'*****
ABMParallax.InitializeScaledWithContainer(page As ABMPage,id As String,imageName As String,heightSmall As int,heightMedium As int,heightLarge As int,container As ABMContainer,containerTopSmallPx As int,containerTopMediumPx As int,containerTopLargePx As int)
'*****
ABMParallax.InitializeWithContainer(page As ABMPage,id As String,imageName As String,height As int,container As ABMContainer,containerTopPx As int)
'*****
ABMPatternLock.Initialize(page As ABMPage,id As String,matrixSize As int,themeName As String)
'*****
ABMPercentSlider.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMPivotTable.Initialize(page As ABMPage,id As String,heightPx As int,documentURL As String,columns As String,rows As String,hiddenFields As String,readOnly As boolean,themeName As String)
'*****
ABMPivotTable.InitializeAutoHeight(page As ABMPage,id As String,documentURL As String,columns As String,rows As String,hiddenFields As String,readOnly As boolean,themeName As String)
'*****
ABMPlanner.Initialize(page As ABMPage,id As String,showWeekend As boolean,fromHour As int,toHour As int,minutesInterval As int,readOnly As boolean,themeName As String)
'*****
ABMPlannerTask.Initialize(day As int,taskID As String,startHour As int,startMinututesPer As int,lengthMinutesPer As int,text As String,themeColorIndex As int)
'*****
ABMPoint.Initialize()
'*****
ABMRadioGroup.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMRange.Initialize(page As ABMPage,id As String,start As double,stop As double,min As double,max As double,step As double,themeName As String)
'*****
ABMReport.Initialize(ba As BA,eventName As String,callObject As Object,page As ABMPage,id As String,css As String,pageBreak As String)
'*****
ABMReportBlock.InitializeAsContainer(page As ABMPage,id As String,themeName As String,pageBreak As String)
'*****
ABMReportBlock.InitializeAsTexts(texts As List,widthPercentages As List,cssClasses As List,pageBreak As String)
'*****
ABMSVGElement.Initialize(elementID As String,SVGElementType As int)
'*****
ABMSVGSurface.Initialize(page As ABMPage,id As String,viewbox As String,preserveAspectRatio As String,svgWidthPx As String,svgHeightPx As String)
'*****
ABMSideBar.Initialize(page As ABMPage,id As String,sideBarWidthPx As int,sideBarItemHeightPx As int,sideBarStartTopPx As int,sideBarTopComponent As ABMComponent,sideBarCollapseType As String,themeName As String)
'*****
ABMSideBar.InitializeAsPanel(page As ABMPage,id As String,sideBarWidthPx As int,sideBarStartTopPx As int,sideBarTopComponent As ABMComponent,themeName As String,panelId As String,panelThemeName As String)
'*****
ABMSignaturePad.Initialize(page As ABMPage,id As String,widthPx As int,heightPx As int,clearColor As String,clearColorIntensity As String,penColor As String,penColorIntensity As String,zDepth As String)
'*****
ABMSlider.Initialize(page As ABMPage,id As String,value As double,min As double,max As double,step As double,themeName As String)
'*****
ABMSmartWizard.Initialize(page As ABMPage,id As String,previousButtonText As String,nextButtonText As String,finishButtonText As String,themeName As String)
'*****
ABMSocialOAuth.Initialize(page As ABMPage,id As String)
'*****
ABMSocialShare.Initialize(page As ABMPage,id As String,url As String,jumpToComponent As ABMComponent,text As String,buttonType As String)
'*****
ABMSwitch.Initialize(page As ABMPage,id As String,onText As String,offText As String,state As boolean,themeName As String)
'*****
ABMSwitch.Initialize2(page As ABMPage,id As String,title As String,onText As String,offText As String,state As boolean,themeName As String)
'*****
ABMTable.Initialize(page As ABMPage,id As String,isSortable As boolean,usingQueriesToSort As boolean,isInteractive As boolean,themeName As String)
'*****
ABMTable.InitializeScrollable(page As ABMPage,id As String,isSortable As boolean,usingQueriesToSort As boolean,isInteractive As boolean,Widths As List,themeName As String)
'*****
ABMTableCell.Initialize()
'*****
ABMTableMutable.Initialize(page As ABMPage,id As String,isSortable As boolean,usingQueriesToSort As boolean,isInteractive As boolean,themeName As String)
'*****
ABMTabs.Initialize(page As ABMPage,id As String,themeName As String)
'*****
ABMTabs.Initialize2(page As ABMPage,id As String,fixedHeightPx As int,marginTopPx As int,iconTopPx As int,themeName As String)
'*****
ABMTheme.Initialize(name As String)
'*****
ABMTimeLine.Initialize(page As ABMPage,id As String,titleSlideUniqueID As String,titleSlideThemeName As String,fileName As String,themeName As String)
'*****
ABMTimeLineDate.Initialize(year As int)
'*****
ABMTimeLineEra.Initialize(startYear As int,endYear As int)
'*****
ABMTimeLineLocation.Initialize(iconURL As String,latitude As float,longitude As float)
'*****
ABMTimeLineMedia.Initialize(url As String)
'*****
ABMTimeLineSlide.Initialize(uniqueID As String,startYear As int,slideTheme As String)
'*****
ABMTimeLineText.Initialize()
'*****
ABMTreeTable.Initialize(page As ABMPage,id As String,isInteractive As boolean,themeName As String,colWidthPx As int,depthThemes As List,totalColspan As int)
'*****
ABMTreeTableCell.Initialize(id As String,stringValue As String,colOffset As int,colSpan As int,isEditable As boolean,theme As String)
'*****
ABMTreeTableCell.InitializeAsComponent(id As String,component As ABMComponent,arrayName As String,colOffset As int,colSpan As int,theme As String)
'*****
ABMTreeTableCell.InitializeAsIcon(id As String,iconName As String,iconAwesomeExtra As String,colOffset As int,colSpan As int,theme As String)
'*****
ABMTreeTableRow.Initialize(depth As int,treeRowId As String,treeRowParentId As String,isFooterForRowId As String,dragDropTreeRowName As String,iconColorThemeName As String,overruleDefaultDepthThemeName As String)
'*****
ABMUpload.Initialize(page As ABMPage,id As String,message As String,buttonText As String,themeName As String)
'*****
ABMVideo.InitializeHTML5(page As ABMPage,id As String,source As String,hasControls As boolean,videoType As String)
'*****
ABMVideo.InitializeVimeo(page As ABMPage,id As String,source As String,hasFrameBorder As boolean,allowFullScreen As boolean)
'*****
ABMVideo.InitializeYouTube(page As ABMPage,id As String,source As String,origin As String,hasControls As boolean,hasFrameBorder As boolean,allowFullScreen As boolean,volume As int)
'*****
B4JSVariable.Initialize(varName As String,B4JSClassName As String)
'*****
NativeApp.Initialize(packageName As String,applicationName As String,applicationTitle As String,ABMaterialWebAppUrl As String)
 
Top