B4J Tutorial BANano for Dummies by Example

Ola

BANAno4Dummies

TERMS OF ENGAGEMENT: Please DO NOT POST QUESTIONS ON THIS THREAD.

I AM ONLY DOING THIS DUE TO THE NUMEROUS REQUESTS I HAVE RECEIVED TO DO IT. I AM NOT A BANANO EXPERT AND STILL A DUMMY MYSELF, EXPECT SPELLING ERRORS (I SPEAK XHOSA), EXPECT CODE ERRORS, BE CONSIDERATE, BE KIND, FOR ANYTHING ELSE, USE SEARCH, IT WORKS! LOL


What is BANano?

BANano is a once in lifetime B4J Library created by Alain Bailleul to create one-page websites/webapps with (offline) Progressive Web App support. It transpiles B4J source code to Javascript/HTML/CSS. It can be used to make Websites and WebApps, even Progressive Web Apps (PWA).It does not depend on jQuery but generates pure Vanilla Javascript. It does not rely on any javascript/css framework, so you can use whatever one you prefer.You do have to write the wrapper for the framework you want to use yourself.

The generated HTML, CSS and JavaScript files do not need to run from a VPN! In fact, you can just run the app by opening the html file in any browser.Because they are PWA's, they also work after the user goes off-line. A new feature for JavaScript is encryption so to protect your source code!

For communication with the outside world, Ajax/PHP calls And MQTT are build-in.
For local storage you can use Cookies, LocalStorage, SessionStorage And IndexedDB (using the build-in BANAnoSQL object).

The BANanoJSONParser And BANanoJSONGenerator can be used to read and write Json. They are the equivalent of the normal JSONParser And JSONGenerator from B4X.

To be able to develop websites/webapps with BANAno, you need experience in B4J, HTML, CSS and Javascript

Download BANano 3.09+
View Online Help.

Sourced from Alain's thread & online help.

NB: These examples will be based on my experience using BANano.
 

Attachments

  • DummiesLikeMe01.zip
    1.2 KB · Views: 1,366
Last edited:

Mashiane

Expert
Licensed User
Longtime User
The Structure of a BANano Project

B4X:
Sub Process_Globals
    Private BANano As BANano  'ignore
    Private fx As JFX
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    'initialize banano object with event, appname (must not have space) and version
    BANano.Initialize("BANano", "MyApp",DateTime.now)
    'the name of the html file
    BANano.HTML_NAME = "index.html"
    'the title of the page
    BANano.Header.Title = "MyApp"
    'do not use service workers for PWA
    BANano.TranspilerOptions.UseServiceWorker = False
    'transpile b4j code to html, css and javascript and store output in File.DirApp
    'the webiste/website will be loaded in \Objects\MyApp where you saved your project
    BANano.Build(File.dirApp)
    'open the compiled index file
    Dim URL As String = File.GetUri(File.Combine(File.dirapp,"MyApp"),"index.html")
    fx.ShowExternalDocument(URL)
    ExitApplication
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub BANano_Ready
    '****javascript****
    'var body = document.getElementById("body");
    'var.innerHTML = 'Hello Alain Bailleul!';
    
    '****jquery****
    'var body = $("#body");
    'body.append("Hello Alain Bailleul!");
    
    '****banano****
    Dim body As BANanoElement = BANano.GetElement("#body")
    body.Append("Hello Alain Bailleul!")
End Sub

When you run this code (F5), the default browser will be opened and this will appear!

helloalain.jpg


For any BANano App, the sub routine AppStart and BANano_Ready is required!

We activated the BANAno library by initializing it with an event name 'BANano', this expectes BANano_Ready. I assume _Ready indicated that the page has loaded

We then set some properties for the app. For more details on the BANano object properties, see the online BANano help.

After everything is done, we need to build our page so that it has content. BANano creates a blank page when it runs and that's where you need to create HTML elements

On the code example we show how the code can be written in javascript and jquery and how to do the same thing in BANano.

The above example just used normal HTML5 without any CSS. One can add CSS files in their project as depicted below within the AppStart subroutine before .Build().

B4X:
BANano.Header.AddCSSFile("mini.min.css")

Things to remember

1: All code that will be writen in your Code and Class Modules will be transpiled to HTML, Javascript and CSS.
2: The starting point for your app executing is ALWAYS BANano_Ready.
3: You write your code the normal way you have been doing using B4J.
4: By default, your code will be saved in app.js file on the scripts folder.
5: Anything you add on the Files tab will be saved on the ./assets folder of your app.
6: Any css files added on the files tab will be saved on the ./styles folder.
7: Any js files added on the files tab will be saved on the ./scripts folder.

Rule #1. Have fun!
Rule #2. Remember Rule #1

Ta!
 

