B4J Library [Web][ABMaterial] Framework for WebApps

TIP: For absolute beginners with ABM, Get started with the Mini Template
TIP: Get started with 'ABMaterial For Dummies' by Harris here! (lessons)
TIP:
My mini course on Youtube by MichalK73

ABMaterial is a framework combining a tuned Materialize CSS with the free programming tool B4J. It allows creating WebApps that not only look great thanks to Googles Material Design, but can be programmed with the powerful free tool from Anywhere Software without any knowledge of HTML, CSS or Javascript.

ABMDragonfly4.00.png


ABMaterial has over 45 themeable controls and some useful helpers.

Components:

  • ABMActionButton
  • ABMAudioPlayer (1.08)
  • ABMBadge
  • ABMButton
  • ABMCanvas
  • ABMCalendar
  • ABMCard
  • ABMChart (Plugin support 2.00)
  • ABMChat (2.50)
  • ABMCheckbox
  • ABMChronologyList (2.00)
  • ABMCombo
  • ABMCustomControl (1.05)
  • ABMChip
  • ABMCodeLabel
  • ABMDivider
  • ABMDateTimeScroller (1.06)
  • ABMDateTimePicker (1.06)
  • ABMEditor (1.07)
  • ABMFileInput (1.20+)
  • ABMGoogleMap
  • ABMLabel
  • ABMList
  • ABMImage
  • ABMImageSlider
  • ABMInputField
  • ABMRadioGroup
  • ABMPagination (1.04)
  • ABMPatternLock (1.20+)
  • ABMPDFViewer (1.08)
  • ABMPercentSlider (2.50)
  • ABMPlanner (2.50)
  • ABMPivotTable (1.08)
  • ABMRange (1.05)
  • ABMSignaturePad
  • ABMTimeLine (1.10, depreciated in 4.00)
  • ABMSlider (1.05)
  • ABMSmartWizard (3.00)
  • ABMSocialShare (1.07)
  • ABMSocialOAuth
  • ABMSVGSurface (1.20+)
  • ABMSwitch
  • ABMTabs
  • ABMTreeTable (1.04)
  • ABMUpload
  • ABMVideo

Helpers:
  • ABMContainer
  • ABMFlexWall (1.10)
  • ABMGenerator (1.07)
  • ABMModalSheet
  • ABMNavigationBar
  • ABMPage
  • ABMParallax
  • ABMSideBar (2.00)
  • ABMTable
  • ABMTableMutable (1.20+)
Other:
  • Firebase Auth (1.20+)
  • Firebase Storage (1.20+)
  • Configurable App and Content folders (2.00)
  • Lorem Ipsum Generator (2.00)
  • Grid Builder (2.00+)
The Grid Builder:
With the Grid Builder you can build the responsive framework very easy. This has been the most difficult part for beginners to understand. But now with the builder, you have no reason to not use ABMaterial :)

gridbuilder1.png


There is an online demo at http://abmaterial.com
Alternative url: http://prd.one-two.com:51042/demo/

NEW: You can now support BANano and ABMaterial here too: https://www.patreon.com/alwaysbusy


This means it is free to use, but consider this: it took me already thousands of hours to program ABMaterial, all done in my free time early in the morning and deep into the night. Not only will a donation push me to continue developing ABMaterial , remember, you'll get a warm and fuzzy feeling doing it!

Download version 5.12 - for jServer 4.00 (open source, library only):

ALWAYS TAKE A BACKUP BEFORE USING A NEW VERSION!


ABMaterial 5.12 is now available on github and is open sourced :cool: (AS IS)! This version has been in heavy use (development and production) within our company for over a year now without major alterations, so I consider it very stable and ready to be open sourced.

I trust no one here will publish a clone or take credit for my work and I would consider it common courtesy if you find a bug/fix/new feature, you report back to me so I can make the same changes in the official library and everyone can benefit from it.


Note: next to downloading the library, you need also to download the accompanying www zip files from the same github (releases) containing the latest javascript/css/font files.

The procedure from Github for 5.12:

1. Download https://github.com/RealAlwaysbusy/A...eleases/download/v5.12/ABMaterial5.12-bin.zip
2. Download https://github.com/RealAlwaysbusy/A...r4.00/releases/download/v5.12-www/www5.12.zip
3. Unzip ABMaterial5.12-bin.zip and copy all .xml and .jar files to you B4J Libraries folder
4. Unzip www5.12.zip
5. In the projects you are working on (e.g. a for Dummies project) delete the following folders in \www
  • css
  • font
  • js
