B4J Tutorial [ABMaterial/BANano] Making BANano Libraries for ABMaterial

PREFACE:
As some may know, ABM has some basic JavaScript functionality build-in called B4JS. It was the predecessor of BANano. However, because of the design of ABM, B4JS could never reach its full potential. But from that came the idea to write a full blown true B4J to JavaScript Transpiler was born: BANano! (Thinking in retrospect, B4JS in ABM may have been a poor choice of words, as BANano covers much more that term ;) )

In my day job, we still use ABM in most of our client projects. But sometimes we just miss that extra BANano can do on the Browser side. For new projects, we now mostly use a BANanoServer instead of an ABMServer, but we still have many ABM apps running and continue to write extra functionalities to those apps. What if we could use BANano generated code IN ABMaterial?

Hence this new idea came up: If BANano could generate .b4xlib libraries, writing the 'glue' between ABM and BANano, that would be a great asset to add features to ABM!

An Example of an ABMButton hover extension:

1. One writes BANano code that when one hovers over an ABMButton, it changes color

In pure ABM, it is kind of a hassle, but in BANano this is pretty simple:

The ABMHover Class
B4X:
#Event: Hover(ID As String, IsOver As Boolean)

Sub Class_Globals
    Private BANano As BANano 'ignore
    Private mEventName As String
End Sub

'Initializes the object, setting the event
Public Sub Initialize(eventName As String)
    mEventName = eventName
End Sub

' Adds hover functionality to an ABM Component
public Sub AddHover(ID As String)
    ' get the element with the ID
    Dim mElement As BANanoElement
    mElement.Initialize("#" & ID)

    ' add the Mouse Enter and Leave events to the element
    Dim event As Object
    mElement.AddEventListener("mouseenter", BANano.CallBackExtra(Me, "HandleMouseEnter", event, Array(mElement)),True)
    mElement.AddEventListener("mouseleave", BANano.CallBackExtra(Me, "HandleMouseLeave", event, Array(mElement)),True)
End Sub

' the Callback for the Mouse Enter event
private Sub HandleMouseEnter(event As BANanoEvent, Element As BANanoElement) 'ignore
    ' make the button red
    Element.RemoveClass("light-blue").AddClass("red")
    ' optionaly raise an event back to ABM
    BANano.RaiseEventToABM(mEventName & "_Hover", Array("ID","IsOver"), Array(Element.Name, True), "")
End Sub

' the Callback for the Mouse Leave event
private Sub HandleMouseLeave(event As BANanoEvent, Element As BANanoElement) 'ignore
    ' make the button blue again
    Element.RemoveClass("red").AddClass("light-blue")
    ' optionaly raise an event back to ABM
    BANano.RaiseEventToABM(mEventName & "_Hover", Array("ID","IsOver"), Array(Element.Name, False), "")
End Sub

NOTES:
a. You can use BANano.RaiseEventToABM() to make a call back to the ABM server. This could be just an notice that it is done, or even a result.
But it is also possible to get something returned by the BANano methods immediately:
B4X:
public Sub TestReturningSomething(someParam As String) As Boolean
    Return True
End Sub

You can define your Event for ABM with:
B4X:
#Event: Hover(ID As String, IsOver As Boolean)

b: Comments you add before the Method declaration will be visible in the final ABMBANano lib.

2. Making a ABM BANano b4xlib

In our main, you make one call (similar to the BANano.BuildAsB4XLib() for normal BANano Libraries):
B4X:
Sub Process_Globals
    Private BANano As BANano 'ignore
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    ' you can change some output params here
    BANano.Initialize("BANano", "Hover",7) '<--------------------- the name of our lib
    BANano.JAVASCRIPT_NAME = "hover.js" '<------------------- the name of the generated JavaScript file

    ' start the build
    #if release
        BANano.BuildAsB4XlibForABM("K:\_ONETWO210203\Work2020\Objects\www", "1.0") '<-----------------------
        ExitApplication
    #else
        BANano.Build(File.DirApp)
    #end if
End Sub

' HERE STARTS YOUR APP
Sub BANano_Ready()

End Sub

The Result is this:
B4X:
Reading B4J INI in C:\Users\pi\AppData\Roaming\Anywhere Software\B4J to find Additional Libraries folder...
Found Additional Libraries folder: K:\B4J\AddLibraries
Starting to transpile...
Building K:\BANano6.11\ABMJavaScript\Objects\Hover\scripts\hover.js
Copying CSS files to WebApp assets...
Copying Javascript files to WebApp assets...
Starting to build the ABMBANanoHover.b4xlib...
==========================================================================
The following files have been created in your Additional Libraries folder K:\B4J\AddLibraries
-> ABMBANanoHover.b4xlib
-> ABMBANanoHover.Assets.zip
-> ABMBANanoHover.txt
--------------------------------------------------------------------------
Read the instructions in ABMBANanoHover.txt on how to deploy and use this library!
==========================================================================

