Share My Creation [BANano] Create your UX with MaterializaCSS using UOEBANano

Mashiane

Expert
Licensed User
Hi there


NB: This is an OpenSource project, anyone can contribute to it and enhance it. I happen to have some time challenges on my side and due to the sheer size of this thing, I might not fully be doing it.

My BANano Related Projects

CRUD with LocalStorage BackEnd

Methodology Used

1. Create your UX via code (no abstract designer is used). The UOEBANanoDemo project has in detail shown how this is done. The UOEContainer is the master component including UOEHTML component.
Components can sit inside a grid using RC e.g. R1C1, R5C1 or outside the grid at R0C0. You create a grid first to place components in.
2. Bind events to elements AFTER injecting body - this is done with AddEvent and BindEvent(s)

To Do
  • CSS Styles - universal themeing
  • Setters and Getters - most of these you can use BANano right away (however there are some functions within MaterializeCSS that need a little attention
  • Fixing some bugs and some irritations
  • Adding click events to most clickable things.
How to explore the library and demo
  • Download alwaysbusy's BANano and save it on your external libraries.
  • Download UOEBANano (library source code) and UOEBANanoDemo (demo source code). This has been built with the latest version of BANano.
  • Open UOEBANano project, run it (f5) and also compile it to library.
  • Copy the contents of the Files folder inside UOEBANano to UOEBANanoDemo Files folder
  • Copy the webfonts folder to Objects\UOEBANanoDemo folder
  • Copy the fonts folder to Objects\UOEBANanoDemo\styles folder
  • Open UOEBANanoDemo project, run it and open the generated index.html file on your Objects\UOEBANanoDemo folder via your browser. You should be seeing something as per video above.
  • Both library and source code are available for your pleasure/leisure if interested.
  • If you decide to take up some parts of the project and update/add, please push them to github for all of our impulsive nerves.
UOEBANAnoDemo (if all goes well, you should see this)

Use the UOEToc on right to explore each element. You can see the code in the demo about how it was created.

DemoProject.png




Example Client Project

ATM.png


Above is an example client project I have just demoed, its a CRUD application to register, search, update member records for an organization. It used Modals and some input components and uses LocalStorage as a backend.

Ta!

PS: This is just a UX workaround, you will have to BANano your way around your project functionality.

Take care and enjoy.
 
Last edited:

Mashiane

Expert
Licensed User
Updated opensource UOEBANano to work with BANano 2.17

ChangeLog

1. Updated most clickable things to have hasEvent, as some elements can use href to navigate, hasEvent should be turned off for them, those that have a click event have this added with .HandleEvents. When clickable elements are added to a page, an AddEvent is added automatically to track which elements will have 'click' events. One can create any event linked to an element id with AddEvent(ElementID, "change"), BEFORE Page.Create. App.BindEvents("eventMethod", Me) will then execute .HandEvents for all the elements.
2. A universal event handler can be used or single events can be used per elements added to the page.
3. When clickable things are added, on the demo a toast will show of the clicked element, also on console log - see (event as BAnanoEvent) examples in the pages.
4. To yet update the example on post #1.
 

Mashiane

Expert
Licensed User
UOEFile

With this component one is able to select a file using file input and then process it whatever way they need. This demo shows how to read the file properties like name, date and size. This is still work in progress as I need to load an image from a file selection and then upload the file.

UOEFile.gif


I define the component in Process_Globals

B4X:
Dim fu As UOEFile
Then in Page.Init I add the component to the page

B4X:
fu.Initialize(App,"fu","Browse","Upload one or more files...",False,"")
    Page.Content.AddFile(1,1,fu)
So in my active app, I trap the event..

B4X:
Sub navEvents(event As BANanoEvent)
    modBANano.tocButtons(event)
    Page.ToastSuccess(event.ID)
    Dim elID As String = App.GetID(event.ID)
    Log(event.ID)
    Select Case elID
        Case "fu"
            Dim fd As Map = fu.GetFile
            Dim sname As String = fd.Get("name")
            Dim ssize As String = fd.Get("size")
            Dim sdate As String = fd.Get("date")
            App.SetText("filename", $"File Name: ${sname}"$)
            App.SetText("filesize", $"File Size: ${ssize}"$)
            App.SetText("filedate", $"File Date: ${sdate}"$)
            Log(fd)
        Case "fu1"
    End Select
End Sub
To create this element workings inside the UOEBANano library, first I needed a method to find out which file is selected, so I include this for my UOEBANano library. This ensures it works with any file input element

B4X:
#if javascriptsmart
    function getSelectedFile(elid){
        var fi = document.getElementById(elid);
        var file = fi.files[0];
        var fp = {};
        fp.name = file.name;
        fp.size = file.size;
        fp.type = file.type;
        fp.date = file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() : '';
        fp.file = file;
        fi.value = null;
        return fp;
    }
#End If
Then I define a method to return the details to the active app inside the UOEFile component.

B4X:
Sub GetFile As Map
    Dim fp As Map
    fp.Initialize
    fp = BANAno.RunJavascriptMethod("getSelectedFile",Array As String(ID))
    Return fp
End Sub
The ID is the element id of my file input element and it has a change event added with .HandleEvents

B4X:
App.AddEvent(ID,"change",$"${ID}_change"$)
Ta!
 
Last edited:

Mashiane

Expert
Licensed User
Image File Preview

The next part is to show the selected image preview on an image..

Continuing with the above UOEFile example, we add an image to the page..

B4X:
Page.Content.AddImage1(1,1,"profile","./assets/eric.png","Eric",True,App.EnumZDepth.zdepth_4,True,False,False,"","","","")
UOEFilePreview.gif


Then on our event handler, instead of calling fu.GetFile, we call..

B4X:
fu.ShowPreview("profile")
This gets the file contents and renders it on the 'profile' image element.

This is possible due to the FileReader API. We have our javascript code that gets both the file input and image elements and then using the file reader api, renders the image

B4X:
#if javascript
    function previewfile(fileid,imgid){
        var fi = document.getElementById(fileid);
        var img = document.getElementById(imgid);
        var file = fi.files[0];
        var reader = new FileReader();
        reader.addEventListener("load", function () {
            img.src = reader.result;
        }, false);
        if (file) {
            reader.readAsDataURL(file);
          }
    }
#End If
And the UOEFile.ShowPreview method is simple as...

B4X:
Sub ShowPreview(imgid As String)
    BANAno.RunJavascriptMethod("previewfile", Array As String(ID,imgid))
End Sub
Ta!
 

Mashiane

Expert
Licensed User
Thanks to Kiffi, a 'banano-way' of working around the BANanoObject to achieve the same FileReader stuff was availed.

B4X:
Sub UploadCallback(Event As Map)
    Dim Target As BANanoObject = Event.Get("target")
    Dim UploadedFile As BANanoObject = Target.GetField("file")
    Log("UploadedFile: " & UploadedFile.GetField("name"))
    Log("DataURL: " & Target.GetField("result"))
End Sub

Sub GetBase64 As String
    'var fi = document.getElementById(fileid);
    Dim fi As BANanoElement = BANAno.GetElement($"#${ID}"$)
    'var files = fi.files;
    Dim UploadedFiles() As String = fi.ToObject.GetField("files").Result
        
    For UploadCounter = 0 To UploadedFiles.Length - 1
        'var fr = new FileReader();
        Dim FileReader As BANanoObject
        FileReader.Initialize2("FileReader", Null)
        'fr.readAsDataURL(files[0]);
        FileReader.SetField("file", UploadedFiles(UploadCounter))
        Dim evt As Map
        'fr.onload = function(){
        FileReader.SetField("onload", BANAno.CallBack(Me, "uploadcallback", Array(evt)))
        FileReader.RunMethod("readAsDataURL", UploadedFiles(UploadCounter))
    Next
End Sub
As I'm also learning javascript for other things besides BANano, you will decide what to use.
 

Mashiane

Expert
Licensed User
In this instance, adopting the code above, one can be able to retrieve the file DataURL. I wanted something like this to save the data to the db.

FileDataURL.gif


1. Add a file input control as usual

B4X:
fu2.Initialize(App,Me,"fu2","File DataURL","Get file DataURL...",False,"")
    Page.Content.AddFile(1,1,fu2)
    Page.Content.AddBreak(1,1)
2. Remember to define it as a progress_global variable.

B4X:
Dim fu2 As UOEFile
3. Call the method to call the DataURL for the file.., this is done in the events handler

B4X:
Sub navEvents(event As BANanoEvent)
    modBANano.tocButtons(event)
    Page.ToastSuccess(event.ID)
    Dim elID As String = App.GetID(event.ID)
    Log(event.ID)
    Select Case elID
        Case "fu"
            Dim fd As Map = fu.GetFile
            Dim sname As String = fd.Get("name")
            Dim ssize As String = fd.Get("size")
            Dim sdate As String = fd.Get("date")
            App.SetText("filename", $"File Name: ${sname}"$)
            App.SetText("filesize", $"File Size: ${ssize}"$)
            App.SetText("filedate", $"File Date: ${sdate}"$)
        Case "fu1"
            fu1.ShowPreview("profile")
        Case "fu2"
            fu2.GetDataUrl
    End Select
End Sub

4. A look at the code to make this work is in the UOEFile class of UOEBanano

B4X:
Sub uploadcallback(Event As Map)
    Dim Target As BANanoObject = Event.Get("target")
    'Dim UploadedFile As BANanoObject = Target.GetField("file")
    'Log("UploadedFile: " & UploadedFile.GetField("name"))
    Dim result As BANanoObject = Target.GetField("result")
    'call the FileDataURL sub inside your calling module
    BANAno.CallSub(EventHandler,"FileDataURL",Array(ID, result))
End Sub

Sub GetDataUrl()
    Dim fi As BANanoElement = BANAno.GetElement($"#${ID}"$)
    'get the selected files, if any
    Dim files() As String = fi.ToObject.GetField("files").Result
    'loop though each selected file
    For fCnt = 0 To files.Length - 1
        Dim FileReader As BANanoObject
        FileReader.Initialize2("FileReader", Null)
        FileReader.SetField("file", files(fCnt))
        Dim evt As Map
        FileReader.SetField("onload", BANAno.CallBack(Me, "uploadcallback", Array(evt)))
        FileReader.RunMethod("readAsDataURL", files(fCnt))
    Next
End Sub
5. On the hosting page module..

B4X:
Sub FileDataURL(id As String, bo As BANanoObject)
    Log("working...")
    Log(id)
    Log(bo)
End Sub
Now the only thing is figuring out how to upload files to the server and that should cover it.

Ta!
 

Mashiane

Expert
Licensed User
Top