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

Ola

**NB: BANanoPostProcessor: The BP used in some of the examples is an updated version of what Kiffi did in the forum. The examples are old and have not been maintained due to time challenges as the focus has been to maintain the core library and other things. Due to enhancements in BANano, this means you can un-reference it and comment out the code that uses it for BANanoWebix. This will not have any effect on your app.

Here are the revised procedures...

Step 1:
Download BANano

Step 2:
Download Webix GPL License - OpenSource or
Download Webix Pro Trial Version

Step 3:
Download BANanoWebix

3.1 Copy the contents of the 1. Libraries folder to your B4J external libraries

3.2. From your Webix download, copy the webix.js and webix.css files to the Files folder of the BANanoWebix project folder

3.3 Open BANanoWebix project and run it in release mode (DO NOT COMPILE TO LIBRARY) and ensure BANanoWebix.b4xlib is created! This will be stored in your additional libraries folder

bananowebix.png


Step 4

Open BANanoWebixApp, this should have the project references established and run it in release mode.

bananowebixapp.png


5. On execution, the web-browser should be opened with the localhost file. Your b4j logs will have some details, this is normal. It might look like this..

logs.png


From the Demos, I have selected charts. I am running a laragon webserver. You can also publish to Xamp. The Chrome Web-browser does not support PHP thus Im not using it for tests.

DemoCharts.png


Congrats, you have setup BANanoWebix for use!

Using BANanoWebix

New: BANanoWebix App Creation Process

webix.png


Development Servers you can use

1. XAMPP
2. Laragon

The 32 bit version of laragon is available here, https://sourceforge.net/projects/laragon/files/releases/4.0/laragon-wamp.x86.exe

Reproduction:


If you are using XAMP, comment out the line that publishes to laragon on Main.AppStart

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    Publish = "C:\xampp\htdocs"
    Publish = "C:\laragon\www"

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



An Object Oriented UX library for BANano [BANanoWebix]
Show a progressbar on long processes [BANanoWebix]
WixPivot on PRO [OffTopic] [BANanoWebix]
App Creation Process: The BackEnd with BANanoSQL [BANanoWebix]
App Creation Process: The UI [BANanoWebix]
Creating a Multi-Page Interface in a SPA [BANanoWebix]
Creating Multi-Page Apps - Part 1 [BANanoWebix]
Creating Multi-Page Apps - Part 2 [BANanoWebix]
Creating Multi-Page Apps - Part 3 [BANanoWebix]
Creating Multi-Page Apps - Part 4 [BANanoWebix]
Creating Multi-Page Apps - Part 5 [BANanoWebix]
Creating the Form Designer CRUD Backend BANanoSQL DB [BANanoWebix]
Dragging N Dropping Things with the Form Designer [BANanoWebix]
Form Builder / Designer [BANanoWebix]
Lesson 1 - Understanding the layout of a Webix SPA [BANanoWebix]
Lesson 2: Understanding the 6 layout types [BANanoWebix]
Lesson 3: Let's create some accordions [BANanoWebix]
Lesson 4: Carousels, MultiView & TabView [BANanoWebix]
Lesson 5: Creating ToolBars [BANanoWebix]
Lesson 6.X Form Validation [BANanoWebix]
Lesson 6: Form Data Entry Elements [BANanoWebix]
Lesson 7: Charts - Part 1 [BANanoWebix]
Lesson 8.1 The DataTable/DataGrid [BANanoWebix]
Lesson 8.2. The DataTable/DataGrid [BANanoWebix]
Lesson 8.3 Datatable Pagination & Exporting to XLSX, PNG, PDF and CSV [BANanoWebix]
Lesson 8.4 Enhanced Data-Table [BANanoWebix]
Lesson 9: DataView [BANanoWebix]
Lesson 10 Lists [BANanoWebix]
Lesson 11 Unit List [BANAnoWebix]
Lesson 12: Property Sheet [BANanoWebix]
Lesson 13 The TreeView [BANanoWebix]
Lesson 14 - The TreeTable [BANanoWebix]
Lesson 15 Menus & Windows [BANanoWebix]
Lesson 16 - The Sidebar [BANanoWebix]
Lesson 17 - Comments / Chat Widget [BANanoWebix]
Lesson 18 GroupList [BANanoWebix]
Lesson 19 Contexts [BANanoWebix]
Lesson 20 Google Map [BANAnoWebix]
Lesson 21 TabBar [BANanoWebix]
Lesson 22 - Method 3 [DropZone] [BANanoWebix]
Lesson 22 Uploader - Method 1 [BANanoWebix]
Lesson 22 Uploader Method 2 [BANanoWebix]
Lesson 23 WixVideo [BANanoWebix]
Lesson 24 ScrollView [BANanoWebix]
Lesson 25 Template [BANanoWebix]
Lesson 28 Suggestions [BANanoWebix]
Lesson 29 MessageBoxes [BANanoWebix]
Lesson 30 WixHints [BANanoWebix]
Lesson 31 WixImage [BANanoWebix]


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.

B4X:
BP.UnzipFonts
    BP.UnzipFile("extras.zip")

2. On the page where you will use exporting, after page initialize

B4X:
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.

B4X:
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...

B4X:
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:

Mashiane

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

B4X:
'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

B4X:
'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...

B4X:
'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 String) As 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.
 

Mashiane

Expert
Licensed User
Longtime 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.

B4X:
#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.

B4X:
#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
 

astronald

Active Member
Licensed User
Longtime User
Hello mashiane thanks for your wonderful work,
how i can change locale to "es-ES"

i found this function

B4X:
webix.i18n.setLocale("es-ES");

but i don't know how call this.

Grateful.... Ronald.
 

Mashiane

Expert
Licensed User
Longtime User
#LetMeExploreSomeMore

It should be Let Me Explore Something new.........for the beginner
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
 

jackywuqiang

New Member
Licensed User
Longtime 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

Expert
Licensed User
Longtime User
how i can change locale to "es-ES"
@astronald I have added a method for you to be able to do this.

B4X:
'set locale
Sub SetLocale(locale As String) As 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

B4X:
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!
 

micro

Well-Known Member
Licensed User
Longtime 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

Expert
Licensed User
Longtime User
me too
Other error in compilation with your last b4xlib
View attachment 81872
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!
 

Mashiane

Expert
Licensed User
Longtime 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

B4X:
    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.
 
Top