6. Copy from the unzipped www5.12.zip the 3 folder (css/font/js) to the \www folder where you just deleted these 3 folders.

Additional Resources:

Demo source code (for v4.51, not yet updated for 5.12, but still usefull to learn ABM): https://gorgeousapps.com/ABMExtras4.51.zip

I hope you enjoy it as much as I did creating it and I look forward to see the killer apps you will make with ABMaterial!

Also consider BANano if you are planning to write Websites/Apps in B4J!

Alain Bailleul
Alwaysbusy's Corner
 
Last edited:

mwebim

New Member
Licensed User
Longtime User
Hi Alwaysbusy
This looks amazing.
I tried to run it in b4j and I get the following error. I previously upgraded java to version 8 update 66
I get it building ok but on running comes up with this error

java.lang.ExceptionInInitializerError
Caused by: java.lang.RuntimeException: java.lang.UnsupportedClassVersionError: com/ab/abmaterial/ABMTheme : Unsupported major.minor version 52.0
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:114)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:90)
at abmaterial.ab.com.main.<clinit>(main.java:17)
Caused by: java.lang.UnsupportedClassVersionError: com/ab/abmaterial/ABMTheme : Unsupported major.minor version 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at anywheresoftware.b4a.shell.Shell.getCorrectClassName(Shell.java:485)
at anywheresoftware.b4a.shell.Shell.createObject(Shell.java:472)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:243)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
... 2 more
Exception in thread "main"


Any ideas

regards

mike
 

b4auser1

Well-Known Member
Licensed User
Longtime User
Wish: I believe that standard control to authenticate users with facebook and google accounts will be usefull to avoid own authentication in many cases.
 

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
Hello again!!!

How I can add items to a list at runtime and refresh the page every time ?

Right now I 'm doing with Page.Refresh after clickar on a table , element adds me on the list, but the page tables are me " rare " and stop behaving as usual. And you can not be ordered depending on the title of the column that you click , etc.

In addition are the colors of the table also changed.

Please. Look at this images:

Before refresh:
beforerefreshpage-png.38971


After refresh:
afterrefreshpage-png.38972
 

Attachments

  • BeforeRefreshPage.PNG
    BeforeRefreshPage.PNG
    13.5 KB · Views: 793
  • AfterRefreshPage.PNG
    AfterRefreshPage.PNG
    13.1 KB · Views: 781

billyrudi

Active Member
Licensed User
Longtime User
@billyrudi I'm sorry, but I do not understand your first question. Do you want to disable the button? You can check if the login/password is ok in b4j (like in the demo).
As for the hourglass, there is one when you navigate between pages. I see if it it possible to make one that can be called by code.
the first question is:
if in login panel i click the buttom and i must wait a webserver to verify the username and password there is a way to lock the panel or the botton to prevent more than one click?
for the second how i can show the hourglass that you you show when navigate between pages.
 

Cableguy

Expert
Licensed User
Longtime User
Hello again!!!

How I can add items to a list at runtime and refresh the page every time ?

Right now I 'm doing with Page.Refresh after clickar on a table , element adds me on the list, but the page tables are me " rare " and stop behaving as usual. And you can not be ordered depending on the title of the column that you click , etc.

In addition are the colors of the table also changed.

Please. Look at this images:

Before refresh:
beforerefreshpage-png.38971


After refresh:
afterrefreshpage-png.38972

About adding to the list, I can't help you there, but after you have added to the list, call "ABMShared.NavigateToPage" to reload the entire page
 

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
Hi alwaysbusy,
another question..
there is the way to add items to an ABMList programmatically and not in the BuildPage event?

I'm trying to do it in this way:

B4X:
Dim list1 As ABMList = page.Component("list1")

Sub tbl2_clicked(PassedRowsAndColumns As List)
    ' is the root table
    Dim tblCellInfo As ABMTableCell = PassedRowsAndColumns.Get(0)
    Dim tbl As ABMTable = page.Component(tblCellInfo.TableName)
    Dim StringSelect As String = tbl.GetString(tblCellInfo.Row, tblCellInfo.Column)
    Dim list1 As ABMList = page.Component("list1")
    list1.AddSubItem("H1", "S"&(myToastId+1), BuildSimpleItem("L1H1S"&(myToastId+1),"", StringSelect))
    list1.Refresh
    page.Refresh  

    myToastId = myToastId + 1   
    page.ShowToast("toast" & myToastId, "toastred", "Clicked " & tblCellInfo.TableName & " row " & tblCellInfo.Row & " column " & tblCellInfo.Column, 5000)