Mashiane

Expert
Licensed User
Longtime User
Lesson 2: Creating Multiple Pages

In this lesson, we look at how do we create multiple pages in our single page app. We will use buttons to navigate the pages which will have click events.

Creating multiple pages involves the process of clearing the contents of the body in our page everytime a new page needs to be rendered.

DummiesLikeMe02.gif


To do this we use code modules. Project > Add New > Code Module.

We name one module page1 and the other page2 and in each we have a .Show method. This time around we move our code to generate page content from BANano_Ready to the page that we want to show initialy, in this case, page 1

In Main.BANano_Ready, we call the page we want to show.

B4X:
Sub BANano_Ready
    'show the initial page we want to see
    page1.Show
End Sub

When page1.Show is executed, it needs to build the content of that page. This happens in real-time.

Code for page1.codemodule

B4X:
'Static code module
Sub Process_Globals
    Private BANano As BANano  'ignore
End Sub

Sub Show
    'get the body element of the page
    Dim body As BANanoElement = BANano.GetElement("#body")
    'clear the body
    body.Empty
    'add the contents
    body.Append("<h1>Hello there, I am page 1. Click the button to go to page 2.</h1>").Append("<br/>")
    'add the button
    Dim btn1 As BANanoElement = body.Append($"<button id="btn1">Page 2</button>"$).Get("#btn1")
    'add a click event to the button
    btn1.HandleEvents("click", Me, "btn1_click")
End Sub

Sub btn1_click(e As BANanoEvent)
    page2.show
End Sub

Here we define a global BANano variable in case we will use it in our page. Previously we got the body element and then appended to it. This time around, whilst we will append to the body, we will create an own independent element named 'btn1'. We create it individually because we want to assign a 'click' event to it.

We added a H1 element to the page that indicates which page we are in. We then defined btn1 as bananoelement, the contents of this element will be residing on the body of the page, thus, body.append. To assign the HTML element defined within <button></button>, we call the .Get(?) element.

Because we want to trap the 'click' event of the button, we attach an event to the button. The event is click, this will call the btn1_click method which resides on this code module i.e. Me. We have used HandleEvents, this cancels out preventDefault.

There is a tutorial here about events written by alwaysbusy.

btn1_click receives an event object when called, thus it being passed. When btn1_click is fired, we want page2 to be shown thus calling page2.show. In page 2 we want to clear the contents of the body and show the contents of page 2.

The code for the second module is almost identical.

Debugging & Checking out your transpiled code.

At times, you might run through error in our app, you can run it in debug mode so that you can try and identify errors. With this you have the ability of seeing the transpiled code of your app.

Open app.js after running your app in debug mode, you will see similar...