As you can see, three files are generated:
- The .b4xlib itself
- a .zip file containing the assets (this is the CSS/JS BANano generated) MUST BE NEXT TO THE .b4xlib!
- a .txt file with some usage info:

Here for example the .txt content looks like this:
B4X:
========== Using the ABMBANanoHover Library in ABM: CHECKLIST ===============

---------- 1. Add the ABMBANanoHover library to your project ---------------

---------- 2. Add these lines in BuildPage() ---------------
page.AddExtraJavaScriptFile("bananocore.js")
page.AddExtraJavaScriptFile("Hover/hover.js")
' unless you use a specific other place where your Static Files are, this will always be "www"
Hover.UnzipAssets("www")

---------- You can now use your BANano Classes in ABM like a normal B4J class
EXAMPLE:
Dim myFirstBANanoClass As FirstBANanoClass
myFirstBANanoClass.Initialize(ws, "myFirstBANanoClass")
myFirstBANanoClass.MyFirstMethod(ws, "Hello World!")

It is a short checklist of what you have to do to use this library in ABM.

3. So we follow these few simple instructions:

3.1. In our ABM project, First we pick the newly generated library:

1611312130658.png


3.2 In BuildPage(), we add the assets:

1611312458464.png


And now we can just start using our BANano Hover code in ABM! šŸ˜Š

B4X:
public Sub ConnectPage()
   Dim button as ABMButton
   button.Initialize(page, "button", "", "", "Say Hello", "")
   page.Cell(2,1).AddComponent(button)

   ' refresh the page
   page.Refresh
   ' Tell the browser we finished loading
   page.FinishLoading
   ' restore the navigation bar position
   page.RestoreNavigationBarPosition

   Dim MyJS as ABMHover
   myJS.Initialize(ws, "myJS") ' <<<<<<<<<<<<<<<<<<<< New in 6.59 the first parameter ws has to be passed
   myJS.AddHover(ws, "button")  ' <<<<<<<<<<<<<<<<<<<< New in 6.59 the first parameter ws has to be passed
End Sub

' our Hover event (the BANano.RaiseEventToABM we did)
Sub myJS_Hover(ID As String, IsOver as Boolean)
   Log("Hover on " & ID & " -> Is Over: " & IsOver)
End Sub

And this is the result (Notice the color of the button changing and in the B4J log also the Events back):



HOW IT WORKS (For those interested in the mechanics behind it)

The .b4xlib created is a 'glue' lib with all the Public methods in it, making calls to their BANano counterparts:

For example this snippet from the ABMBANanoHover.b4xlib):
B4X:
public Sub AddHover(ws as WebSocket, ID As String)
    ws.Eval("BANhover['" & UniqueBANID & "'].addhover(arguments[0])", Array (id))
    ws.Flush
End Sub

When calling AddHover in ABM, we forward it to the method in the BANano library.

Alwaysbusy
 

Attachments

  • 1611312620698.png
    1611312620698.png
    7.2 KB · Views: 616
  • 1611313146813.png
    1611313146813.png
    22.5 KB · Views: 626
Last edited:

Cableguy

Expert
Licensed User
Longtime User
Its funny you used a button hover effect....
I have been playing with you latest code sample you provided me to my "expandable containers " issue to get that exact same effect...
So, if I understand correctly, we can create an "extraevents " kinda of BAnano library and just add the events like we would with any other B4J library?
 

Harris

Expert
Licensed User
Longtime User
OMG!

I knew there would come a day when I would be coaxed into learning BANano...

You have to know you've just opened a little pandora's box to me... so you may expect me to LEARN this!
Stealing and modding your thunder @Cableguy
I have always been afraid of anything { <> , </> }... except for coding inline colors, bold, etc. for ABMLabel's and such... ( {B} Comment By: {/B} ).

As @alwaysbusy has previously stated in prior posts - ABM is stable - so to extend it - enjoy this!
Oh joy.... (no - really!). The older we get, the more reluctant we are to the never-ending process of change.... Apparently, this does not apply to all in this world (ab)...

With all the forthcoming examples of how to apply our new found (provided) functionality - I "Shall" Learn! (as my tag line states)

