B4J Tutorial [BANanoWebix] Creating a Multi-Page Interface in a SPA

Discussion in 'B4J Tutorials' started by Mashiane, Jul 2, 2019.

  1. Mashiane

    Mashiane Expert Licensed User

    Ola

    The latest release of BANanoWebix features a sidebar that when selected, it displays 'different pages' within the same 'index.html file.

    LessonMP.gif

    At the heart of every BANano based App, there is the '#body' element of a page. Initially this is blank and one needs to feed content to it to create their app. This 'body' element is created automatically by BANano and that is what needs to be generated.

    BANano has a BANanoElement class, this works like document.getElementByID(???) or jquerys $('#???') calls, so to get the body element one could....

    Code:
    Dim EL As BANanoElement = BANano.GetElement("#body")
    This will get the element by id 'body' and enable it to be fed HTML content. To just assume that we were adding a paragraph , one would execute....

    Code:
    EL.Append("<p>This is my first paragraph!</p>")
    and also add any other HTML they need to make the page alive. This happens in runtime so no other methods should be called to make it work.

    Now, assuming that you wanted to show something totally different on the body tag, let's assume an image, you will have to clear the body tag and then overwrite it.

    Code:
    'clear the body tag
    EL.Empty
    'write something else
    EL.Append("<img src='image.png' alt='This is an image'/>
    This will have the effect of 'deleting' everything that was in the body and now creating the image there.

    Thus to create multiple-pages on this SPA framework, one just overwrites the body tag like this over and over again, maybe perhaps a function call or a button click.

    The approach followed by webix is similar. Whilst I could replace the complete body tag, we did'nt want to over-write the 'shell' contents of the page i.e. toolbar, sidebar etc, we just wanted to have the middle body of the page replaced.

    So we did the following:

    1. Created the page and the toolbar and told our lib that we want everything on the page to be rendered on the element with id = body.

    Code:
    pg.Initialize("forms""body").SetTypeSpace("")
        
    '
        Dim R1 As WixRow
        R1.Initialize(
    "R1")
        
    'add toolbar
        Dim tblBar As WixToolBar
        tblBar.Initialize(
    "tblBar")
        tblBar.CreateIcon(
    "menuopen").SetIcon("mdi mdi-menu").SetClick(BANano.CallBack(Me, "OpenMenu"Null)).Pop
        tblBar.CreateLabel(
    "heading").SetLabel("BANanoWebix - A Webix Wrapper for BANano").Pop
        tblBar.setPadding(
    3)
        R1.AddRows(tblBar.Item)
    2. We then added the sidebar with its parent and child buttons. This has a click event so that we pick up which id is selected. On each element click, we just render the code module page that is generated to a specific div, in this case, r2c2_content

    Code:
    Dim sm As WixSideBar
        sm.Initialize(
    "sm").SetPositionRight("").SetCollapsed(False).SetActiveTitle(True).SetScroll(True)
        
    '
        sm.AddItem("""layouts""L1-L3 Layouts","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "layouts""lesson1""Lesson 1","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "layouts""lesson2""Lesson 2","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "layouts""lesson3_1""Lesson 3.1","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "layouts""lesson3_2""Lesson 3.2","","mdi mdi-view-dashboard""","")
        
    '
        sm.AddItem("""multiview""L4 MultiView","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """toolbar""L5 ToolBar","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """dataentry1""L6 Data Entry","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "dataentry1""dataentry""L6 Data Entry","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "dataentry1""forms1""Forms 1","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "dataentry1""forms2""Forms 2","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """charts""L7 Charts","","mdi mdi-view-dashboard""","")
        
    '
        sm.AddItem("""datatable""L8 DataTable","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "datatable""lesson8_1""Lesson 8.1","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "datatable""lesson8_2""Lesson 8.2","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "datatable""lesson8_3""Lesson 8.3","","mdi mdi-view-dashboard""","")
        
    '
        sm.AddItem("""dataview""L9 DataView","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """lists""L10-L11 Lists","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "lists""list""L10 List","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "lists""unitlist""L11 Unit List","","mdi mdi-view-dashboard""","")
        
    '
        sm.AddItem("""property""L12 Property Sheet""""mdi mdi-table""","")
        
    '
        sm.AddItem("""trees""L13-L14 Trees","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "trees""treeview""L13 Tree","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "trees""treedata""L14 Tree Data","","mdi mdi-view-dashboard""","")
        
    '
        sm.AddItem("""menu""L15 Menu""""mdi mdi-table""","")
        sm.AddItem(
    """sidebar""L16 Side Bar""""mdi mdi-table""","")
        sm.AddItem(
    """comments""L17 Comments""""mdi mdi-table""","")
        sm.AddItem(
    """grouplist""L18 Group List","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """context""L19 Contexts""""mdi mdi-table""","")
        sm.AddItem(
    """gmap""L20 GoogleMap""""mdi mdi-table""","")
        sm.AddItem(
    """tabbar""L21 Tab Bar""""mdi mdi-table""","")
        sm.AddItem(
    """uploader""L22 Uploader""""mdi mdi-table""","")
        sm.AddItem(
    "uploader""lesson22_1""L22.1 Upload Grid","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "uploader""lesson22_2""L22.2 Linked List","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    "uploader""lesson22_3""L22.3 Drop Zone","","mdi mdi-view-dashboard""","")
        
    '
        sm.AddItem("""lesson23""L23 Video","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """lesson24""L24 Scroll View","","mdi mdi-view-dashboard""","")
        sm.AddItem(
    """lesson25""L25 Template","","mdi mdi-view-dashboard""","")
      
        
    Dim items As List = sm.Items
        
    Dim data As List = pg.Unflatten(items,"data")
        sm.SetData(data)
    3. We then created a normal HTML div element and placed it as a 'template' inside one of our WixElements. We want that div to fit its parents so we apply some inline styling to set the width and height to 100%.

    Code:
    Dim R2C2 As WixElement
        R2C2.Initialize(
    "R2C2")
        
    Dim div As UOENowHTML
        div.Initialize(
    "r2c2_content","div").SetStyle("width","100%").SetStyle("height","100%")
        R2C2.SetTemplate(div.HTML)
        
    '
        R2.AddColumns(R2C2.item)
    The name of this div is r2c2_content. So each time an item in the sidebar is clicked, we want it to be rendered on this container div.

    4. After the page is rendered, we add an item click to the side menu so that we can trap each item that is clicked.

    Code:
    pg.ui
        
    '
        Dim meid As Map
        pg.OnItemClick(
    "sm", BANano.CallBack(Me, "itemClick"Array(meid)))
    Now each time that happens, the code module or rather 'page' is generated in its entirety and rendered to r2c2_content due to the fact that each WixElement has a container attribute that you can indicate as to tell it which div to render the contents of that object based element to. This is done by the .SetContainer(???) call on the page.

    Code:
    Sub itemClick(meID As String)
        
    Select Case meID
        
    Case "lesson8_3"
            pgLesson8_3.Init(
    "r2c2_content")     
        
    Case "lesson24"
            pgScrollView.Init(
    "r2c2_content")
        
    Case "lesson25"
            pgTemplate.Init(
    "r2c2_content")
        
    Case "forms1"
            pgForms.Init(
    "r2c2_content")
        
    Case "forms2"     
            pgForms1.Init(
    "r2c2_content")
        
    Case "lesson23"
            pgVideo.Init(
    "r2c2_content")
        
    Case "lesson22_1"
            pgUploader1.Init(
    "r2c2_content")
        
    Case "lesson22_2"
            pgUploader2.Init(
    "r2c2_content")
        
    Case "lesson22_3"
            pgUploader3.Init(
    "r2c2_content")
        
    Case "tabbar"
            pgTabBar.Init(
    "r2c2_content")
        
    Case "gmap"
            pgGoogleMap.Init(
    "r2c2_content")
        
    Case "context"
            pgContext.Init(
    "r2c2_content")
        
    Case "comments"
                pgComments.Init(
    "r2c2_content")
        
    Case "sidebar"
            pgSideBar.Init(
    "r2c2_content")
        
    Case "menu"
            pgMenu.Init(
    "r2c2_content")
        
    Case "treeview"
            pgTree.Init(
    "r2c2_content")
        
    Case "treedata"
            pgTreeTable.Init(
    "r2c2_content")
        
    Case "property"
            pgPropertySheet.Init(
    "r2c2_content")
        
    Case "grouplist"
            pgGroupList.Init(
    "r2c2_content")
        
    Case "unitlist"
            pgUnitList.Init(
    "r2c2_content")
        
    Case "list"
            pgList.Init(
    "r2c2_content")
        
    Case "dataview"
            pgDataView.Init(
    "r2c2_content")
        
    Case "lesson8_1"
            pgDataTable.Init(
    "r2c2_content")
        
    Case "lesson8_2"
            pgDataTable1.Init(
    "r2c2_content")
        
    Case "charts"
            pgCharts.Init(
    "r2c2_content")
        
    Case "lesson1"
            pgLayout.Init(
    "r2c2_content")
        
    Case "lesson2"
            pgLayouts.Init(
    "r2c2_content")
        
    Case "lesson3_1"
            pgLayouts1.init(
    "r2c2_content")
        
    Case "lesson3_2"
            pgLayouts2.init(
    "r2c2_content")
        
    Case "multiview"
            pgMultiView.Init(
    "r2c2_content")
        
    Case "toolbar"
            pgToolBar.Init(
    "r2c2_content")
        
    Case "dataentry"
            pgDataEntry.Init(
    "r2c2_content")     
        
    End Select
    End Sub
    The Page Initialization

    Code:
    'initialize the page and empty the page '#body' element
    Public Sub Initialize(pgID As String, pgContainer As StringAs WixPage
        hints.Initialize
        Dollar.Initialize(
    "$$")
        
    ID = pgID.tolowercase
        webix.Initialize(
    "webix")
        
    Page.Initialize(ID)
        
    'init other stuff
        EnumButtonTypes.Initialize
        EnumLayoutTypes.Initialize
        EnumWixIcons.Initialize
        SetContainer(pgContainer)
        
    Return Me
    End Sub
    As noted above, this calls SetContainer, which calls the .Empty BANanoElement method and then set the container property of the Page (WixElement).

    Code:
    'set the container of the page
    Sub SetContainer(contID As StringAs WixPage
        contID = contID.tolowercase
        
    Dim sKey As String = "#" & contID
        
    Page.Container = contID
        BANano.GetElement(sKey).empty
        
    Return Me
    End Sub
    All of this in effect, clearing the div contents and then overwriting them each time a page is created, creating an 'illusion' that we have multiple-pages in our SPA.

    Ta
     
    Last edited: Jul 2, 2019
    joulongleu likes 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