B4J Library [BANano] Website/App/WPA library with Abstract Designer support

Discussion in 'B4J Libraries & Classes' started by alwaysbusy, Nov 26, 2018.

  1. alwaysbusy

    alwaysbusy Expert Licensed User

    [​IMG]

    INTRO


    BANano is a new B4J library to create one-page websites/webapps with (offline) Progressive Web App support. Unlike its big brother ABMaterial, BANano does not rely on any particular framework like Materialize CSS. You will have to write that part yourself, but on the other hand, you have the choice to pick which one.

    Why a second framework? Well, from the start ABMaterial was build with a back server in mind. B4J has great support to setup a very powerful jServer to handle web requests. Which does mean all intelligence is at the server side and you have the full power of B4J to do whatever you want (secure database access, serial communication, cache control etc). With B4JS, some of this intelligence could be transferred to the browser side, but the app still needs internet/intranet access so this is as far as it could go.

    BANano is a different animal. It can use a Service Worker to 'install' the web app in the browser, so it can also work when the user is offline. While ABMaterial builds the page from the server side, BANano builds it from the browser side. This means EVERYTHING you write in B4J is transpiled to Javascript, HTML and CSS.

    But with great power comes great responsibility! Unlike ABMaterial, knowledge of HTML, CSS and to some extend Javascript is needed to build BANano apps. It makes excellent use of B4X's SmartStrings to create the HTML part of the app. BANano gives you a set of tools to write your own wrapper around any framework (MiniCSS, Skeleton, Spectre, Bootstrap, ...), which then can be easily used to quickly build webapps/websites.

    Note: Because Progressive Web Apps are a new technology, not all browsers do support it (e.g. on iOS, the chrome browser does not support it yet)

    OVERVIEW

    A quick overview to show the different uses of both frameworks:

    [​IMG]
    So both frameworks have their specific target, both for the programmer and the app you want to make.

    BANano is written from scratch, so although it is similar to B4JS, both support different things. B4JS is build on jQuery, while BANano uses Umbrella JS (a lighter form of jQuery, about 50x smaller) and Mustache to build the HTML.

    BANano does also support some different B4J than B4JS: e.g. things like CreateMap, better support for SmartStrings etc.

    Abstract Designer support in v2.0+

    [​IMG]

    DEMO

    Visit https://banano.alwaysbusy.org

    This is just a 'test it all' demo. Some stuff you can see:

    After loading the page, open the Chrome Console. It will show the output of a lot of aspects of BANano. Notable are the 'mycoun't logs: this increments as a browser database is used and with every refresh it inserts a record in the database.

    You can go offline, close the browser and go back to it. In the 'network tab' you'll see some red lines (e.g. for some favicons), but this is normal as it is a bug in Chrome.

    LICENSE

    Cheers,

    Alain
     
    Last edited: Mar 6, 2019
  2. Erel

    Erel Administrator Staff Member Licensed User

    Very impressive. This is a 100% client solution. Are you actually using the B4J compiler?
     
    Beja, B4JExplorer and joulongleu like this.
  3. Mashiane

    Mashiane Expert Licensed User

    Very impressive indeed! I was just starting to wonder how I will make my ABM apps work offline to work underground for some mining apps I'm working on. So I can just create a wrapper for myself for Material CSS and then use it with this and boom! Done! Perfect and I will have a seamless user experience.

    Thanks a million for this! Viva!
     
    B4JExplorer and joulongleu like this.
  4. alwaysbusy

    alwaysbusy Expert Licensed User

    Partially. To configure the app and to run the BANano library and Build the app. At that point, the library takes over and transpiles the B4X source code to JavaScript.

    Unlike ABM, it uses a more 'classic' way of B4X programming (e.g. one copies the assets to the 'Files' in B4J, and they are moved to the final web structure by the library).
     
    Last edited: Feb 6, 2019
  5. alwaysbusy

    alwaysbusy Expert Licensed User

    Browse through the demo code get a first glance on how things work in BANano.

    Don't ask questions here, but maybe use [BANano] in your subject if you have questions (or if you made a framework wrap!).
    All methods are documented in the library. Unfortunately, it is getting to big to put in a forum post

    Important note on naming conventions in BANano (read it!)
    https://www.b4x.com/android/forum/threads/banano-nomenclature-of-banano.103675/#post-649935

    Not supported B4J Core keywords (or replacements):
    Code:
    CallsubCallsub2Callsub, Callsubdelayed, Callsubdelayed2, Callsubdelayed3: 'Use BANano.CallSub instead
    Charstostring
    Density
    Diptocurrent
    ExitApplication
    Exitapplication2
    File
    Getenvironmentvariable
    Getsystemproperty
    Isdevtool
    Regex'Use BANAnoRegEx instead
    Setsystemproperty
    Smartstringformatter
    Stopmessageloop
    Startmessageloop
    Wait'Use BANAno.WaitFor instead)
    #if#end: 'only CSS, CSSSmart, PHP, PHPSmart JavaScript, JavascriptSmart accepted
    BANanoLibraries (wrapped libraries):

    - Leaflet by @Kiffi: https://www.b4x.com/android/forum/threads/banano-leaflet-wrapper.100389
    - SweetAlert 2 by Alain Bailleul: included in the zip
    - Skeleton CSS by Alain Bailleul: included in the zip
    - Create desktop applications (Windows, Linux, MacOS) with BANano and NW.js by @Kiffi: https://www.b4x.com/android/forum/threads/banano-nw-js-wrapper.102371/
    - Kendo UI by @Kiffi: https://www.b4x.com/android/forum/threads/banano-kendo-ui-core-wrapper.103257/
    - MediaRecorder by Alain Bailleul: included in the zip
    - ChartKick by @Mashiane: https://www.b4x.com/android/forum/t...ts-with-1-line-of-code-using-uoecharts.104942

    BANano tutorials:

    1. Abstract Designer: https://www.b4x.com/android/forum/threads/banano-v2-1-b4j-abstract-designer.101531/
    2. Abstract Designer & making libraries: https://www.b4x.com/android/forum/threads/banano-v2-2-b4j-abstract-designer.101544/
    3. Talking with Javascript: https://www.b4x.com/android/forum/threads/banano-bananoobject-talks-with-javascript.100385/
    4. Events: https://www.b4x.com/android/forum/threads/banano-events.100041/#content
    5. BANano SQL: https://www.b4x.com/android/forum/threads/banano-working-with-bananosql.99795/#content
    6. Inline php -> server code: https://www.b4x.com/android/forum/threads/banano-inline-php-server-code.101224/#content
    7. Authentication to a B4J server (REST API): https://www.b4x.com/android/forum/threads/banano-inline-php-server-code.101224/#content
    8. TIP: running a test Web Server: https://www.b4x.com/android/forum/threads/banano-tip-running-a-test-server.100180/
    9. Resumable Sub (sort of): https://www.b4x.com/android/forum/threads/banano-resumeable-sub-sort-of.100500/#content
    10. Ajax calls: https://www.b4x.com/android/forum/threads/banano-ajax-calls.100009/#content
    11. Working with Promises: https://www.b4x.com/android/forum/threads/banano-working-with-promises.102413/#post-642677
    12. Communication between B4J and BANano: https://www.b4x.com/android/forum/t...-communication-between-b4j-and-banano.102908/
    13. Media Recorder: https://www.b4x.com/android/forum/threads/banano-capture-webcam-microphone-screen.104504/

    BANano tools:

    BANanoPostProcessor by @Kiffi:alternative js compressor using node.js https://www.b4x.com/android/forum/threads/banano-bananopostprocessor.104812/

    Alwaysbusy
     
    Last edited: May 9, 2019
  6. Don Oso

    Don Oso Member Licensed User

    Just one word ..... WOW !!

    Thanks Alain !
     
  7. alwaysbusy

    alwaysbusy Expert Licensed User

    Some tips to make your life easier. Unlike ABM, BANano is case sensitive in a lot of ways (e.g. for html id's, css classes, events, ...)

    So if you plan to build a wrapper for a CSS/JS framework (like MiniCSS, Bootstrap, Materialize CSS), take the time to make sure everything is always lowercase. When you call one of your methods use any case you want.

    An example for the MiniCSS framework:
    Code:
    ' TIP: you make it yourself a lot easier if you LowerCase all the IDs!
    Sub Process_Globals
       
    Dim BANano As BANano 'ignore
    End Sub

    public Sub AddRows(RowIDPrefix As String, Rows As Int, classes As StringAs List
       RowIDPrefix = RowIDPrefix.ToLowerCase
       
    Dim l As List
       l.Initialize
       
    For i = 1 To Rows
           
    Dim myRow As GridRow
           myRow.Initialize(RowIDPrefix & i, classes)
           l.Add(myRow)
       
    Next
       
    Return l
    End Sub

    public Sub AddColumns(CellIDPrefix As String, theRow As GridRow, Cells As Int, classes As String)
       CellIDPrefix = CellIDPrefix.ToLowerCase
       
    For i = 1 To Cells
           
    Dim myCol As GridColumn
           myCol.Initialize(theRow.ID & CellIDPrefix & i, classes)
           theRow.cols.Add(myCol)
       
    Next
    End Sub

    public Sub BuildGrid(TargetID As String, Rows As List)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    Dim s As StringBuilder
       s.Initialize
       s.Append(
    $"<div class="container">"$)
       
    For i = 0 To Rows.Size - 1
           
    Dim myRow As GridRow = Rows.Get(i)
           s.Append(
    $"<div id="${myRow.ID}" class="${myRow.Classes}">"$)
           
    For j = 0 To myRow.Cols.Size - 1
               
    Dim myCol As GridColumn = myRow.Cols.Get(j)
               s.Append(
    $"<div id="${myCol.ID}" class="${myCol.Classes}"></div>"$)
           
    Next
           s.Append(
    $"</div>"$)
       
    Next
       s.Append(
    $"</div>"$)
       BANano.GetElement(TargetID).setHTML(s.toString)
    End Sub

    public Sub Content(TargetID As StringID As String, Text As String)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       BANano.GetElement(TargetID).RenderAppend( 
    $"<p id="${ID}">"$ & Text & "</p>","")
    End Sub

    public Sub Header(TargetID As StringID As String, Level As Int, Text As String)
       TargetID =  
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       BANano.GetElement(TargetID).RenderAppend(
    $"<h${Level} id="${ID}">${Text}</h${Level}>"$,"")
    End Sub

    Public Sub Button(TargetID As StringID As String, Text As String, ColorVariant As String, EventHandler As Object)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       
    Dim tgt As BANanoElement = BANano.GetElement(TargetID)
       
    Dim btn() as BANanoElement = tgt.RenderAppend($"<button id="${ID}" class="${ColorVariant}">${Text}</button>"$,"").Children("")
       
    ' defining events is very simple. Note that it has to be run AFTER adding it to the HTML DOM!
       btn(0).HandleEvents("mousedown, touchstart", EventHandler, ID & "_clicked")
    End Sub

    public Sub Image(TargetID As StringID As String, Src As String, AltText As String)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       BANano.GetElement(TargetID).RenderAppend(
    $"<img id="${ID}" src="${Src}" alt="${AltText}"/>"$"")
    End Sub

    public Sub List(TargetID As StringID As String, Ordered As Boolean, Items As List, EventHandler As Object)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       
    Dim s As StringBuilder
       s.Initialize
       
    If Ordered Then
           s.Append(
    $"<ol id="${ID}">"$)
       
    Else
           s.Append(
    $"<ul id="${ID}">"$)
       
    End If
       
    For i = 0 To Items.Size - 1
           
    Dim item As String = Items.Get(i)
           s.Append(
    $"<li id="${ID}_${(i+1)}" class="${ID}_event">${item}</li>"$)
       
    Next
       
    If Ordered Then
           s.Append(
    "</ol>")
       
    Else
           s.Append(
    "</ul>")
       
    End If
       BANano.GetElement(TargetID).RenderAppend(s.ToString, 
    "")
       
    ' defining events is very simple. Note that it has to be run AFTER adding it to the HTML DOM!
       ' we only have to define it on our class (ID & "_event") once because we can retrieve wich one from the event later
       BANano.GetElement($".${ID}_event"$).HandleEvents("mousedown, touchstart", EventHandler, ID & "_clicked")
    End Sub

    public Sub Code(TargetID As StringID As String, CodeText As String)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       BANano.GetElement(TargetID).RenderAppend( 
    $"<pre id="${ID}">"$ & CodeText & "</pre>","")
    End Sub

    public Sub BlockQuote(TargetID As StringID As String, Text As String, cite As String)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       BANano.GetElement(TargetID).RenderAppend( 
    $"<blockquote id="${ID}" cite=${cite}>"$ & Text & "</blockquote>","")
    End Sub

    public Sub Card(TargetID As StringID As String, Rows As List, Classes As String)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       BANano.GetElement(TargetID).RenderAppend(
    $"<div id="${ID}" class="${Classes}"></div>"$"")
       BuildGrid(
    ID, Rows)
    End Sub
    Also a note on BANano.GetElement():

    The target parameter can be a html tag (no prefix), a tags id (has prefix #) or a css class (has prefix .). So the result of your call may affect multiple html tags at once!
    This can be very handy (e.g. in the List() in the above class where we are using the CSS class) where instead of making an event per list item, you can catch them all at once.

    But, if not carefully used, it can give unexpected results!

    Alain
     
    Last edited: Dec 3, 2018
  8. Roberto P.

    Roberto P. Well-Known Member Licensed User

    I bielive that this new framwework will have many possibilities.

    I think the following developments:

    - integrated with PhoneGap, for created hybrid apps
    - Sync support with server
    - layout design with B4j designer

    I propose to support all Alain
    thank
     
    B4JExplorer and joulongleu like this.
  9. Kiffi

    Kiffi Active Member Licensed User

    That looks very promising!

    [​IMG]

    Greetings ... Peter
     
  10. alwaysbusy

    alwaysbusy Expert Licensed User

    A new version 1.02 is uploaded thanks to some remarks/tests from @Kiffi:

    1. There was a mistake in the example button code (that appeared to work but the event was on the wrong element):

    Correct code (also updated in post #7 and the demo):
    Code:
    Public Sub Button(TargetID As StringID As String, Text As String, ColorVariant As String, EventHandler As Object)
       TargetID = 
    "#" & TargetID.ToLowerCase
       
    ID = ID.ToLowerCase
       
    Dim tgt As BANanoElement = BANano.GetElement(TargetID)
       
    Dim btn() as BANanoElement = tgt.RenderAppend($"<button id="${ID}" class="${ColorVariant}">${Text}</button>"$,"").Children("")
       
    ' defining events is very simple. Note that it has to be run AFTER adding it to the HTML DOM!
       btn(0).HandleEvents("mousedown, touchstart", EventHandler, ID & "_clicked")
    End Sub
    2. Improved support for Arrays to make the above possible.

    3. Fix for methods that have a return value. The last variable type in the method was handled like the return value.
    Note: a method that has a return value must be put in a variable first. May be extended in a later update.

    Example:

    does work:
    Code:
    dim myTarget as BANanoElement = GetElement("myid")
    mytarget.addClass(
    "myclass")

    Sub GetElement(ID As StringAs BANanoElement
       
    ID = ID.ToLowerCase
       
    Return BANano.GetElement(ID)
    End Sub
    does NOT work:
    Code:
    GetElement("myid").addClass("myclass")

    Sub GetElement(ID As StringAs BANanoElement
       
    ID = ID.ToLowerCase
       
    Return BANano.GetElement(ID)
    End Sub
    4. Support for inline Javascript within a method:

    Code:
    Sub BANano_Ready()
       
        
    #If JAVASCRIPT
            alert("!");
        
    #End If  
       
    End Sub
    5. Added also BANano.CheckInternetConnectionWait and BANano.CallAjaxWait

    Example usage:
    Code:
    If BANano.CheckInternetConnectionWait Then
           
    Dim res As String = BANano.CallAjaxWait("https://reqres.in/api/users?page=1","GET","jsonp""",""""False)
           Shared.Ajaxresult = res
           MiniCSS.Content(
    "#r4c1""contajax", res)
    Else
           MiniCSS.Content(
    "#r4c1""contajax""Cannot make Ajax call because you are not connected to the internet, but here is the last result:<br>" & Shared.Ajaxresult)
    End If
    6. Several other fixes, mostly typos in the javascript.

    Alain
     
  11. Kiffi

    Kiffi Active Member Licensed User

    Very cool! Thanks a lot, Alain! [​IMG]

    Greetings ... Peter
     
    joulongleu likes this.
  12. Harris

    Harris Well-Known Member Licensed User

    Why named BANano and not ABNano? Just curious, as I am sure you have your reasons... (typo? - BA(_ ) looks in keeping...)

    This is where my trousers fall down - exposing what I don't know (or could hope to retain all the knowledge) of these other requirements.
    However, like while learning ABM - it was daunting at first but it quickly became obvious (helped with B4J coding as well). I always rely on [you / and] the community to produce examples that help me learn and utilize.

    Browser based would help reduce the need for 3 apps (desktop, Android, iOS) and the toil involved.

    One thing many have noticed: your creative / intellectual talents never stop! I partially attribute (blame) Erel for this - since he inspires us all to excel.
     
  13. alwaysbusy

    alwaysbusy Expert Licensed User

    No hidden messages in this one :D It is small (compared to ABM) so Nano, and instead of Alain Bailleul I used Bailleul Alain, et voila, BANano it was :)

    As this is more like a pet project compared to the serious beast ABM, it could have a more fluffier name.

    But only up to a point! Once you need OS queries, you're stuck (it is not PhoneGap). You can give your users a lot more using the other 'native' B4X tools.

    Some days, it is more of a curse... ;)
     
  14. alwaysbusy

    alwaysbusy Expert Licensed User

  15. alwaysbusy

    alwaysbusy Expert Licensed User

    Uploaded version 1.04

    CHANGES:

    1. Important: The syntax of CallAjax and CallAjaxWait has changed to allow headers! (user and password params are gone as you have to pass them as header anyway)

    2. Fixes in CallAjax/Wait (mainly in the returned Json part)

    3. Fix in BANanoJSONGenerator to allow initialize to accept a Map

    4. Change in SetStyle: now only allows a string as parameter, so in case of a JSONGenerator, you now have to first ToString() it. There was no clear way to determin if it was a native JSON object or a JSON string.

    Code:
    Dim JSONGenerator As BANanoJSONGenerator
    Dim style As Map
    style.Initialize
    style.Put(
    "background""green")
    style.Put(
    "border-radius""5px")
    JSONGenerator.Initialize(style)
       
    row2c1.SetStyle(
    JSONGenerator.ToString)
    5. Object is now an allowed Type.

    6. Several other bug fixes

    Download: https://www.b4x.com/android/forum/threads/banano-progressive-web-app-library.99740/#post-627764
     
  16. alwaysbusy

    alwaysbusy Expert Licensed User

  17. alwaysbusy

    alwaysbusy Expert Licensed User

    Uploaded version 1.11: download https://www.b4x.com/android/forum/threads/banano-progressive-web-app-library.99740/#post-627764

    CHANGES:

    1. New feature to make BANano libraries (see tutorial: https://www.b4x.com/android/forum/threads/banano-creating-libraries.100412)
    2. Fix where comments of inline javascript were not ignored
    3. Fix for BANanoObject GetField() and SetField() using a variable instead of a string
    4. Warning if you use a reseved word. This can cause trouble when BANano is transpiling your code generating bad javascript.
    5. Attempt to have some kind of B4J WaitFor system using promises. (see tutorial: https://www.b4x.com/android/forum/threads/banano-resumeable-sub-sort-of.100500/)
    6. Other small bug fixes
     
    Last edited: Dec 17, 2018
  18. alwaysbusy

    alwaysbusy Expert Licensed User

  19. alwaysbusy

    alwaysbusy Expert Licensed User

    XbNnX_507, Alexander Stolte and Erel like this.
  20. alwaysbusy

    alwaysbusy Expert Licensed User

    BANano v2.07: download https://www.b4x.com/android/forum/threads/banano-progressive-web-app-library.99740/#post-627764

    CHANGES:

    1. NEW Abstract Design system using your own Custom Views: tutorial https://www.b4x.com/android/forum/threads/banano-b4j-abstract-designer-v2-part-1.101531/
    2. The signature of BuildAsLibrary has changed: it doesn't need parameters anymore and generates the files in the Additional Libraries folder immidiately.
    3. Support for the Const keyword
    4. You can now use inline CSS with the #if CSS tag. This can be useful if you want to quickly have a small CSS class that you want to use.
    Bacause this CSS is saved in the HTML file, it is strongly advised to create a sperate CSS file if this becomes to big.

    Example
    Code:
    ...
    #if CSS
    .tablehover {
       background-color: #F0F0F0;
    }
    #End If

    #Region Internal Events
    public Sub RowMouseEnter(event As BANanoEvent)
       
    Dim row As BANanoElement
       row.Initialize(
    "#" & event.ID)
       row.AddClass(
    "tablehover")
    End Sub

    public Sub RowMouseLeave(event As BANanoEvent)
       
    Dim row As BANanoElement
       row.Initialize(
    "#" & event.ID)
       row.RemoveClass(
    "tablehover")
    End Sub
    #End Region
    5. The layout properties support boolean, int and float. Colors are translated to a string but as rgba(255,2255,255,1.0).

    6. I've completed the Skeleton CSS library. Just the basics, but can be extended by whoever feels like it.

    7. Support for getters and setters (using the lowercased prefixes set/get)

    8. Support for Smart Formatting. Just wrap your text into a BANano.SF()

    Supported Smart formatting Tags:

    {B}{/B}: Bold
    {I}{/I}: Italic
    {U}{/U}: Underline
    {SUB}{/SUB}: Subscript
    {SUP}{/SUP}: Superscript
    {BR}: Line break
    {WBR}: Word break opportunity
    {NBSP}: Non breakable space
    {AL}http://...{AT}text{/AL}: Link, opening a new tab
    {AS}http://...{AT}text{/AS}: Link, not opening a new tab
    {C:#RRGGBB}{/C}: Color
    {ST:styles}{/ST}: Add specific styles e.g. {ST:font-size:0.9rem;color:#2B485C}My text in font-size 0.9rem{/ST}
    {IC:#RRGGBB}{/IC}: Icons (if the correct .css or font is loaded) e.g. {IC:#FFFFFF}fa fa-refresh{/IC}

    Example:
    Code:
    mElement.SetHTML(BANano.SF("I'm {C:#FF0000}{U}row " & (i+1) & "{/U}{/C} of a multi layout!"))
    9. Bug Fixes in the transpiler

    Alwaysbusy
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice