B4J Tutorial [BANanoVuetifyAD3] Create Professional Looking Vuetify WebSites & WebApps with BANano

Ola

**************************************************
Feb 2024: BVAD3 RoadMap

*************************************************

Download Additional Libraries
Download BANanoVuetifyAD3Core Library OR Download BANanoVuetifyAD3 Library
Download Kitchen Sink WebApp (Optional - useful for Learning how this works)
Download BVAD3Builder (Optional - useful to trim your final package)

Full Install Instructions on Github

What's New

To use this free and open source B4J library, you need BANano.

IMPORTANT: BANano License

Join Us

Telegram: https://t.me/bananovuematerial
Twitter: https://twitter.com/mashymbanga
Discord: https://discord.gg/ys8stGgWCU
YouTube: Mashy Teaches Video Series
B4x Blog: Mashy Teaches BVAD3 - New Series
Full Demo: New Awesome Kitchen Sink

Notable Forum Members Contributions

@Erel : Obviously
@alwaysbusy : valuable advice etc, BANano (incl. adjustments that support BVAD3)
@LJG : BANanoServer jRDC2, best overall bug finder
@aeric: Recommendations & Enhancements etc
@Star-Dust : Small solutions to development hitches etc
More...


What's Next?

You will find the most up to date content from this post onwards

Testing DataBase Connectivity (PHP)

The kitchen sink now has connectity testing for the various backends. To ensure that your app will work, you can check if your back-end is accessible.

MySQL
SQLite
MSSQL

WebServers You Can Use

Laragon - publish to c:\laragon\www



USBWebServer
IIS - Publish to C:\inetpub\wwwroot
XAMPP - change your publish folder to use // instead of \

You can find more information here related to IDE Setup

Enjoy

PS: Log Warnings & Compilation Errors

1. Please check the pre-run logs. In most cases modules with warnings will have an underline. Warning, 9, 10, 11, 12 are normal, don't be scared.

1625825241311.png


2. manifext.txt file not found - Download the library source code and RUN to recompile on your PC. "Do not Compile to Library"
3. Do a HARD REFRESH of your browser.[/B]
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
It is with pleasure to release the first Awesome Kitchen Sink for BVAD3

For more details, follow this link...

 

Mashiane

Expert
Licensed User
Longtime User
Tip: Life Cycle Hooks

VueJS uses a methodology called life cycle hooks. That is to say before a Vue instance fully runs, you can inject code to run.

For example, to load data to a combo box from a database, you can do this on the created / mounted life cycle hooks.

There are further discussed here, https://vuejs.org/v2/guide/instance.html

To see this work, in the kitchen sink code, in pgIndex, we have defined an onmounted hook, this clears the drawer and feeds the item. We also did a similar task with the bottom nav bar, we created a hook to clear the items and then create them. This means that each time one navigates to the page, the hook is called and executes the code.

For each VuetifyApp and VueComponent, we have defined methods to handle these... Internally these are defined as

