Share My Creation [BANanoWebix] An OpenSource Webix UX Wrapper for BANano

Discussion in 'B4J Share Your Creations' started by Mashiane, Jun 12, 2019.

  1. Mashiane

    Mashiane Expert Licensed User

    Ola

    New: BANanoWebix App Creation Process

    Please download your own copy of the Webix resources here: Webix GPL License - OpenSource

    Fork

    Reproduction:

    1. Download BANano 3.09+ and save in external libraries
    2. Open BANanoWebix project and run it and ensure BANanoWebix.b4xlib created!
    3. Open BANanoWebixDemo, reference BANano 3.09+ and BANanoWebix 1.03+
    4. On execution, the web-browser should be opened with the local file. I am using XAMPP as my webserver.

    Now Featuring a Form Designer that generates source code you can use in your B4J Project





    Lesson 1
    Lesson 2
    Lesson 3
    Lesson 4
    Lesson 5
    Lesson 6
    Lesson 7.1
    Lesson 8
    Lesson 9
    Lesson 10
    Lesson 11
    Lesson 12
    Lesson 13
    Lesson 14
    Lesson 15
    Lesson 16
    Lesson 17
    Lesson 18
    Lesson 19
    Lesson 20
    Lesson 21
    Lesson 22 - Method 1
    Lesson 22 - Method 2
    Lesson 22 - Method 3
    Lesson 23
    Lesson 24
    Lesson 25
    Lesson 26
    Lesson 27
    Lesson 28
    Lesson 29
    Lesson 30
    Lesson 31

    Creating a multi-page SPA

    For a long long long while I have been very curios about Webix, It reminded me of my days when I was doing ASP.Net with Ext.JS many many moons aho. That helped me create my first web database application with SQL as a backend back in 2009. A lot of VB.Net code that was... It was marvelous and I was the happiest man in the world, king of the world. It so amazing how the excitement of achieving something as a first "Hellow World" app running without hurdles. Just like when I first wrote my first Android app with B4A many years back.

    So today I spent time time to feed that curiosity and with my question being can I achieve this with BANano? I am happily surprised and satisfied that I was able to pull it off, and I had to take everything I tend to think about HTML out of the window for a while to Object Orientation.

    I made mistakes, rewrote stuff, debugged a lot, but hey, ended up with a single component class to rule them all.

    What I liked most was that all this was done without a single HTML element being created by me. I'm basically using Lists and Maps all the way. Everything is an object and Webix just renders, creates the datasource links automatically. Basically I just had to worry about the look and feel of the app.

    So I followed their example, tried to understand the logic of what they did things and came up with my own flavor of implementation.

    Webix.png
    As their lib is quiet huge, this just for me meant that its possible and if I want to explore more of their candy, I continue on the trend, there are a lot of things I like about it though and well, their price is not as welcoming. Yes for internal company apps and open source apps, the moon is no longer the limit. Anything commercial should be licensed.

    Exporting Offline: BANanoWebix 1.04+

    The current implementation of BANanoWebix is able to export to excel, pdf etc only when you are connected to the internet.

    To be able to export offline without an internet connection there is about 6MB of resources needed as discussed here.

    In BANanoWebix, this is how this has been implemented..

    1. Unzip the extras folders to your project build folder.

    Code:
    BP.UnzipFonts
        BP.UnzipFile(
    "extras.zip")
    2. On the page where you will use exporting, after page initialize

    Code:
    pg.Initialize("wp", pgContainer).SetHeader("Lesson 8.3 Datatable Pager").SetResponsive("master")
        pg.SetExtrasFolder(
    "http://localhost/bananowebixdemo/extras")
        
    '
    Execute .SetExtrasFolder

    Use your own PROJECTNAME for bananowebixdemo

    Developing an app

    In their example, this is the structure of the Basic App.

    Code:
    webix.ui({
        width:
    500,
        rows:[
            {
                
    view:"toolbar", elements:[
                    { 
    view:"button", value:"Add", width:100 },
                    { view:"button", value:"Delete", width:100 }
                ]
            },
            {
                height:120, cols:[
                    {
                        view:"form", elements:[
                            { view:"text", placeholder:"Title" },
                            { view:"text", placeholder:"Year" }
                        ]
                    },
                    {
                        view:"list",
                        template:"#title# - #year#", // which data to show
                        select:true, //enables selection
                        height:400,
                        data:[
                            { id:1, title:"The Shawshank Redemption", year:1994 },
                            { id:2, title:"The Godfather", year:1972 },
                            { id:3, title:"The Godfather: Part II", year:1974 },
                            { id:4, title:"The Good, the Bad and the Ugly", year:1966 },
                            { id:5, title:"My Fair Lady", year:1964 },
                            { id:6, title:"12 Angry Men", year:1957 }
                        ]
                    }
                ]
            }
        ]
    });

    So here is my BANano_Ready to generate same...

    Code:
    Sub BANano_Ready()
        Dollar.Initialize(
    "$$")
        pg.Initialize(
    "mashy")
        pg.Content.TypeOf = 
    "line"
        
    '*** define row 1
        'add toolbar
        Dim R1 As WixRow
        R1.Initialize(
    "R1")
        
    'R1.Template = R1.ID
     
        
    Dim hdr As WixHeader
        hdr.Initialize(
    "hdr""My First Webix App")
        R1.AddItem(hdr.Item)
     
        
    Dim tblBar As WixToolBar
        tblBar.Initialize(
    "tblBar")
        tblBar.AddButton(
    "btnSave","Save",70, BANano.CallBack(Me,"save_row",Null))
        tblBar.AddButton(
    "btnDelete""Delete"70, BANano.CallBack(Me,"delete_row",Null))
        tblBar.AddButton(
    "btnClear""Clear"95, BANano.CallBack(Me,"clear_form",Null))
        R1.AddItem(tblBar.Item)
        
    'add rows to the page
        pg.AddRow(R1)
     
        
    Dim R2 As WixRow
        R2.Initialize(
    "R2")
     
        
    Dim R2C1 As WixColumn
        R2C1.Initialize(
    "R2C1")
        
    'R2C1.Template = R2C1.ID
     
        
    'add form
        myForm.Initialize(Dollar, "myform",300)
        myForm.AddTextBox(
    "title","Title",280,"left")
        myForm.AddTextBox(
    "year""Year",280,"left")
        R2C1.AddItem(myForm.Item)
        
    'add r2c1 to row
        R2.AddColumn(R2C1)
     
        
    Dim R2C2 As WixColumn
        R2C2.Initialize(
    "R1C2")
        
    'R2C2.Template = R2C2.id
        'add a list
     
        
    Dim filmset As List
        filmset.Initialize
        filmset.Add(CreateMap(
    "id":1"title":"The Shawshank Redemption""year":1994))
        filmset.Add(CreateMap(
    "id":2"title":"The Godfather""year":1972))
        filmset.Add(CreateMap(
    "id":3"title":"The Godfather: Part II""year":1974))
        filmset.Add(CreateMap(
    "id":4"title":"The Good, the Bad and the Ugly""year":1966))
        filmset.Add(CreateMap(
    "id":5"title":"My Fair Lady""year":1964))
        filmset.Add(CreateMap(
    "id":6"title":"12 Angry Men""year":1957))
     
        
    Dim recID As String
        myList.Initialize(Dollar, 
    "myList")
        myList.Template = 
    "#title# - #year#"
        myList.EnableSelect = 
    True
        myList.Height = 
    400
        myList.data = filmset
        myList.onAfterSelect = BANano.CallBack(Me,
    "record_selected",Array(recID))
        
    '
        R2C2.AddItem(myList.Item)
        
    '
        R2.AddColumn(R2C2)
        
    '
        pg.AddRow(R2)
        
    '
        pg.UI
        
    'attach the select event
        myList.AttachAfterSelectEvent
    End Sub
     
    Last edited: Jul 19, 2019 at 3:52 PM
  2. Mashiane

    Mashiane Expert Licensed User

    The other event linking code was also just a breath of fresh air to try and link.

    Code:
    'a row is selected from the list
    Sub record_selected(id As String)
        
    'get the record from the list
        Dim record As Map = myList.GetItem(id)
        
    'assign record to the form
        myForm.SetValues(record)
    End Sub

    'the toolbar save button is clicked
    Sub save_row(e As BANanoEvent)
        
    'get values from the form
        Dim values As Map = myForm.GetValues
        
    'read the id for the record
        Dim recID As String = values.GetDefault("id","")
        
    If recID = "" Then
            
    'add to the list
            myList.Add(values)
        
    Else
            
    'update the list
            myList.Update(recID,values)
        
    End If
    End Sub

    'the toolbar delete button is clicked
    Sub delete_row(e As BANanoEvent)
        
    'get the selected iten
        Dim recID As String = myList.GetSelectedID
        
    If recID = "" Then Return
        
    'remove item from list
        myList.Remove(recID)
        
    'clear the form
        myForm.Clear
    End Sub

    'the toolbar clear button is clicked
    Sub clear_form
        
    'clear the form contents
        myForm.Clear
    End Sub
    These are linking the form to the list. The list was just automatically updated by Webix when we just fed it the data that it needed to process and defined the 'template' to display the data.

    One of my favourate things were these methods...@form level

    Code:
    'get the form contents
    Sub GetValues() As Map
        
    Dim values As Map = Dollar.Selector(ID).RunMethod("getValues",Null).result
        
    Return values
    End Sub

    'clear the form
    Sub Clear
        Dollar.Selector(
    ID).RunMethod("clear",Null)
    End Sub

    'set values
    Sub SetValues(values As Map)
        Dollar.Selector(
    ID).RunMethod("setValues",Array(values))
    End Sub
    Just calling built in methods on the library we are able to getValues, clear the form and setValues, off course just from a JSON object (i.e. map)

    On the list side...

    Code:
    'update an existing record
    Sub Update(recordID As String, record As Map)
        Dollar.Selector(
    ID).RunMethod("updateItem",Array(recordID,record))
    End Sub

    'get an item
    Sub GetItem(recordID As StringAs Map
        
    Dim values As Map = Dollar.Selector(ID).RunMethod("getItem",Array(recordID)).Result
        
    Return values
    End Sub

    'attach events after page is created
    Sub AttachAfterSelectEvent()
        Dollar.Selector(
    ID).RunMethod("attachEvent",Array("onAfterSelect",onAfterSelect))
    End Sub

    'remove an item
    Sub Remove(recID As String)
        
    If recID = "" Then Return
        Dollar.Selector(
    ID).RunMethod("remove",Array(recID))
    End Sub

    'get the selected item id
    Sub GetSelectedID As String
        
    Dim recID As String = Dollar.Selector(ID).RunMethod("getSelectedId",Null).Result
        
    Return recID
    End Sub
    These methods were just a marvel. The idea of not writing loops and creating HTML elements to create the UX was just too cool. So I'm thinking, if I'm really serious about speed in development of app, this is one option I should look for in these frameworks.
     
  3. Mashiane

    Mashiane Expert Licensed User

    If one took a look at the WixHeader class, there is really nothing fancy and its basic as it gets, off course I have not taken a deep look into this whole big monster.

    Code:
    #IgnoreWarnings:12
    Sub Class_Globals
        
    Public ID As String
        
    Public Header As WixElement
    End Sub

    'initialize the header
    Public Sub Initialize(sID As String, sTitle As String)
        
    ID = sID.tolowercase
        Header.Initialize(
    ID)
        Header.View = 
    "template"
        Header.TypeOf = 
    "header"
        Header.Template = sTitle
    End Sub

    Sub Item As Map
        
    Return Header.item
    End Sub
    In all classes that I have created, they have a base class that I have named WixElement. That base class is nothing more other than just lists and maps variables.

    Code:
    #IgnoreWarnings:12
    Sub Class_Globals
        
    Public ID As String
        
    Public Template As String
        
    Public Columns As List
        
    Public Width As Int
        
    Public Height As Int
        
    Public Rows As List
        
    Private Element As Map
        
    Public Value As String
        
    Public Elements As List
        
    Public Name As String
        
    Private Attributes As Map
        
    Public View As String
        
    Public TypeOf As String
    End Sub

    'initialize the element
    Public Sub Initialize(sID As String)
        
    ID = sID.ToLowerCase
        Width = 
    0
        Height = 
    0
        Element = CreateMap(
    "id":ID)
        Value = 
    ""
        Name = 
    ""
        Rows.Initialize
        Elements.Initialize
        Columns.Initialize
        
    Attributes.Initialize
    End Sub

    'set an attribute
    Sub SetAttr(attrName As String, attrValue As Object)
        SetOnContent(attrName,attrValue)
    End Sub

    'return the object
    Sub Item As Map
        SetOnCondition(Height,
    "height",Height)
        SetOnCondition(Width, 
    "width", Width)
        SetOnContent(
    "type", TypeOf)
        SetOnContent(
    "view"View)
        SetOnContent(
    "name", Name)
        SetOnContent(
    "value", Value)
        SetOnContent(
    "template", Template)
        SetOnCondition(Columns.Size,
    "cols", Columns)
        SetOnCondition(Rows.Size, 
    "rows", Rows)
        SetOnCondition(Elements.Size, 
    "elements", Elements)
        
    For Each attr As String In Attributes.Keys
            
    Dim strVal As Object = Attributes.Get(attr)
            Element.Put(attr,strVal)
        
    Next
        
    Return Element
    End Sub

    'add item to a column
    Sub AddColumnItem(itm As Map)
        Columns.Add(itm)
    End Sub

    'add item to a row
    Sub AddRowItem(itm As Map)
        Rows.Add(itm)
    End Sub

    'add on elements
    Sub AddElementItem(itm As Map)
        Elements.Add(itm)
    End Sub

    'update property when not blank
    private Sub SetOnContent(Prop As String, PropValue As String)
        
    If PropValue = "" Then Return
        Element.put(Prop,PropValue)
    End Sub

    'update property when size > 0
    private Sub SetOnCondition(Condition As Int, Prop As String, PropValue As Object)
        
    If Condition <= 0 Then Return
        Element.put(Prop,PropValue)
    End Sub
    So far I have not written a single HTML element definition or written any javascript. Now that I love!

    #LetMeExploreSomeMore
     
  4. astronald

    astronald Member Licensed User

    Hello mashiane thanks for your wonderful work,
    how i can change locale to "es-ES"

    i found this function

    Code:
    webix.i18n.setLocale("es-ES");
    but i don't know how call this.

    Grateful.... Ronald.
     
    joulongleu and Mashiane like this.
  5. swamisantosh

    swamisantosh Member Licensed User

    #LetMeExploreSomeMore

    It should be Let Me Explore Something new.........for the beginner
     
    joulongleu and Mashiane like this.
  6. Mashiane

    Mashiane Expert Licensed User

    Thanks I will investigate and revert back to you.
     
    astronald and joulongleu like this.
  7. Mashiane

    Mashiane Expert Licensed User

    Nice... eventually ended up with more lessons than I anticipated but it’s been all good.

    Hopefully my not so first language and not so home language English is understandable. Ha ha ha.

    #BornNative
     
    joulongleu likes this.
  8. jackywuqiang

    jackywuqiang New Member Licensed User

    Hello mashiane thanks for your wonderful work,
    i open BANanoWebixDemo index.html page,but can't display real content,i open the console ,find the error message:
    --------------------------------------------------------------------------------------
    Uncaught ReferenceError: banano_bananowebix_wixpage is not defined
    at new banano_bananowebixdemo_pglesson8_3 (app1562248754592.js:8)
    at app1562248754592.js:6
    --------------------------------------------------------------------------------------
    error in the flowing line:
    function banano_bananowebixdemo_pglesson8_3() {var _B;this._pg= new banano_bananowebix_wixpage();

    How to solve the problem?
    thanks.

    library information:
    BANano 3.09
    BANanoWebix 1.01
     
    Mashiane and joulongleu like this.
  9. Mashiane

    Mashiane Expert Licensed User

    Funny I'm not sure what the issue could be, anyway, let me recompile another version and post it?

    Lesson8_3.png

    I never want to make ICT people excuses of 'it works on my side'. :rolleyes: Lol.

    Version 1.02 is now available.
     
    Last edited: Jul 4, 2019
    joulongleu likes this.
  10. Mashiane

    Mashiane Expert Licensed User

    @astronald I have added a method for you to be able to do this.

    Code:
    'set locale
    Sub SetLocale(locale As StringAs WixPage
        
    Dim i18n As BANanoObject = webix.GetField("i18n")
        i18n.RunMethod(
    "setLocale"Array(locale))
        
    Return Me
    End Sub
    So after you initialize your WixPage element, just call

    Code:
    pg.SetLocale("es-ES")
    This has been done in this lesson and also tested with setting the date format of one of the columns.

    Ta!
     
    joulongleu and astronald like this.
  11. micro

    micro Well-Known Member Licensed User

    Hi mashiane, thank's for you work.
    I have compiled the last version of BANanoWebix (1.02)
    but the problem is the same of the jackywuqiang.
    Can you post the library compiled?
     
    Mashiane likes this.
  12. Mashiane

    Mashiane Expert Licensed User

    Done, please get Version 1.03 here

    Are you using B4J version 7.51 and are your paths configured correctly?

    I am using jdk1.8.0_201 for this still hey.. :)
     
    joulongleu likes this.
  13. astronald

    astronald Member Licensed User

    Thanks very much.

    I invite the coffee
     
    Mashiane likes this.
  14. micro

    micro Well-Known Member Licensed User

    me too
    Other error in compilation with your last b4xlib
    upload_2019-7-5_7-29-28.png
     
  15. Mashiane

    Mashiane Expert Licensed User

    Do you mind if we run an AnyDesk session? you can start it on your side and pm me the session number. I'm really not sure what is happening.

    Ohh, with the latest version

    WixTextBox has been renamed to WixText for consistency with Webix, sorry man!
     
  16. micro

    micro Well-Known Member Licensed User

    Ok, Now work.
    In lesson 8.3 this error (files not present)
    I can't export table in xls, pdf and png.

    upload_2019-7-5_8-28-20.png
     
  17. jackywuqiang

    jackywuqiang New Member Licensed User

    Mashiane likes this.
  18. micro

    micro Well-Known Member Licensed User

  19. Mashiane

    Mashiane Expert Licensed User

    Please ensure you are connected to the internet. I have not added any offline functionality for this yet.
     
  20. Mashiane

    Mashiane Expert Licensed User

    BANAnoWebix 1.04+ Updates

    After careful consideration, it will no longer be necessary to add the unflatten code for the following items after the last .AddItem() call.

    • Menu
    • SideBar
    • ContextMenu
    • GroupList
    • SideBar
    • Tree
    • TreeTable

    REMOVED CODE IS LIKE

    Code:
    Dim items As List = sm.Items
        
    Dim data As List = pg.Unflatten(items,"data")
        sm.SetData(data)
    This code had the effect of generating a tree from flat data. This is now done automatically after the items are added with the .AddItem method for these components.
     
    swamisantosh and joulongleu like this.
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