B4J Question [BANAnoVuetifyAD3] VueTable

LJG

Member
Is it possible to change the data in a VueTable without re-populating the whole VueTable? I understand that each row entry in the BANAnoVuetifyAD3 VueTable is an Item and can have an ItemKey. But how do I access a specific row in a VueTable to change one or more fields in that row?

For a simple example from one of the tutorials, let's say that I have a VueTable with the following setup.

VueTable:
vetable.AddColumn1("name", "Dessert (100g Serving", vetable.COLUMN_TEXT, 0, True, vetable.ALIGN_LEFT)
vetable.AddRow(CreateMap("name": "Frozen Yogurt", "calories": 159, "color":"green", "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": "1%"))
tables.BindVueTable(vetable)

If I make "name" the ItemKey, how do I change the "calories" field in the first row from 159 to 200 without having to recreate the whole table? I assume that I would use SetData or some other method to do that but I could not find an example.

Thank you for your help.
 

Mashiane

Expert
Licensed User
Longtime User
Hi LJG

Is it possible to change the data in a VueTable without re-populating the whole VueTable?
Yes definately. create your table and then you can add rows during runtime.

how do I access a specific row in a VueTable to change one or more fields in that row?

This is currently not implemented, I will update you soon on its availability.

The easiest choice is.

1. Get the underlying data of the vuetable with .GetData, this returns an array of objects
2. Update the underlying array of objects using something like a where clause. This updates the affected records in the List.
3. The VueTable is updated in real-time without a refresh.

NB: This does not update any back-end database.

Also note that it you make a property an itemKey, you cannot use the inline editing functionality for that column. This is a Vuetify Limitation.
 
Reactions: LJG
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
Just checked, here are the runtime methods. These do not affect the backe-end.

1. Add Row at runtime use, .AddItem
2. Remove Row at position X at runtime, use, .RemoveItemAtPosition
3. Remove an item where p=? at runtime, use .RemoveItem("name", "LJG")
4. Update an item where p=? at runtime, use, .UpdateItem("name", "LJG", createmap())
5. Updating an item at runtime, use. UpdateItemAtPosition
6. Finding an item, use .FindItem
7. Find an item position, use .FindItemPosition

positions are 0 index based.

I have never tested these before though, just implemented them. They are not built in vuetify methods but just using basic javascript array methods with the state.

DO NOT execute .Refresh when you use these methods.
 
Reactions: LJG
Upvote 0

LJG

Member
Thanks Mashiane, but these methods did not work.

I'm going to try to use another Vuetify component to display the data that I need to be updated on a real-time basis. Thanks for your help, as always, much appreciated.
 
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
Hi

In this example, we are adding records each 2 seconds... as you can see the table is not refreshed but appended to



The table with the column names and headings is created via the abstract designer. Here is the code for example

B4X:
'Static code module
Sub Process_Globals   
    Public vuetify As VuetifyApp
    Public home As VueComponent
    Public path As String
    Public name As String = "home"
    Private banano As BANano
    Private VCol1 As VCol
    Private VCol2 As VCol
    Private VContainer1 As VContainer
    Private VRow1 As VRow
    Private VueTable1 As VueTable
    Private mint As Int
End Sub

Sub Initialize
    'establish a reference to the app
    vuetify = pgIndex.vuetify
    'initialize the component
    home.Initialize(Me, name)
    home.vuetify = vuetify
    'make this the start page
    home.Path = "/"
    path = home.path
    '
    'build the page html here
    banano.LoadLayout(home.Here, "mytable")
   
    'IMPORTANT
    VueTable1.ParentComponent = home
   
    home.BindVueTable(VueTable1)
   
    home.SetMounted(Me, "starttimer", Null)
    'add this route component to the app
    vuetify.AddRoute(home)
End Sub   

Sub starttimer
    'clear the table
    VueTable1.clear
    mint = home.SetInterval("addmenu", 1000, Null)
End Sub

Sub addmenu
    Dim nr As Map = CreateMap()
    nr.Put("name", "Frozen Yogurt")
    nr.Put("calories", 159)
    nr.Put("fat", 6.0)
    nr.Put("carbs", 24)
    nr.Put("protein", 4.0)
    nr.Put("iron", "1%")
    VueTable1.AddItem(nr)
End Sub

NB: I will update the library after I have checked these methods.
 
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
This one demonstrates how a record is changed, for example, its added and then after a few seconds its changed in realtime.

We use the same example as before but just added an id column to make the records unique,