End Sub

But I've got 2 "problems":
  1. list1.refresh (apparently not work)
  2. page.refresh (works, but with the problems indicated in my previous post deforming the tables)
 

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
I've founded a abnormal behaviour using fixed size tables.

The footer band is putted twice:
before-jpg.38976


When I click y any row and the page is refreshed, the aspect is:
after-jpg.38977


And then, you can click in both rows with data...

Bye.
 

Attachments

  • Before.JPG
    Before.JPG
    22.2 KB · Views: 715
  • After.JPG
    After.JPG
    23.5 KB · Views: 753

alwaysbusy

Expert
Licensed User
Longtime User
@billyrudi No, but I'll see what I can do. Making good progress on the bugs on the refresh of the table and list. There were some shortcuts I created when I started writing the framework that don't appear to work now that the framework is bigger. Quite some work to do but it looks you would not have to make any changes to your code once its done.
 

billyrudi

Active Member
Licensed User
Longtime User
hi with this code i'm able to load item perfectly.
B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
   Log("Connected")
   ws = WebSocket1   
   If ABMShared.NeedsAuthorization Then
     If ws.Session.GetAttribute2("IsAuthorized", "") = "" Then
       ABMShared.NavigateToPage(ws, "../")
       Return
     End If
   End If
   ' connect our page with the websocket   
   page.SetWebSocket(ws)
   ' Prepare the page IMPORTANT!
   page.Prepare
   CaricaGriglia
   
End Sub


Sub CaricaGriglia()
    Dim list1 As ABMList = page.Component(2,1,"list1")
    Dim ll As List
    Try
        ll = ws.Session.GetAttributesNames
    Dim ii As Int
    For ii = 0 To ll.Size -1
        Dim s As String
        s = ll.Get (ii)
        If s.StartsWith("$$") Then
            Dim lstmez As List = ws.Session.GetAttribute (s)
            Dim jj As Int
            For jj = 0 To lstmez.Size -1
                Dim sl() As String
                Dim tll As String
                tll = lstmez.Get (jj)
                sl = Regex.Split ("\|",tll)
                Dim quando As String
                quando = sl(8)
                '  20151117090830
                quando = quando.SubString2 (6 ,8) & "/" &  quando.SubString2(4,6) & "/" &  quando.SubString2(0,4)& " " & quando.SubString2(8,10) & ":" &  quando.SubString2(10,12)
                list1.AddSubItem("H1",  sl(2), BuildSimpleItem( sl(3),  "","{B}" & sl(2) & "{/B} - " & quando  & "{BR}{B}T1:{/B}" & Round2( sl(4),1) & "°C"  & " - {B}T2:{/B}:" & Round2(sl(5),1) & "°C" & " - {B}T3:{/B}:" & Round2(sl(6),1) & "°C" & " - {B}T4:{/B}:" & Round2(sl(7),1) & "°C"))
                Log(sl(2))   
            Next
           
           
        End If
    Next
        list1.Refresh
        page.Refresh

    Catch
       
        Log(LastException)
    End Try
End Sub
 

billyrudi

Active Member
Licensed User
Longtime User
Excuseme for my questions.... but working ...
there is a way to make a reverse geocoding using this instructions for example?

B4X:
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 8,
    center: {lat: 40.731, lng: -73.997}
  });
  var geocoder = new google.maps.Geocoder;
  var infowindow = new google.maps.InfoWindow;

  document.getElementById('submit').addEventListener('click', function() {
    geocodeLatLng(geocoder, map, infowindow);
  });
}

function geocodeLatLng(geocoder, map, infowindow) {
  var input = document.getElementById('latlng').value;
  var latlngStr = input.split(',', 2);
  var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
  geocoder.geocode({'location': latlng}, function(results, status) {
    if (status === google.maps.GeocoderStatus.OK) {
      if (results[1]) {
        map.setZoom(11);
        var marker = new google.maps.Marker({
          position: latlng,
          map: map
        });
        infowindow.setContent(results[1].formatted_address);
        infowindow.open(map, marker);
      } else {
        window.alert('No results found');
      }
    } else {
      window.alert('Geocoder failed due to: ' + status);
    }
  });
}
?
 

Roberto P.

Well-Known Member
Licensed User
Longtime User
there is a problem: after some time, the application is disconnected and is no longer reachable. There is a timer that stops or after a little time?

thank you
 
Top