B4X:
// =========================== page1  ===========================
function banano_dummies_page1() {
var _B;
// [6] Sub Show
this.show=function() {
if (_B==null) _B=this;
var _body,_btn1;
// [8]  Dim body As BANanoElement = BANano.GetElement( {1} )
_body=u("#body");
// [10]  body.Empty
_body.empty();
// [12]  body.Append( {2} ).Append( {3} )
_body.append("<h1>Hello there, I am page 1. Click the button to go to page 2.</h1>").append("<br/>");
// [14]  Dim btn1 As BANanoElement = body.Append( {0} ).Get( {4} )
_btn1=_body.append("<button id=\"btn1\">Page 2</button>").find("#btn1").bananofirst();
// [16]  btn1.HandleEvents( {5} , Me, {6} )
_btn1.handle("click", function(event) {if (typeof _B["btn1_click"]==="function") {return _B["btn1_click"](event,_B)}});
// End Sub
};

// [19] Sub btn1_click(e As BANanoEvent)
this.btn1_click=function(_e) {
if (_B==null) _B=this;
// [20]  page2.show
_banano_dummies_page2.show();
// End Sub
};

Where is banano_dummies_page1 coming from? This is the BANano library, the b4j project file name is 'dummies', the module we added was page1. BANAno is case sensitive and thus most things should be lower case.

Running the BANano code this way (debug), enables you to see the representation of the code you wrote in b4j and how it was transpiled to javascript. BANano internally uses the UmbrellaJS library (an alternative to JQuery), thus most of its functions are close to JQuery. To regress a little, there has been drives to leave JQuery by most, in some instances due to security issues or otherwise, for example, http://youmightnotneedjquery.com

Running the same code in Release mode gives different code as its now encrypted, for example _body is now _B1.

B4X:
function banano_dummies_page1() {
    var _B;
    this.show = function () {
        if (_B == null) _B = this;
        var _B1, _B4;
        _B1 = u("#body");
        _B1.empty();
        _B1.append("<h1>Hello there, I am page 1. Click the button to go to page 2.</h1>").append("<br/>");
        _B4 = _B1.append("<button id=\"btn1\">Page 2</button>").find("#btn1").bananofirst();
        _B4.handle("click", function (event) {
            if (typeof _B["btn1_click"] === "function") {
                return _B["btn1_click"](event, _B)
            }
        });
    };
    this.btn1_click = function (_e) {
        if (_B == null) _B = this;
        _banano_dummies_page2.show();
    };
}

Things to remember:

B4X:
Dim btn1 As BANanoElement = body.Append($"<button id="btn1">Page 2</button>"$).Get("#btn1")

We created a button element with a unique identifier "btn1".Each time you create a HTML element, you can give it an identifier. The identifier should be unique and it should ALWAYS be in lowercase.

The .Get("#btn1") at the end is the same as

B4X:
Dim btn1 As BANanoElement = BANano.GetElement("#btn1")

In JQuery, this could have been written like..

B4X:
var btn1 = $("#btn1");

In JavaScript, this could have been written like...

B4X:
var btn1 = document.getElementById("btn1");

All of these are using the unique identifier for the HTML element, btn1

BANAno transpiles the code to javascript based on Umbrella (Unencryped Debug Mode)

B4X:
var _btn1;
_btn1 = u("#btn1)

Please note the declaration on the left is just the variable name, i just decided to call it btn1, you can use any variable name.

You can also attach events to elements and there are various ways to do this as per link provided above.

Ta!
 

Attachments

  • DummiesLikeMe02.zip
    2.3 KB · Views: 799
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 3: Creating websites

Creating websites is done by writing documents (marking) that a computer browser can understand. This language is called HTML (HyperText Markup Language) and it uses some types of tools (tags). Each time you visit a site, the browser performs some kind of download of this file and displays it. The browser interprets the HTML and then displays the content as a web page.

This document is just a long text of string and it also contains information about the content. For example a picture gets displayed at a particular location and some text is italic or bold. This information about the content of the page is not usually visible to the person seeing the web page.

All of this information, called markup tells the browser what each piece of content is, where they start and where they end and what purpose they serve.

The building block for HTML is a tool called a tag. Some have a opening and closing tags and some dont (to indicate the start and end of an element).

As an example, this is just a simple tag..

B4X:
<header>Your header content goes here</header>

One can also make a tag to be 'more useful' and or 'more powerful' by giving it attributes. Let's look at another example.

B4X:
<a href="http://www.google.com/">Google: a handy search engine</a>

In this example, href is an attribute that tells the <a> tag where to link to. An element is nothing more than text wrapped between a pair of tags. Angle brackets, the < and > characters, delimit the beginning and end of a tag.

Let's look at XML,which is just another language to code information.

B4X:
<title>Where the Streets Have No Name</title>
<artist>U2</artist>
<album>The Joshua Tree</album>
<released>1987</released>

We have a song that we give it a title and then tag it with an opening and closing tag title. The song has an artist which can belong to an album and then released in 1987.

As you noted, these are details of a song. What if you had many songs? You can take all this information and create an element called song.

B4X:
<song>
<title>Where the Streets Have No Name</title>
<artist>U2</artist>
<album>The Joshua Tree</album>
<released>1987</released>
</song>

The song element here has items inside (it encloses other elements), these are called children and itself is the parent element.

Now that we have a song, its easier to add other songs to our list and expand our document. Adding another song we can have..

B4X:
<song>
<title>Hungry Like the Wolf</title>
<artist>Duran Duran</artist>
<album>Rio</album>
<released>1982</released>
</song>
<song>
<title>Dream On</title>
<artist>Aerosmith</artist>
<album>Aerosmith</album>
<released>1973</released>
</song>

These songs can belong to a playlist so that we can mix them up. We can do this by enclosing the songs in a playlist element.

B4X:
<playlist>
<song>
<title>Where the Streets Have No Name</title>
<artist>U2</artist>
<album>The Joshua Tree</album>
<released>1987</released>
</song>
<song>
<title>Hungry Like the Wolf</title>
<artist>Duran Duran</artist>
<album>Rio</album>
<released>1982</released>
</song>
<song>
<title>Dream On</title>
<artist>Aerosmith</artist>
<album>Aerosmith</album>
<released>1973</released>
</song>
<playlist>

Using the same structure, one is able to markup various elements with different types of information that can have different structures inside others etc. That large structure becomes what is known as a tree.

To make this work and make sense, more information is needed and this information is stored in attributes and values.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 3: Creating websites... continued...

We add extra content to HTML / XML elements using attributes. These expect an attribute name and attribute value. In our example above for lesson 2, this was the attribute name 'id' and its value it was 'btn1'.

For example, for our playlist, we might indicate when it was created.

B4X:
<playlist created="May 28, 2012">

Alternatively, if you just wanted to indicate the authour, you could have written,

B4X:
<playlist author="johndoe">

To include both attributes...

B4X:
<playlist author="johndoe" created="May 28, 2012">

When does one use attributes?

It’s considered best practice to use attributes and values for metadata (or data about data) and to use elements for everything else. In other words, if it’s data that’s meant to be seen by the end user, it’s best to mark it up in an element. If it’s data that describes some other data in the document, it’s best to use an attribute/value pair.

There are standards that each web page should meet so that there is uniformity and not chaos. This means each page should follow a particular template / format. Usually this is called a boiler-plate and will look like this..

B4X:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
<script src="javascript.js"></script>
</head>
<body>
</body>
</html>

Let's open the generated index.html for our DummiesLikeMe02 project in \objects\MyApp\index.html. I used Visual Studio Code and beautified the file to make it easy to the eye.


dummieslikeme02.jpg


As you can see, this is meeting the standards of a basic HTML page as per boilerplate above. As earlier indicated, BANAno creates all of this including the 'body' tag where the contents of the page will display. In our examples above we did open the app.js file and looked at the debug code that built our app up and injected elements we defined for our page. To add components we used the .Append method of the BANanoElement. A BANanoElement is an HTML Element however one that you can code for BANano and you will have to markup its structure yourself.

If you remember in our example, we did write some mark up for our element and added it to the page with.

B4X:
body.Append("<h1>Hello there, I am page 1. Click the button to go to page 2.</h1>").Append("<br/>")

You can use the B4J's StringBuilder class to markup your elements as the code should just be strings and then inject it to a BANanoElement so that your string becomes.

B4X:
<h1>Hello there, I am page 1. Click the button to go to page 2.</h1>
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 4: Marking up Content

The 'body' tag is where the magic of your website will happen and that is where we need to add content for our website/webapp. For this process we are going to code our way through. This will help when we are moving to creating custom views for our HTML elements. That however is for another day, a very long way ahead.

For the better part of lesson 4, we will look at the various HTML5 elements we can markup.

As an example...

B4X:
<section>
    <h1>HTML5 Overview</h1>
    <p>HTML5 is used to structure documents on the web. It contains a lot of useful elements (Or tags).</p>
    </section>

We have a section element that has 2 children. A heading and a paragraph. Off course we can just enclose this inside $$ and add it to our body content.

We want to add children to the section element, we will therefore define the element and set its identity and then append the children to the section. Setting the section identity is important because we want to get that HTML element and then add content to it.

B4X:
    'append the section to the page
    Dim section As BANanoElement = body.Append($"<section id="sect1"></section>"$).Get("#sect1")
    '
    section.Append($"<h1>HTML5 Overview</h1>"$)
    '
    section.Append($"<p>HTML5 is used to structure documents on the web. It contains a lot of useful elements (Or tags).</p>"$)

If we wanted to create each element, we can do this like this..

B4X:
body.Append($"<section id="sect2"></section>"$)
    Dim section As BANanoElement = body.Get("#sect2")
    '
    Dim h1 As BANanoElement = section.Append($"<h1 id="h1">HTML5 Overview</h1>"$).Get("#h1")
    '
    Dim p As BANanoElement = section.Append($"<p id="p1">HTML5 is used to structure documents on the web. It contains a lot of useful elements (Or tags).</p>"$).Get("#p1")

Over time building your websites in this fashion will prove tedious, thus BANano has a way to help you code faster. This is through creating a custom view for your HTML elements and then using the Abstract Designer. For now, creating custom views for BANano is beyond the scope of this thread.

There is however very detailed threads on how the abstract designer work from the creator.

BANano Abstract Designer 1
BANano Abstract Designer 2

Already there is a Skeleton based library done by the creator of the library that is available on the download that you can use and a perfect example of this is already available on

http://gorgeousapps.com/BANano/

skeleton.png
 

Attachments

  • DummiesLikeMe03.zip
    11.2 KB · Views: 745
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 5: Deciding on a framework to use

There are a variety of web frameworks that you can use to develop websites/webapps with BANano. Initially this was the mini.css framework. This is where the hard part comes, deciding which framework to use. For you to be able to create a framework that you can use going forward, you need to build it for all the HTML elements that you will use.

In the above examples, I showed how to markup elements and feed them to a page. In the attached example here, we built a class module and we used that to build the HTML elements using the original choice of mini.css. Its a very nice and straightforward framework, just like Skeleton.

Remember, we are coding our way through and no custom views or abstract designer is being used. I think I have only managed to create 1 BANano custom view so far and not much versed on how to use it much.

The best way to learn is to explore source code, so the source code for BANanoMiniCSSCode is available.

Let's watch a video.


The demo on this code, follows the same structure of the mini.css documentation website. We use a class to create each element and then feed it to the page. The class just generates the markup and you can use the .Append methods we have showed to add your content to the page.

You can download the BANanoMiniCSSCode from this repo, https://github.com/Mashiane/BANano4Dummies

After you decide on the framework to use, you will have to code it so that you can create your webpages/sites/webapps.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 6: Styling Components

stylingcomponents.png


For this lesson, we create different paragraphs and then apply some styles to them.

B4X:
Dim p11 As BANanoElement = body.Append($"<p id="p1">This is a paragraph</p>"$).Get("#p1")
    p11.SetStyle(BANano.ToJson(CreateMap("color":"red")))
    
    Dim p22 As BANanoElement = body.Append($"<p id="p2">This is a paragraph</p>"$).Get("#p2")
    p22.SetStyle(BANano.ToJson(CreateMap("background-color":"powderblue")))
    
    Dim p33 As BANanoElement = body.Append($"<p id="p3">This is a paragraph</p>"$).Get("#p3")
    p33.SetStyle(BANano.ToJson(CreateMap("font-family":"verdana")))
    
    Dim p44 As BANanoElement = body.Append($"<p id="p4">This is a paragraph</p>"$).Get("#p4")
    p44.SetStyle(BANano.ToJson(CreateMap("font-size":"300%")))
    
    Dim p55 As BANanoElement = body.Append($"<p id="p5">This is a paragraph</p>"$).Get("#p5")
    p55.SetStyle(BANano.ToJson(CreateMap("text-align":"center")))
 

Mashiane

Expert
Licensed User
Longtime User
Lesson 7: Formatting Elements

To do this the BANano.SF (StringFormatter) function is used.

formatting.png


B4X:
Dim p1 As BANanoElement = body.Append($"<p id="p1"></p>"$).Get("#p1")
    p1.SetHTML(BANano.SF($"{B}This is a paragraph{/B}"$))
    
    Dim p2 As BANanoElement = body.Append($"<p id="p2"></p>"$).Get("#p2")
    p2.SetHTML(BANano.SF($"{I}This is a paragraph{/I}"$))
    
    Dim p3 As BANanoElement = body.Append($"<p id="p3"></p>"$).Get("#p3")
    p3.SetHTML(BANano.SF($"{U}This is a paragraph{/U}"$))
    
    Dim p4 As BANanoElement = body.Append($"<p id="p4"></p>"$).Get("#p4")
    p4.SetHTML(BANano.SF($"{C:#cd24d6}This is a paragraph{/C}"$))
 

Mashiane

Expert
Licensed User
Longtime User
Lesson 8: Creating Nested Components

In this example, we create a div, set a border around it and then add a paragraph to it. This is all being done using the .Append method of the BANanoElement. The paragraph is blank and we use .SetText on it to update its text value.

nestelements.png


Let's look at the code.

B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    '
    'create an empty div and get it
    Dim div As BANanoElement = body.Append($"<div id="div1"></div>"$).Get("#div1")
    'add a class
    div.AddClass("row")
    'set an attribute
    div.SetAttr("height", "100")
    div.SetAttr("width", "100")
    'set border
    div.SetStyle(BANano.ToJson(CreateMap("border-style": "dotted")))
    'add a paragraph to the div
    Dim p1 As BANanoElement = div.Append($"<p id="p1"></p>"$).Get("#p1")
    p1.SetText("This content is added via code!")
 
End Sub

Here we also show how to add a class to an element, set an attribute and also set the style for the border. To be able to add the paragraph to the div, the div had to have an identifier so that we could retrieve it!

If you right click on the element in the browser and then select 'Inspect Element' you will see the generate HTML element as depicted below.

viewelement.png


You will usually want to execute this code when you want to change an already existing HTML element. There are also other methods for each of the BANano "things" that you can explore. As noted, these act like JQuery so you can explore such further yourself.

Ta!

NB: All code for these lessons is downloable from post #1
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 9: Setting the background color of page body / div

The code below will change the background color of the body of the page to be light-blue.

B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    'set the background color
    body.SetStyle(BANano.ToJson(CreateMap("background-color": "lightblue")))
End Sub
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 10: Setting the background image for the page body / div

The next example shows how to set the background image of any div. The image fills the complete area of div. I have split the .SetStyles methods but you can consolidate the map as one call.

To achieve this, add the file that you will use in the 'Files' tab on your B4J projects. On compilation, the file will be saved in the /assets folder by default.

cover.png


B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    'set the background color
    body.SetStyle(BANano.ToJson(CreateMap("background-image": $"url("./assets/image001.jpg")"$)))
    'the image should not be repeated
    body.SetStyle(BANano.ToJson(CreateMap("background-repeat": "no-repeat")))
    'the image should cover the page
    body.SetStyle(BANano.ToJson(CreateMap("background-size":"cover")))
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
Lesson 11: Margins & Padding

In Lesson 8, we created a div and added a paragraph inside and the content of the paragraph was close to the edge of the div. By specifying some padding and margins, we can set the style of the element to appear as we want..

The CSS Box model is 'shaped' like this..

boxmodel.png


So you can set the margins with "margin", "margin-top", "margin-left" etc. Also the padding can be set with "padding", "padding-left" etc.

We shaped the div in our example and added some padding to the paragraph.

B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    '
    'create an empty div and get it
    Dim div As BANanoElement = body.Append($"<div id="div1"></div>"$).Get("#div1")
    'set border
    div.SetStyle(BANano.ToJson(CreateMap("border-style": "solid","width":"300px","height":"300px")))
    'add a paragraph to the div
    Dim p1 As BANanoElement = div.Append($"<p id="p1"></p>"$).Get("#p1")
    'set the text of the paragraph via code
    p1.SetText("This content is added via code!")
    'set the left margin of the paraphaph
    p1.SetStyle(BANano.ToJson(CreateMap("margin-left":"30px")))
    'set the padding of the paragraph
    p1.SetStyle(BANano.ToJson(CreateMap("padding":"24px")))
End Sub

There is a tool called EnjoyCSS that is mind blowing that you can use to explore CSS, check it out, https://enjoycss.com

The code above, produces this..

padding.png
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 12: Manipulating the canvas: A JavaScript To BANano Experiment

So far this is what we have done...

1. Created a page
2. Created two pages, added headers, a button and explored the click event of a button to move between pages
3. We created paragraphs, set background images, set styles, set attributes, set borders etc.

That was to take one through the process of designing stuff and creating HTML elements via code. Whether its an input or just a display element, creating it will mean you define its structure, set its attributes and style and then append it to the parent element you want it to show.

One of interesting controls in the HTML5 space is the canvas which you can use to draw stuff on it. This lesson will just take a peek into that. We will just go up a notch now into dealing with the BANanoObject as we have been dealing with the BANanoElement all this time.

What we will do?

1. We will create a canvas on the body of the page using own own built in class. Our built in class just builts up the markup of an HTML element. You can use whatever methodology you want to do that, like wrapping it inside $$, I'm just using my class for simplicity.

This is the HTML code to create...

B4X:
'<canvas id="mycanvas" width="600" height="400">
    'Your browser does Not support the canvas element.
    '</canvas>

My markup code for the same is... and I just added a border so that we can see the canvas, using the markup builder BANanoHTML is just a matter of choice.

B4X:
Dim cHTML As BANanoHTML
    cHTML.Initialize("canvas").SetID("mycanvas").SetWidth("600").SetHeight("400")
    cHTML.SetText("Your browser does not support the HTML 5 Canvas.")
    'lets set a border around the canvas so that we see the canvas
    cHTML.SetStyle("border", "1px solid black")
body.Append(cHTML.HTML)

Using BANAno, just as shown in examples before to do it can be done in this manner.

B4X:
Dim canvas1 As BANanoElement = body.Append($"<canvas id="mycanvas"><canvas>"$).Get("#mycanvas")
    canvas1.SetAttr("width","600")
    canvas1.SetAttr("height","400")
    canvas1.SetText("Your browser does not support the HTML 5 Canvas.")
    canvas1.SetStyle(BANano.ToJson(CreateMap("border":"1px solid black")))

Now that the canvas is added to the page, we need to get the element and get the drawing context. What we will do next is to take a javascript code line and then convert it to its banano representation. To be able to do this we will use another banano class called BANanoObject.

This was discussed here by the creator.

Here we go...

B4X:
'get the drawing context
    '****javascript
    'var ctx = document.getElementById('mycanvas').getContext('2d');
    '***banano 1.get the document
    Dim doc As BANanoObject = BANano.Window.GetField("document")
    '2. run the method
    Dim mycanvas As BANanoObject = doc.RunMethod("getElementById", Array("mycanvas"))
    'get the document context
    Dim ctx As BANanoObject = mycanvas.RunMethod("getContext", Array("2d"))

Things to remember: The RunMethod arguements are case sensitive.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 12: Continued.... Drawing on the canvas

canvas.png


What we need to achieve is to execute this script using BANano. There are a variety of ways to do this.

Option 1. Use BANano.CallJavaScriptMethod

To achieve this, we need to copy the following code to our code module

PS: Here is the complete code...

B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
   
    '<canvas id="mycanvas" width="600" height="400">
    'Your browser does Not support the canvas element.
    '</canvas>
      
    Dim canvas As BANanoElement = body.Append($"<canvas id="mycanvas"></canvas>"$).Get("#mycanvas")
    canvas.SetAttr("width","600")
    canvas.SetAttr("height","400")
    canvas.SetText("Your browser does not support the HTML 5 Canvas.")
    canvas.SetStyle(BANano.ToJson(CreateMap("border":"1px solid black")))
    BANano.RunJavascriptMethod("drawOnCanvas", Null)
End Sub

#if javascript
function drawOnCanvas() {
    ctx = document.getElementById('mycanvas').getContext('2d');
    ctx.fillStyle = "#E34C26";
    ctx.beginPath();
    ctx.moveTo(39, 250);
    ctx.lineTo(17, 0);
    ctx.lineTo(262, 0);
    ctx.lineTo(239, 250);
    ctx.lineTo(139, 278);
    ctx.closePath();
    ctx.fill();
}
#End If

Option 2 is below, we use the BANanoObject.
 

Attachments

  • DummiesLikeMeLesson12_PureJavaScript.zip
    48.9 KB · Views: 588
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 12 Continued, Option 2 - using the BANanoObject to draw on the canvas

This method involves writing the same code using BANano's own methodology. For each line in the drawOnCanvas sub, I have prefixed it with a commented line of the javascript version for more brevity and then showed how to write that using BANano syntax.

B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    '*** CREATE MARKUP ****
   
    '<canvas id="mycanvas" width="600" height="400">
    'Your browser does Not support the canvas element.
    '</canvas>
   
    Dim canvas As BANanoElement = body.Append($"<canvas id="mycanvas"></canvas>"$).Get("#mycanvas")
    canvas.SetAttr("width","600")
    canvas.SetAttr("height","400")
    canvas.SetText("Your browser does not support the HTML 5 Canvas.")
    canvas.SetStyle(BANano.ToJson(CreateMap("border":"1px solid black")))
    '
    drawOnCanvas
End Sub

Sub drawOnCanvas
    'var ctx = document.getElementById('mycanvas').getContext('2d');
    Dim doc As BANanoObject = BANano.Window.GetField("document")
    Dim mycanvas As BANanoObject = doc.RunMethod("getElementById", Array("mycanvas"))
    Dim ctx As BANanoObject = mycanvas.RunMethod("getContext", Array("2d"))
    'ctx.fillStyle = "#E34C26";
    ctx.SetField("fillStyle", "#E34C26")
    'ctx.beginPath();
    ctx.RunMethod("beginPath", Null)
    'ctx.moveTo(39, 250);
    ctx.RunMethod("moveTo", Array(39, 250))
    'ctx.lineTo(17, 0);
    ctx.RunMethod("lineTo", Array(17, 0))
    'ctx.lineTo(262, 0);
    ctx.RunMethod("lineTo", Array(262, 0))
    'ctx.lineTo(239, 250);
    ctx.RunMethod("lineTo", Array(239, 250))
    'ctx.lineTo(139, 278);
    ctx.RunMethod("lineTo", Array(139, 278))
    'ctx.closePath();
    ctx.RunMethod("closePath", Null)
    'ctx.fill();
    ctx.RunMethod("fill", Null)
End Sub

For this example, we did not include inline javascript in our code.

Just like you can include inline javascript in BANano projects, you can also include CSS, PHP etc.

See here for more details
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 13: Input Controls & Events

One can create input controls and then get and set their values using .GetValue and .SetValue. In this lesson we do the following:

1. Create a label (we will update this whenever the value in the input control changes. We trap the change event)
2. Create an input control, set some attributes to it
3. Attach an event to the onChange event of the control
4. When the event fires, update the label text with the selected value in the input control.

One can create input and other controls in this manner and then attach events to them in a similar way.

InputControls.gif


Let's peek at the code..

1. the slide BANanoElement has been created in Process_Globals.

B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    '
    body.Append($"<label id="lblvalue">Value goes here</label>"$)
    '
    body.Append("<br/>")
    
    '<input id="slide" type="range" min="0" max="100" value="100" onChange="changescale(this.value)" Step="10"/>
    slide = body.Append($"<input id="slide"></input>"$).Get("#slide")   
    slide.SetAttr("type","range")
    slide.SetAttr("min", 0)
    slide.SetAttr("max", 100)
    slide.SetAttr("value",100)
    slide.SetAttr("step",10)
    slide.AddEventListener("change", BANano.CallBack(Me, "changescale", Null), True)
End Sub

Sub changescale()
    'get the value of the element
    Dim value As String = slide.GetValue
    '
    Dim lbl As BANanoElement = BANano.GetElement("#lblvalue")
    '
    lbl.SetText(value)
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
Lesson 14: Inline CSS

In the example above, we got a taste of working with inline Javascript which we later used in calling a javascript method/sub. In this example, we use inline css to apply to our document. To do this, one needs to enclose their code inside #if CSS and #End if

B4X:
#if CSS
body
{
font: 1em Verdana, Geneva, sans-serif;
padding: 0;
margin: 5px;
color: Black;
background-color: WhiteSmoke;
}
div
{
padding: 0;
margin: 0;
}
button
{
cursor: pointer;
}
.hidden
{
display: none;
}
#End If

The inline css will apply on the affected elements

Let's create the page structure where the Css will be applied.

When executed, the running app shows this..

inlinecss.png


B4X:
Sub Show
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    '
    body.Append($"<div id="app">
<header>App</header>
<div id="main"></div>
<footer></footer>
</div>"$)
End Sub

With this approach, one might not have to use the .SetStyle(??) method as the css is automatically applied to the elements.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Lesson 14 Continued...

We can expand on the inline css. In this example, we use actual element identifiers to apply the css style.

B4X:
#if css
#app
{
margin: 4px;
background-color: #bbc;
}
#app>header
{
padding: 0 0.5em;
font-size: 1.5em;
color: WhiteSmoke;
background-color: #006;
}
#app>footer
{
padding: 0.25em;
color: WhiteSmoke;
background-color: #006;
}
#main
{
margin: 1em;
}
#End If

And when the code is executed, you have something like this..

inlinecss1.png
 

Mashiane

Expert
Licensed User
Longtime User
Lesson 15: Using other JavaScript Libs, case in point JQuery

Most available library at this time use the JQuery library to perform some tasks. If ever you get to have to create custom components for BANano, you might need to use JQuery. Remember, BANano is built using the UmbrellaJS library which has functionality like JQuery.

In this lesson, we will create a class and name it BANanoJQuery just to demonstrate this. We will add a few methods to it so that we are able to change some things in our app. The functions we will use .Append and .SetText are already built in and this is just to demo how this works.

As an example, let's look at these two javascript calls...

B4X:
$("#app>header").append(version);
setStatus("ready");

where setStatus is defined as..

B4X:
function setStatus(message)
{
$("#app>footer").text(message);
}

JQuery is initialized using the dollar sign $. To initialize that inside BANano, we have to do the following.

1. Add JQuery using Files tab, this will be saved on the ./scripts folder of our app.
2. In AppStart, add the resource in the header.

B4X:
'add jquery
    BANano.Header.AddJavascriptFile("jquery-3.4.1.min.js")

In the class we have created, we have dimensioned a JQuery variable as a BANanoObject, so we need to initialize it using the JQuery keyword $.

B4X:
Sub Class_Globals
    Public JQuery As BANanoObject
    Private BANano As BANano
End Sub

'In AppStart add
'BANano.Header.AddJavascriptFile("jquery-3.4.1.min.js")

'Initializes jquery
Public Sub Initialize
    JQuery.Initialize("$")
End Sub

Let's create our own .Append and our own .SetText methods that will be used by the JQuery variable.

B4X:
'set the text for an element
Sub SetText(elID As String, text As String) As BANanoJQuery
    JQuery.Selector(elID).RunMethod("text", text)
    Return Me
End Sub

'usage:
'*** javascript : $("#app>footer").text(message);
'*** JQuery.SetText("#app>footer", message)

'append content
Sub Append(elID As String, text As String) As BANanoJQuery
    JQuery.Selector(elID).RunMethod("append", text)
    Return Me
End Sub

'usage:
'*** javascript: $("#app>header").append(version);
'*** JQuery.Append("#app>header", version)

When this is being executed, on the screen we will see this...

jquery.png


As seen above, the BANanoObject class exposes a .Selector(??) method to select elements. In JQuery..

B4X:
A jQuery Selector is a function which makes use of expressions to find out matching elements from a DOM based on the given criteria. Simply you can say, selectors are used to select one or more HTML elements using jQuery.

With BANano, we used .Get("#body") and .GetElement("#body") to retrieve the body element in our previous examples, the same principle applies.

Looking at the complete code..

B4X:
Sub Show
    'initialize jquery
    JQuery.Initialize
    'call the javascript method to ensure all variables are defined
    JQuery.UseStrict
    
    'get the body element of the page
    body = BANano.GetElement("#body")
    'clear the body
    body.Empty
    '
    body.Append($"<div id="app">
<header>App </header>
<div id="main"></div>
<footer></footer>
</div>"$)
    
    'define the version
    version = "v1.0"
    '
    JQuery.Append("#app>header", version)
    JQuery.Append("#main", "This is my JQuery App!")
    setStatus("ready...")
End Sub

Sub setStatus(message As String)
    JQuery.SetText("#app>footer", message)
End Sub
 
Top