B4X:
'set mounted
Sub SetMounted(Module As Object,methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim mounted As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("mounted", mounted)
    SetMethod(Module, methodName, args)
    Return Me
End Sub

'set updated
Sub SetUpdated(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim updated As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("updated", updated)
    SetMethod(Module, methodName, args)
    Return Me
End Sub

'set beforemount
Sub SetBeforeMount(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim beforeMount As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("beforeMount", beforeMount)
    SetMethod(Module, methodName, args)
    Return Me
End Sub

'set beforeupdate
Sub SetBeforeUpdate(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim beforeUpdate As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("beforeUpdate", beforeUpdate)
    SetMethod(Module, methodName,args)
    Return Me
End Sub

'set before destroy
Sub SetBeforeDestroy(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim beforeDestroy As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("beforeDestroy", beforeDestroy)
    SetMethod(Module, methodName, args)
    Return Me
End Sub


'set before created
Sub SetBeforeCreate(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim beforeCreate As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("beforeCreate", beforeCreate)
    SetMethod(Module, methodName, args)
    Return Me
End Sub


'set created
Sub SetCreated(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim created As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("created", created)
    SetMethod(Module, methodName, args)
    Return Me
End Sub

'set destroyed
Sub SetDestroyed(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim destroyed As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("destroyed", destroyed)
    SetMethod(Module, methodName, args)
    Return Me
End Sub


'set activated
Sub SetActivated(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim activated As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("activated", activated)
    SetMethod(Module, methodName, args)
    Return Me
End Sub


'set deactivated
Sub SetDeActivated(Module As Object, methodName As String, args As List) As VueComponent
    methodName = methodName.ToLowerCase
    If SubExists(Module, methodName) = False Then Return Me
    Dim deactivated As BANanoObject = BANano.CallBack(Module, methodName, args)
    opt.Put("deactivated", deactivated)
    SetMethod(Module, methodName, args)
    Return Me
End Sub

Enjoy!
 
  • Like
Reactions: LJG

Mashiane

Expert
Licensed User
Longtime User
TIPS

  1. The pgIndex code module is used to set up the skeleton shell of your application. Here you create the AppBar, NavDrawer, Footer and the Router View.
  2. You can have an app without a Drawer or AppBar or Footer.
  3. Your App has to have a VApp and VMain elements, this is compulsory and should be the first 2 elements in your app.
  4. If your app will have multiple "pages", use the router view inside vmain
  5. The BVADEDS B4xtemplate has the skeleton template to create a new app with a drawer, app bar, vmain and router views.
  6. The Router View shows other pages in your application when you navigate to it.
  7. Each page is treated as a separate vue component i.e. vue instance.
  8. Each page is defined inside a code module, this is done inside the .Initialize subroutine. There you load your page layout, specify events etc.
  9. Each element is created on an abstract designer and that is loaded inside a component.
  10. Each element for your layout should be .BindVueElement after loadlayout so that VueComponent knows about its events and state bindings.
  11. You can initialize state binding data for your app by creating a .SetCreated method that will be called each time one navigates to the page. This can be used to load data to combo-boxes and other data bound elements like trees etc.
  12. The value of an element is bound to the v-model, each v-model should be unique per element that is on your component.
  13. To change and get the values at runtime, you use <element>.SetValue(<component>, <newvalue>) and to get a value use, <element>.GetValue(<component>)
  14. To hide and show elements, you need to specify the v-show state variable first, then you will be able to run <element>.UpdateVisible for each element.
  15. If elements have the same v-model or v-show, each time you change those with .SetValue and .UpdateVisible, all the elements that share the same state variable names will be affected.
  16. Most elements have events, use Generate Members from the abstract designer to generate events. The callbacks are built internally by BVAD3 as soon as it detects that the event signature exists in your component.
  17. To enable and disable an element at runtime, call .UpdateDisabled(?, ?), you can pass this true / false.
  18. Your Webapp can only have 1 VAPP and 1 VMain component. This is compulsory.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
TIP: Page Transitions

In the kitchen sink, the router-view sits inside a VTransition component. This is an optional matter as you can just have a router-view sitting inside v-main.
This has been added because of page transitions. You can change how the pages transition during navigation by changing the transition choice from the dropdown.

PageTransitions.jpg
 

Mashiane

Expert
Licensed User
Longtime User
TIP: BANanoMySQL usage

Check this out on examples of how to use the BANanoMYSQLE class. This is already built into BVAD3, so dont recopy.

 

Mashiane

Expert
Licensed User
Longtime User
BANanoVuetifyAD3 Version 5.25 is now available.

This comes with the New Awesome Kitchen Sink WebApp where one can explore all the elements created purely with the abstract designer. This is more than 60 pages demonstrating each element from the power of the library. Just like you would a normal b4x app, you use the abstract designer, generate events and you are good to go in creating your awesome webapp.

As a bonus, this also comes with a new dashboard, the Cloud Inventory Dashboard Clone, as discussed above to help anyone learn along

We have made some simple notes here too

Enjoy and have fun and thanks for supporting this project!!!

Mashy!

PS: Also an eBook for those in a hurry was written to create CRUD based WebApps, find it here:

 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
TIP: Detecting changes on AutoComplete/Combo/Select components in a data-table.

When you define a column as autocomplete, combo or select in a data-table, you can detect changes made to it. For example, in this spippet, our table is called, datasource. It sources content from a saved state list.

During runtime we want to detect changes made on that column so that we can perform other actions.

Adding the column to tha data-table

B4X:
tablecrud.AddColumn("datasource", "ForeignTable")
    tablecrud.SetAutoComplete("datasource", True, "tables", "tablename", "tablename")

B4X:
'the data source has been changed
Private Sub tablecrud_datasource_Change (item As String)
    'selected table
    item = item.trim
    If item = "" Then Return
    tablecrud.UpdateLoading(True)
    'get the active database
    activeDB = vuetify.GetData("database")
    sdatabasename = activeDB.Get("databasename")
    
    Dim rsFields As BANanoMySQLE 
    rsFields.Initialize("bvad3crud", "fieldnames", "fieldid", "fieldid") 
    'add field types 
    rsFields.SchemaAddInt(Array("tableid"))
    '
    Dim sw As Map = CreateMap()
    sw.Put("databasename", sdatabasename)
    sw.Put("tablename", item)
    '
    rsFields.SelectWhere(Array("fieldname"), sw, Array("=", "="), Array("fieldname")) 
    rsFields.JSON = banano.CallInlinePHPWait(rsFields.MethodName, rsFields.Build) 
    rsFields.FromJSON 
    Select Case rsFields.OK 
    Case False 
        Dim strError As String = rsFields.Error 
        Log(strError) 
    End Select 
    home.SetData("fieldnames", rsFields.result)
    tablecrud.UpdateLoading(False) 
End Sub
 
Top