Thanks
 

Harris

Expert
Licensed User
Longtime User
@Harris You can still use ABM comfy as you used to ;). Just something extra someone can do if they feel the need. In our Webapps, using it will certainly be the exception. But is nice to know I can.
Yes, most certainly - as I am using it right now.
As the most lazy of all bass-todds on this site - I will look forward to (copy/paste) the submissions from the wonderful group of dev's that create the extended functionality provided by BANano for my ABM apps. From that, I can learn without giving myself (another) brain tumor! HA!
Thanks
 

Cableguy

Expert
Licensed User
Longtime User
For me the ABM source codes that are bundled with the framework, are like "Mikado"... I poke around, take a bit here and there, and hope I haven't "break" the source!


BTW.... its already "somewhere next week "!!!
 

Cableguy

Expert
Licensed User
Longtime User
Has promised, I've started breaking this already!

On the introduction we see:
Sub AppStart (Form1 As Form, Args() As String) ' you can change some output params here BANano.Initialize("BANano", "Hover",7) '<--------------------- the name of our lib BANano.JAVASCRIPT_NAME = "hover.js" '<------------------- the name of the generated JavaScript file ' start the build #if release BANano.BuildAsB4XlibForABM("1.0") '<----------------------- ExitApplication #else BANano.Build(File.DirApp) #end if End Sub ' HERE STARTS YOUR APP Sub BANano_Ready() End Sub

But it seems the BuildAsB4XlibForABM declaration has changed....

1612709760948.png


I haven't yet compiled to lib, so I was wondering, what would be a " in most cases" value to the ABMStaticFilesFolder in this scenario?
 

alwaysbusy

Expert
Licensed User
Longtime User
I've started breaking this already!
I hardly call this broken :) just an oversight in the first post. I've updated it. This is a change I've made so, if this param is not empty, it will immediately unzip all assets of the .b4xlib to the correct folders in your ABM project. This way, you can 'update' the Javascript code while running your ABM project.

so I was wondering, what would be a " in most cases" value to the ABMStaticFilesFolder in this scenario
I think if you scroll the popup one line down, there should be an example:

1612710753501.png


This one really depends on where the www folder is of your ABM project that is going to use it.

Alwaysbusy
 

Cableguy

Expert
Licensed User
Longtime User
So, if I just let it empty (double quoted) then
the ".unzipassets" call will unzips them to the correct folder, right?

BTW, I knew I didn't break it... just yet ;)
 

alwaysbusy

Expert
Licensed User
Longtime User
the ".unzipassets" call will unzips them to the correct folder, right?
Correct. The other option is just handy if you are writing the library AND you have access to the ABM app that will use it. I for example used this option when I was writing a multi select box in BANano for an ABM project I had. When something did not work correctly, I just had the ABMBANanoLibrary open in another B4J instance, made the correction, rebuilded it and just by pressing CTRL+F5 in the browser, the 'new' javascript files were loaded in my ABM project and I could continue to test it.

Alwaysbusy
 

Cableguy

Expert
Licensed User
Longtime User
I for example used this option when I was writing a multi select box in BANano for an ABM project I had.

Alwaysbusy

Wait! You mean... creating custom views in banano and then using them in ABMATERIAL ????
 

Cableguy

Expert
Licensed User
Longtime User
Wait, wait, wait!!!!!

Even the graphical part? Like we do in B4X custom Views? we can create complete complex "controls", Graphic+Logic in BaNano and use them in ABMaterial, or just the Logic part?

If its the "complete package" an example is in order!!!
 

alwaysbusy

Expert
Licensed User
Longtime User
Hold your horses! It is possible, but you will have to write the HTML and CSS too. And BANano will help you with the JavaScript part. It is then just matter of 'attaching' it to an ABMCell using BANano code. I will try to extract the relevant code from my multi select later. Plans were to add it in the download, but I was kind of 'forced' ;) to do an early release so it did not make it. This is part from a large ABM project with client proprietary code so I will have to see how much I can extract. It will probably not be a out-of-the-box working thing, but I'll include and explain all important bits.

BUT: You will NEED to learn BANano to understand it. I will not go into basic BANano stuff. So I hope you already dived into that else it may make very little sense to you. This is a good start to understand the basics: https://www.b4x.com/android/forum/threads/banano-for-dummies-by-example.108722/#content

It looks something like this in the clients WebApp (only the bottom part is BANano, but everything 'talks' with each other):

1612723102598.png


Alwaysbusy
 
Top