See the calogies data changing..




B4X:
'Static code module
Sub Process_Globals    
    Public vuetify As VuetifyApp
    Public home As VueComponent
    Public path As String
    Public name As String = "home"
    Private banano As BANano
    Private VCol1 As VCol
    Private VCol2 As VCol
    Private VContainer1 As VContainer
    Private VRow1 As VRow
    Private VueTable1 As VueTable
    Private mint As Int
    Private id As Int
    Private changeint As Int
End Sub

Sub Initialize
    'establish a reference to the app
    vuetify = pgIndex.vuetify
    'initialize the component
    home.Initialize(Me, name)
    home.vuetify = vuetify
    'make this the start page
    home.Path = "/"
    path = home.path
    '
    'build the page html here
    banano.LoadLayout(home.Here, "mytable")
    
    'IMPORTANT
    VueTable1.ParentComponent = home
    
    home.BindVueTable(VueTable1)
    
    home.SetMounted(Me, "starttimer", Null)
    'add this route component to the app
    vuetify.AddRoute(home)
End Sub    

Sub starttimer
    'clear the table
    VueTable1.clear
    id = 0
    mint = home.SetInterval("addmenu", 2000, Null)
    changeint = home.SetInterval("changeit", 3000, Null)
End Sub

Sub addmenu
    id = id + 1
    Dim nr As Map = CreateMap()
    nr.Put("id", id)
    nr.Put("name", "Frozen Yogurt")
    nr.Put("calories", 159)
    nr.Put("fat", 6.0)
    nr.Put("carbs", 24)
    nr.Put("protein", 4.0)
    nr.Put("iron", "1%")
    VueTable1.AddItem(nr)
    '
    
    'get all added records
    Dim recs As List = VueTable1.GetData
    'how many records do we have
    If recs.Size = 5 Then
        'stop adding records
        home.ClearInterval(mint)
        home.ClearInterval(changeint)
    End If
End Sub

Sub changeit
    'change calories with random number 
    Dim rndnum As Int = Rnd(0, 250)
    VueTable1.UpdateItem("id", id, CreateMap("calories": rndnum))
End Sub
 
Reactions: LJG
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
This last example is for deletes. The reason the rest of the other examples worked like that is because data was saved in a database and assuming a multi-user environment, one would want to get the latest updates.

Also this example is based on the previous ones, we just added another interval.



Here is the code

B4X:
'Static code module
Sub Process_Globals    
    Public vuetify As VuetifyApp
    Public home As VueComponent
    Public path As String
    Public name As String = "home"
    Private banano As BANano
    Private VCol1 As VCol
    Private VCol2 As VCol
    Private VContainer1 As VContainer
    Private VRow1 As VRow
    Private VueTable1 As VueTable
    Private mint As Int
    Private id As Int
    Private changeint As Int
    Private deleteit As Int
End Sub

Sub Initialize
    'establish a reference to the app
    vuetify = pgIndex.vuetify
    'initialize the component
    home.Initialize(Me, name)
    home.vuetify = vuetify
    'make this the start page
    home.Path = "/"
    path = home.path
    '
    'build the page html here
    banano.LoadLayout(home.Here, "mytable")
    
    'IMPORTANT
    VueTable1.ParentComponent = home
    
    home.BindVueTable(VueTable1)
    
    home.SetMounted(Me, "starttimer", Null)
    'add this route component to the app
    vuetify.AddRoute(home)
End Sub    

Sub starttimer
    'clear the table
    VueTable1.clear
    id = 0
    mint = home.SetInterval("addmenu", 5000, Null)
    changeint = home.SetInterval("changeit", 6000, Null)
    deleteit = home.SetInterval("deleteit1", 7000, Null)
End Sub

Sub addmenu
    id = id + 1
    Dim nr As Map = CreateMap()
    nr.Put("id", id)
    nr.Put("name", "Frozen Yogurt")
    nr.Put("calories", 159)
    nr.Put("fat", 6.0)
    nr.Put("carbs", 24)
    nr.Put("protein", 4.0)
    nr.Put("iron", "1%")
    VueTable1.AddItem(nr)
    '
    
    'get all added records
    Dim recs As List = VueTable1.GetData
    'how many records do we have
    If recs.Size = 5 Then
        'stop adding records
        home.ClearInterval(mint)
        home.ClearInterval(changeint)
        home.ClearInterval(deleteit)
    End If
End Sub

Sub changeit
    'change calories with random number 
    Dim rndnum As Int = Rnd(0, 250)
    VueTable1.UpdateItem("id", id, CreateMap("calories": rndnum))
