B4J Tutorial BANano for Dummies by Example

Discussion in 'B4J Tutorials' started by Mashiane, Aug 17, 2019.

Tags:
  1. Mashiane

    Mashiane Expert Licensed User

    Lesson 16: Let's create a simple app to record our tasks using everything we have learned so far. This is:

    1. Creating elements on a page
    2. Setting properties and classes to elements
    3. Linking events to elements
    4. Using JQuery as an additional library in our app.

    We will also add some additional things to make our app work, we will demonstrate how to use LocalStorage to save and retrieve our tasks.

    Lets build the skeleton... its not too much eye candy at the moment. What we are NOT doing is to use a framework here because one can choose their own framework to use. At the end, the principle of creating websites/webapps is the same, they are all HTML elements.

    TaskAtHand.gif

    Preparations:

    1. We changed our page header to that it now shows Task@Hand
    2. We took all our inline css and saved it in a file and added this file link to our header.
    3. We added JQuery as a dependency for the project.

    Code:
    'the title of the page
        BANano.Header.Title = "Task@Hand"
        
    'add our own css
        BANano.Header.AddCSSFile("taskathand.css")
        
    'add jquery
        BANano.Header.AddJavascriptFile("jquery-3.4.1.min.js")
    We then went on and created the skeleton of our page. This time, to attach an event to an element, we have used the On keyword of the BANanoElement.

    Code:
    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
        
    'define the body of the app
        body.Append($"<div id="app">
    <header>Task@Hand </header>
    <div id="main">
    <div id="add-task">
    <label for="new-task-name">Add a task</label>
    <input type="text" id="new-task-name"
    title="Enter a task name" placeholder="Enter a task name"/>
    </div>
    <ul id="task-list">
    </ul>
    </div>
    <footer>
    </footer>
    </div>"$
    )
       
        
    'define the version
        version = "v1.0"
        
    '
        JQuery.Append("#app>header", version)
        setStatus(
    "Ready")
       
        
    'get the element to attach event to
        Dim taskName As BANanoElement = BANano.GetElement("#new-task-name")
        
    'attach the event
        taskName.On("keypress", Me, "task_keypress")
       
    End Sub

    'fires when a keypress happens on task
    Sub task_keypress(e As BANanoEvent)
        
    Log(e)
    End Sub

    Sub setStatus(message As String)
        JQuery.SetText(
    "#app>footer", message)
    End Sub
    What we want to achieve is that as soon as the user, presses Enter key, the task is added to the list and the focus set on the task name element.

    Code:
    taskName.On("keypress", Me, "task_keypress")
    What we are saying is, On a 'keypress' event, in this code module (ME), execute a method called 'task_keypress'

    As you noted in the GIF, each time we pressed a key in the textbox, console log recorded our keypress.

    Code:
    Sub task_keypress(e As BANanoEvent)
        
    Log(e)
    End Sub
     
    Johan Hormaza likes this.
  2. Mashiane

    Mashiane Expert Licensed User

    Lesson 16: Continued

    TaskAtHand1.gif

    1. As soon as the user has entered a task, add it to the task list by calling addTask

    Code:
    'fires when a keypress happens on task
    Sub task_keypress(e As BANanoEvent)
        
    'if we press enter
        If e.CharCode = 13 Then
            addTask
            
    'cancel default operation/bubbling
            Return False
        
    End If
        
    'set the focus to the task name element
        JQuery.Focus("#new-task-name")
    End Sub
    2. In addTask, the contents of the input text are read. I have written equivalents of this in both jquery and BANano, so we can just comment out the jquery for .GetValue and .SetValue and use BANano built in methods.

    Code:
    Sub addTask
        
    'get the task name
        '*** jquery : var tskName = $("#new-task-name").val();
        '*** BANano : Dim tskName As Object = BANano.GetElement("#new-task-name").GetValue
        Dim tskName As String = JQuery.GetValue("#new-task-name")
        
    If tskName = "" Then Return
        addTaskElement(tskName)
        
    'clear the contents of the textvalue and set focus
        '*** jquery : $("#new-task-name").val("");
        '*** jquery : $("#new-task-name").focus();
        '*** BANAno : BANano.GetElement("#new-task-name").SetValue("")
        JQuery.SetValue("#new-task-name""")
        JQuery.Focus(
    "#new-task-name")
    End Sub
    When the contents are read, they are added to the task list by calling addTaskElement. When that is done, the input text is cleared and then the focus moved to the input element.

    Code:
    Sub addTaskElement(taskName As String)
        
    '*** BANANO : BANano.GetElement("#task-list").Append($"<li>${taskName}</li>"$)
        'var $task = $("<li></li>");
        ''$task.text(taskName);
        '$("#task-list").append($task);
     
        
    Dim task As BANanoObject = JQuery.createElement("li")
        JQuery.SetTextBO(task, taskName)
        JQuery.Append(
    "#task-list", task)
    End Sub
    IMPORTANT:

    It could be really confusing doing these mandane tasks using JQuery whilst BANano has a potent system of doing so. So, for anything that BANano can do, rather use it than using JQuery.

    To summarise, this was taking you through the process of calling jquery within BANano.

    1. We declared JQuery and initialized it.

    Code:
    Public JQuery As BANanoObject
    Code:
    JQuery.Initialize("$")
    2. We showed how to call the val method to set a value to an element.

    Code:
    JQuery.Selector(elID).RunMethod("val", val)
    3. We showed how to get a value from an element

    Code:
    Dim obj As Object = JQuery.Selector(elID).RunMethod("val"Null).result
    4. We showed how to append text using JQuery

    Code:
    JQuery.Selector(elID).RunMethod("append", text)
    5. We called the focus method..

    Code:
    JQuery.Selector(elID).RunMethod("focus"Null)
    6. We also called createElement by using a LI (list item). We created a method to do that.

    Code:
    'create an element
    Sub createElement(tag As StringAs BANanoObject
        
    Dim markup As String = $"<${tag}></${tag}>"$
        
    Dim newEL As BANanoObject = JQuery.Selector(markup)
        
    Return newEL
    End Sub
    IMPORTANT:

    Most of what one will do when writing BANano code is to write javascript / jquery code using BANano, thus understanding the nitty gritties of BANano and how it does things will help.

    If you explore the BANanoElement class in BANano, it has enough methods to perform the tasks that we did with JQuery here. So use JQuery sparringly as it just bloats your app with functions that already exists in BANano. For those libraries that have it that you might want to wrap for BANano, using javascript and then call .RunJavaScriptMethod is better. But then again, use your discretion as nothing is limited. #

    I have learned that there are just some things that are just left as javascript without having to convert them to BANano code. Why? Because BANano transpiles B4J code to Javascript, so 10 lines of javascript are better than 50 lines of B4J in BANano in some cases. Let's think about it.

    OPTION 1
    Copy the following code to your code and use RunJavaScriptMethod.

    Code:
    BANano.RunJavascriptMethod("drawOnCanvas"Null)
    Code:
    #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
    Writing BANano Code for the same thing. Yes you can use both methods in your project.

    Code:
    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(39250))
        
    'ctx.lineTo(17, 0);
        ctx.RunMethod("lineTo"Array(170))
        
    'ctx.lineTo(262, 0);
        ctx.RunMethod("lineTo"Array(2620))
        
    'ctx.lineTo(239, 250);
        ctx.RunMethod("lineTo"Array(239250))
        
    'ctx.lineTo(139, 278);
        ctx.RunMethod("lineTo"Array(139278))
        
    'ctx.closePath();
        ctx.RunMethod("closePath"Null)
        
    'ctx.fill();
        ctx.RunMethod("fill"Null)
    End Sub
    You decide and yes, you can CHAIN methods with BANano.
     
    Last edited: Aug 21, 2019
    Johan Hormaza likes this.
  3. Mashiane

    Mashiane Expert Licensed User

    Lesson 16: Another Version

    We decided to do an extra part of lesson 16 using BANano and Javascript all the way. For this we needed the focus method.

    Code:
    Sub Focus(elID As String)
    'document.getElementById("???").focus();
        BANano.Window.GetField("document").RunMethod("getElementById"Array(elID)).RunMethod("focus"Null)
    End Sub
    So that we can set the focus to the task element we need.

    In the end, you have a more simpler and shorter code base.

    Code:
    Sub addTask
        
    'get the task name
        Dim tskName As String = BANano.GetElement("#new-task-name").GetValue
        
    If tskName = "" Then Return
        addTaskElement(tskName)
        BANano.GetElement(
    "#new-task-name").SetValue("")
        Focus(
    "#new-task-name")
    End Sub
    '
    Sub addTaskElement(taskName As String)
        BANano.GetElement(
    "#task-list").Append($"<li>${taskName}</li>"$)
    End Sub

    Sub setStatus(message As String)
        BANano.GetElement(
    "#app>footer").SetText(message)
    End Sub
     
  4. Mashiane

    Mashiane Expert Licensed User

    Lesson 17: We showcase a task manager built with BANano + Jquery

    This lesson is more about the logic and functionality than the UX / used libraries.


    1. Add a task
    2. Update a task
    3. Delete a task
    4. Move a task up
    5. Move a task down
    6. Save tasks to LocalStorage
    7. Load tasks from LocalStorage
    8. Adding buttons inside a list
    9. Adding events to items before they get added to UX.
    10. Detecting events on button clicks for elements without ids by using BANanoEvent

    As we are not using any framework, we have not styled the UX for this.

    TaskAtHand2.gif

    Get lesson content here,, https://github.com/Mashiane/BANano4Dummies

    What this meant...

    Our sub to add the tasks had to be updated to ensure that we have X, E, U and D buttons inside the list. Whenever X,E,U,D is clicked, we needed to trap this and fire the right event.

    In creating each BANAnoElement below, we called JQuery and converted the object from Jquery to a BANanoElement. We are doing this because at time of creation, the element is not yet added to the body of the page and it also does not have an identifier.

    Code:
    Sub addTaskElement(taskName As String)
        
    'delete button segment
        Dim delete As BANanoElement = JQuery.createElement($"<button title="Delete" class='delete'>X</button>"$)
        delete.On(
    "click", Me, "task_delete")
        
    'edit button segment
        Dim edit As BANanoElement = JQuery.createElement($"<button title="Edit" class='edit'>E</button>"$)
        edit.On(
    "click", Me, "task_edit")
        
    'move up button
        Dim moveUp As BANanoElement = JQuery.createElement($"<button title="Up" class='move-up'>U</button>"$)
        moveUp.On(
    "click", Me, "task_up")
        
    'move down button
        Dim moveDown As BANanoElement = JQuery.createElement($"<button title="Down" class='move-down'>D</button>"$)
        moveDown.On(
    "click", Me, "task_down")
        
    'span to show the item
        Dim span As BANanoElement = JQuery.createElement($"<span class='task-name'> ${taskName}</span>"$)
        
    'create an empty list item
        Dim task As BANanoElement = JQuery.createElement($"<li class="task"></li>"$)
        
    'join other elements
        JQuery.AppendMulti(task, Array(delete, edit, moveUp, moveDown, span))
        
    'add to the list
        JQuery.Append("#task-list", BANano.ToObject(task))
    End Sub
    .AppendMulti, adds all the children to the parent task element using JQuery. We then append everything to the 'task-list' element.

    In this case use the .On method to add an event to the button. This is not the only method to do this. We might hav just created a template html for all of this and just assigned events to it later.

    The last item in the <li></li> item is the text of the task being added, so in our edit button, we set the mode to 'E', then read the lastSibling in the list and then set the value of the textbox.

    Code:
    'when a task is being edited
    Sub task_edit(e As BANanoEvent)
        Mode = 
    "E"
        
    'get the parent node of the button as the button is inside a li
        Dim task As BANanoElement = JQuery.ParentNode(e)
        
    'get last child in the list
        lastEdit = JQuery.LastChild(task)
        
    Dim text As String = lastEdit.GetText
        
    'edit mode show entry
        BANano.GetElement("#new-task-name").SetValue(text)
        
    'focus to text box
        JQuery.Focus("#new-task-name")
    End Sub
    To delete the task, we need to remove the complete <li></li> item, so we need a way to get it and then remove it from the list. Here we use the BANanoEvent and get the 'target' and from the target get the 'parentNode' to be able to get the <li></li> the button is inside of.

    Code:
    'when a task is being deleted
    Sub task_delete(e As BANanoEvent)
        Mode = 
    ""
        
    'get the parent node of the button as the button is inside a li
        Dim task As BANanoElement = JQuery.ParentNode(e)
        
    'remove the item from the list
        JQuery.Remove(task)
        SaveTasks
    End Sub
    The ParentNode sub is NOT JQuery (just saved there) is...

    Code:
    'get the parent node from the event
    Sub ParentNode(e As BANanoEvent) As BANanoElement
        
    'get the target from event
        Dim target As BANanoObject = e.OtherField("target")
        
    'get the parentNode from target
        Dim parent As BANanoElement = BANano.ToElement(target.GetField("parentNode"))
        
    Return parent
    End Sub
    Moving the tasks up / down

    For that we get the <li></li> that we have selected using ParentNode, then we move that up/down

    Code:
    'when a task is being moved up
    Sub task_up(e As BANanoEvent)
        Mode = 
    ""
        
    'get the li the up button sits inside
        Dim task As BANanoElement = JQuery.ParentNode(e)
        
    'move the item up
        JQuery.MoveUp(task)
        SaveTasks
    End Sub

    'when a task is being moved down
    Sub task_down(e As BANanoEvent)
        Mode = 
    ""
        
    'get the task the button sits inside of
        Dim task As BANanoElement = JQuery.ParentNode(e)
        
    'move item down
        JQuery.MoveDown(task)
        SaveTasks
    End Sub
    After we have moved an element, they are saved to LocalStorage.

    Let's look at moveup in a simplified way..

    Code:
    'move an item up
    Sub MoveUp(itm As BANanoElement)
        
    'get the previous sibling
        Dim prev As BANanoElement = BANano.ToElement(itm.GetField("previousSibling"))
        
    Dim s As BANanoObject = BANano.ToObject(itm)
        
    Dim t As BANanoObject = BANano.ToObject(prev)
        JQuery.Selector(s).RunMethod(
    "insertBefore", t)
    End Sub
    In Summary..

    1. We click a button inside a list, this fires an event and returns a BANanoEvent
    2. We read this BANanoEvent in task_up, 2.1 we get the target of BANanoEvent and from the target 2.2 we get the parentNode, this gives us the LI item
    1. We get the list item from 2.2, (a BANanoElement) and pass this to move up sub
    2. The LI is storing the link to the previousSibling, we get that previous LI
    3. We then convert the current LI and the previous LI to BANanoObjects and then use JQuery 'insertBefore' method to move these around.

    Mind boggling...
     
    Last edited: Aug 23, 2019
    Johan Hormaza and joulongleu like this.
  5. Mashiane

    Mashiane Expert Licensed User

    Lesson 18: In most cases you will not need JQuery

    Whilst lesson 18, dealt with functionality done using the JQuery library, in most cases you will not need this as JavaScript is capable.

    To demo this, we will create a class named BANanoJavaScript. As most of what you will do is to reference the document object, let's create a global variable and then initialize it in Initialize.

    javascript.png

    Code:
    #IgnoreWarnings:12
    Sub Class_Globals
        
    Private document As BANanoObject
        
    Private BANano As BANano  'ignore
    End Sub

    Public Sub Initialize
        document = BANano.Window.GetField(
    "document")
    End Sub
    For starters, in our previous example, we used the .Focus method

    Let's create a javascript version..

    Code:
    'focus
    Sub focus(arguements As String)
        
    'document.getElementById("myAnchor").focus();
        document.RunMethod("getElementById"Array(arguements)).RunMethod("focus"Null)
    End Sub
    One of the most things we are doing is to create HTML elements, set properties to them and styles and add them to the DOM tree. In most cases, you call an .Append method to the parent element you need and use .Get with BANano. Let's work on a premise that you want to create an element and then add it it the DOM tree. With javascript there is a .createElement to do that and then you can use .Append later. Let's create own own .createElement method.

    Code:
    'createElement
    Sub createElement(arguements As StringAs BANanoElement
        
    'var newItem = document.createElement("LI");
        Dim bo As BANanoObject = document.RunMethod("createElement"Array(arguements))
        
    Return BANano.ToElement(bo)
    End Sub
    You might want to get the innerHML and outerHTML of your element

    Code:
    'GetOuterHTML
    Sub GetOuterHTML(el As BANanoElement) As String
        
    'var content = element.outerHTML;
        Dim sout As String = el.GetFIeld("outerHTML").Result
        
    Return sout
    End Sub
    Code:
    'GetInnerHTML
    Sub GetInnerHTML(el As BANanoElement) As String
        
    'var content = element.innerHTML;
        Dim sout As String = el.GetField("innerHTML").Result
        
    Return sout
    End Sub
    If you are used to JavaScript, you might still want a familiar approach, lets look at the querySelector...

    Code:
    'querySelector
    Sub querySelector(parent As BANanoElement) As BANanoElement
        
    Dim bo As BANanoObject = parent.RunMethod("querySelector"Null)
        
    Return BANano.ToElement(bo)
    End Sub
    You might want to create multiple items and then add them in one go, why dont you pass them as a list to the .appendChild method.

    Code:
    'appendChild
    Sub appendChild(parent As BANanoElement, childs As List)
        
    For Each child As BANanoElement In childs
            
    Dim bo As BANanoObject = BANano.ToObject(child)
            parent.RunMethod(
    "appendChild"Array(bo))
        
    Next   
    End Sub
    Finally, some of the more or less used methods in javascript... more / less

    Code:
    'getElementById
    Sub getElementById(arguements As StringAs BANanoElement
        
    'var list = document.getElementById("myList");
        Dim bo As BANanoObject = document.RunMethod("getElementById"Array(arguements))
        
    Return BANano.ToElement(bo)
    End Sub

    'getElementsByTagName
    Sub getElementsByTagName(parent As BANanoElement, arguements As StringAs List
        
    'var list = document.getElementsByTagName("<p>");
        Dim lst As List = parent.RunMethod("getElementsByTagName"Array(arguements)).result
        
    Return lst
    End Sub

    'getElementsByClassName
    Sub getElementsByClassName(parent As BANanoElement, arguements As BANanoElement) As List
        
    'var list = element.getElementsByTagName("<p>");
        Dim lst As List = parent.RunMethod("getElementsByClassName"Array(arguements)).result
        
    Return lst
    End Sub
    Lesson 18 here demos how the attached page was created using simple calls to both banano and the javascript class created. It does not have everything but the basis to create elements, set properties and styles. The basics to get you going.

    Ta!
     
    Johan Hormaza and joulongleu like this.
  6. Mashiane

    Mashiane Expert Licensed User

    In closing this [Just to get you Going] journey

    During the course of this series, we have demonstrated the following...

    1. Setting up your BANano project
    2. Adding a page and multiple pages to your project.
    3. Adding elements to the body of the page
    4. Setting element properties like styles, attributes, changing color, changing font
    5. Adding buttons and linking events to them using CallBacks
    6. Manipulating data from the BANanoEvent object
    7. Adding an input control and getting / setting a value to it.
    8. Creating a markup using a class for your HTML elements and appending this to a BANanoElement
    9. Using another library with BANano, e.g. JQuery and how to initialize it and use Selectors and call other methods like .GetField, .SetField, RunMethod
    10. Inline JavaScript and how to call it
    11. Inline CSS
    12. Defining own css file and adding it to the header of our project
    13. Accessing Javascript object e.g. document and calling its method e.g. getElementByID, .focus
    14. We took a peek at the MiniCSS and Skeleton frameworks that you can use with BANano to create your amazing projects
    15. We explored the canvas and how to access the 2d context. This was just a brief..

    etc

    There are a lot of tutorials in the forum to do a variety of things with BANano. In this thread, we have demonstrated the basic things to get one up and going in doing a website/webapp and also just understand what BANano is and what it does. It has a lot of other things that have not been discussed on this thread as they are beyond this thread.

    If you have any questions about BANano, kindly start a new thread with your questions.

    Enjoy your BANano Journey, I'm out!!

    PS: Thanks for the ears, appreciated!
     
    Last edited: Aug 23, 2019
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