End Sub

Sub deleteit1
    'change calories with random number 
    Dim rndnum As Int = Rnd(1, 5)
    VueTable1.RemoveItem("id", rndnum)
End Sub

Whilst we have used a timer here, there is nothing limiting one to implement this based on the edit, delete buttons that exists. One can read the while details into the data-table, make changes and then resave everything back.

I will update the library soon so that you can use these features.

Ta!
 
Reactions: LJG
Upvote 0

LJG

Member
Thank you, Mashiane!

I am currently working on a project that requires real-time updates from a large MSSQL database. This VueTable update is a big deal and will help a lot of people develop even more remarkable web apps … the fun way.

I also noted that you added chartkick to BANanoVuetifyAD3 … amazing, thank you.

Hopefully, later, you will be able to add a Leaflet map to the BANanoVuetifyAD3 library with the same ability to be updated in real time (e.g., to show moving vehicles on a map based on changing lat and longs, etc). I think Leaflet is best for mapping because, unlike Google maps, it is opensource and, I believe, we can use our own maps (which would also be interesting to learn how to do). I was able to get a Leaflet map in my BANanoVuetifyAD3 project but it would be nicer if it was built in the awesome BANanoVuetifyAD3 library.

I will also be experimenting to see how we can get this incredible library fully working in BANanoServer. Still hoping to see this in the near future. Thanks again, and keep up the good work!
 
Upvote 0

LJG

Member
The VueTable real time update is working great. But I was wondering … is it possible to also change the text color of a single field text entry using the same method? I know that we can use chips in a table that can be color coded, but is it possible to change the color of a single item text entry within a row?

Thanks
 
Upvote 0

roberto64

Active Member
Licensed User
Longtime User
hello, I would like to understand where I am wrong, it does not show me the data in the grid.
Greetings
VueTable1:
Sub starttimer
    'clear the table
    Dim dbSQLite As BANanoSQLiteE
    dbSQLite.Initialize("./assets/Rubrica.db", "RubricaSms", "IdRubrica", "IdRubrica")
    dbSQLite.SchemaAddInt(Array("IdRubrica"))
    dbSQLite.SelectAll(Array("IdRubrica","Cognome","Nome","Indirizzo"), Array("cognome"))
    dbSQLite.JSON = banano.CallInlinePHPWait(dbSQLite.MethodName, dbSQLite.Build)
    dbSQLite.FromJSON
    Select Case dbSQLite.OK
        Case False
            Dim strError As String = dbSQLite.Error
            vuetify.ShowSnackBarError("Si è verificato un errore durante l'esecuzione del comando.. " & strError)
            Return
        Case Else
            vuetify.ShowSnackBarSuccess("Sucesso")
    End Select
    Dim jsonUsers As String = banano.ToJson(dbSQLite.result)
'    Log(jsonUsers)

    VueTable1.clear
'    Dim rec As Map = CreateMap()
    For Each rec As Map  In dbSQLite.Result
        Dim nr As Map = CreateMap()
'        Log(rec.Get("IdRubrica"))
'       
        rec.put("idrubrica",rec.Get("idrubrica"))
        rec.put("cognome",rec.Get("cognome"))
        rec.put("nome",rec.Get("nome"))
        rec.put("Indirizzo",rec.Get("Indirizzo"))
'        rec.Get("Comune")
'        rec.Get("InizioContratto")
'        rec.Get("ScadenzaContratto")
'       
'         Log(m.Size)
        VueTable1.AddItem(rec)
'        Log(rec.Get("Cognome"))
'        Log(nr)
    Next
'    VueTable1.clear
    
    Dim recs As List = VueTable1.GetData
'    Log(recs)
    
'    If recs.Size = 5 Then
'        Log(rec.Get("Cognome"))
'    End If
'    id = 0
'    addmenu(rec)
'    mint = home.SetInterval("addmenu", 5000, Null)
'    changeint = home.SetInterval("changeit", 6000, Null)
'    deleteit = home.SetInterval("deleteit1", 7000, Null)
End Sub
 
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
Thanks, can I ask you for a little bit of time please. Currently our DataSource does not support SQLite but jRDC (testing phase) and MySQL. I plan to add it tonight.

For you i think I would rather you just have a working example based on the new direction that our tools are taking. If I update this, I will have to go back and forth and redo it once again using the DataSource and VueTable. As soon as I am done, i will update you.

Thanks.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…