One of the most asked for components in ABMaterial is an editable Grid. We already have ABMTable and ABMTableMutable, but they have their limitations when it comes to being editable. So, as this kind of object is huge, I suggest we make it a Team Effort to build one.
I did a look around and found a rather nice one jsGrid http://js-grid.com/ which is feature rich, easy to use and fits rather well with the ABMaterial look and feel.
I made the first part: modified the default CSS so it works with ABMaterial (checkboxes and combos did not work), created a basic start for the class and how to use it in a project.
Copy the CSS and JS files from the attachment into the css/custom/ and /js/custom/ folders of the ABMaterial www folder.
Start with localhost:51042/GridDemo
My current result looks like this (allows adding, deleting, changing, sorting and filtering):
The ABMTableGrid class (see also attachment):
Usage:
So this is were you guys can come in!
Some suggestions:
1. Adapt my class so the fields are generic (maybe by passing a Map with field definitions in initialize and then 'build' the correct JavaScript string in FirstRun.
2. I only set some basic parameters (like sorting, filtering etc), but this component has a lot more to offer. They can become properties of the class. See the jsGrid link at the top of this article.
And please share your changes in this topic, so everyone can profit from it!
Lets do this
I did a look around and found a rather nice one jsGrid http://js-grid.com/ which is feature rich, easy to use and fits rather well with the ABMaterial look and feel.
I made the first part: modified the default CSS so it works with ABMaterial (checkboxes and combos did not work), created a basic start for the class and how to use it in a project.
Copy the CSS and JS files from the attachment into the css/custom/ and /js/custom/ folders of the ABMaterial www folder.
Start with localhost:51042/GridDemo
My current result looks like this (allows adding, deleting, changing, sorting and filtering):
The ABMTableGrid class (see also attachment):
B4X:
'Class module
Sub Class_Globals
Public ABMComp As ABMCustomComponent
Private cmbCountries As String
Private DBdata As String
End Sub
'Initializes the object. Countries and data are Json Strings
Public Sub Initialize(InternalPage As ABMPage, ID As String, Countries As String, data As String)
ABMComp.Initialize("ABMComp", Me, InternalPage, ID)
cmbCountries = Countries
DBdata = data
End Sub
Sub ABMComp_Build(internalID As String) As String
Return $"<div id="${internalID}"></div><script>var _${internalID};</script>"$
End Sub
Sub ABMComp_FirstRun(InternalPage As ABMPage, internalID As String)
Dim script As String = $"_${internalID} = $("#${internalID}").jsGrid({
height: "100%",
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: {
loadData: function(filter) {
return $.grep(${DBdata}, function(client) {
var fName = filter.Name.toUpperCase();
var fAddress = filter.Address.toUpperCase();
return (!filter.Name || client.Name.toUpperCase().indexOf(fName) > -1)
&& (!filter.Age || client.Age === filter.Age)
&& (!filter.Address || client.Address.toUpperCase().indexOf(fAddress) > -1)
&& (!filter.Country || client.Country === filter.Country)
&& (filter.Married === undefined || client.Married === filter.Married);
});
},
insertItem: function(insertingClient) {
var json = JSON.stringify(insertingClient);
b4j_raiseEvent('${ABMComp.ID}_inserted', {'value':json});
},
updateItem: function(updatingClient) {
var json = JSON.stringify(updatingClient);
b4j_raiseEvent('${ABMComp.ID}_updated', {'value':json});
},
deleteItem: function(deletingClient) {
var json = JSON.stringify(deletingClient);
b4j_raiseEvent('${ABMComp.ID}_deleted', {'value':json});
}
},
fields: [
{ name: "Name", type: "text", width: 150 },
{ name: "Age", type: "number", width: 50 },
{ name: "Address", type: "text", width: 200 },
{ name: "Country", type: "select", items: ${cmbCountries}, valueField: "Id", textField: "Name" },
{ name: "Married", type: "checkbox", title: "Is Married", sorting: false},
{ type: "control" }
]
});"$
InternalPage.ws.Eval(script, Array As Object(ABMComp.ID))
' flush not needed, it's done in the refresh method in the lib
End Sub
public Sub SetDBData(data As String)
DBdata = data
End Sub
Sub ABMComp_Refresh(InternalPage As ABMPage, internalID As String)
Dim script As String = $"$("#${internalID}").jsGrid("refresh");"$
InternalPage.ws.Eval(script, Null)
End Sub
' do the stuff needed when the object is removed
Sub ABMComp_CleanUp(InternalPage As ABMPage, internalID As String)
End Sub
Usage:
B4X:
Sub Class_Globals
...
Dim myTableGrid As ABMTableGrid
' fake database for demo purposes
Dim database As Map
End Sub
' make sure you copied the files from the .zip in the right folders
public Sub BuildPage()
...
page.AddExtraCSSFile("custom/jsgrid.min.css")
page.AddExtraCSSFile("custom/jsgrid-theme.min.css")
page.AddExtraJavaScriptFile("custom/jsgrid.min.js")
...
End Sub
public Sub ConnectPage()
' connecting the navigation bar
' init all your own variables (like a List, Map) and add your components
' as for the demo, we fake a real database here
LoadFakeData
page.Cell(2,1).SetFixedHeight(500)
' for our combo, we add a Json string counting the countries
myTableGrid.Initialize(page, "myTableGrid", $"[
{ Name: "", Id: 0 },
{ Name: "United States", Id: 1 },
{ Name: "Canada", Id: 2 },
{ Name: "United Kingdom", Id: 3 },
{ Name: "France", Id: 4 },
{ Name: "Brazil", Id: 5 },
{ Name: "China", Id: 6 },
{ Name: "Russia", Id: 7 }
]"$, LoadData)
page.Cell(2,1).AddComponent(myTableGrid.ABMComp)
' refresh the page
page.Refresh
' Tell the browser we finished loading
page.FinishedLoading
' restoring the navigation bar position
page.RestoreNavigationBarPosition
End Sub
Sub LoadData() As String
' we have to return a Json string
Dim data As StringBuilder
data.Initialize
data.Append("[")
For i = 0 To database.size - 1
If i > 0 Then
data.Append(",")
End If
data.Append(database.get(i))
Next
data.Append("]")
Return data.ToString
End Sub
Sub myTableGrid_Inserted(value As Map)
End Sub
Sub myTableGrid_Updated(value As Map)
End Sub
Sub myTableGrid_Deleted(value As Map)
End Sub
Sub LoadFakeData()
database.Initialize
database.Put(0,$"{"ID": 0,"Name": "Otto Clay","Age": 61,"Country": 6,"Address": "Ap #897-1459 Quam Avenue","Married": false}"$)
database.Put(1,$"{"ID": 1,"Name": "Connor Johnston","Age": 73,"Country": 7,"Address": "Ap #370-4647 Dis Av.","Married": false}"$)
database.Put(2,$"{"ID": 2,"Name": "Lacey Hess","Age": 29,"Country": 7,"Address": "Ap #365-8835 Integer St.","Married": false}"$)
database.Put(3,$"{"ID": 3,"Name": "Timothy Henson","Age": 78,"Country": 1,"Address": "911-5143 Luctus Ave","Married": false}"$)
database.Put(4,$"{"ID": 4,"Name": "Ramona Benton","Age": 43,"Country": 5,"Address": "Ap #614-689 Vehicula Street","Married": true}"$)
database.Put(5,$"{"ID": 5,"Name": "Ezra Tillman","Age": 51,"Country": 1,"Address": "P.O. Box 738, 7583 Quisque St.","Married": true}"$)
database.Put(6,$"{"ID": 6,"Name": "Dante Carter","Age": 59,"Country": 1,"Address": "P.O. Box 976, 6316 Lorem, St.","Married": false}"$)
database.Put(7,$"{"ID": 7,"Name": "Christopher Mcclure","Age": 58,"Country": 1,"Address": "847-4303 Dictum Av.","Married": true}"$)
database.Put(8,$"{"ID": 8,"Name": "Ruby Rocha","Age": 62,"Country": 2,"Address": "5212 Sagittis Ave","Married": false}"$)
database.Put(9,$"{"ID": 9,"Name": "Imelda Hardin","Age": 39,"Country": 5,"Address": "719-7009 Auctor Av.","Married": false}"$)
database.Put(10,$"{"ID": 10,"Name": "Jonah Johns","Age": 28,"Country": 5,"Address": "P.O. Box 939, 9310 A Ave","Married": false}"$)
database.Put(11,$"{"ID": 11,"Name": "Herman Rosa","Age": 49,"Country": 7,"Address": "718-7162 Molestie Av.","Married": true}"$)
database.Put(12,$"{"ID": 12,"Name": "Arthur Gay","Age": 20,"Country": 7,"Address": "5497 Neque Street","Married": false}"$)
database.Put(13,$"{"ID": 13,"Name": "Xena Wilkerson","Age": 63,"Country": 1,"Address": "Ap #303-6974 Proin Street","Married": true}"$)
database.Put(14,$"{"ID": 14,"Name": "Lilah Atkins","Age": 33,"Country": 5,"Address": "622-8602 Gravida Ave","Married": true}"$)
database.Put(15,$"{"ID": 15,"Name": "Malik Shepard","Age": 59,"Country": 1,"Address": "967-5176 Tincidunt Av.","Married": false}"$)
database.Put(16,$"{"ID": 16,"Name": "Keely Silva","Age": 24,"Country": 1,"Address": "P.O. Box 153, 8995 Praesent Ave","Married": false}"$)
database.Put(17,$"{"ID": 17,"Name": "Hunter Pate","Age": 73,"Country": 7,"Address": "P.O. Box 771, 7599 Ante, Road","Married": false}"$)
database.Put(18,$"{"ID": 18,"Name": "Mikayla Roach","Age": 55,"Country": 5,"Address": "Ap #438-9886 Donec Rd.","Married": true}"$)
database.Put(19,$"{"ID": 19,"Name": "Upton Joseph","Age": 48,"Country": 4,"Address": "Ap #896-7592 Habitant St.","Married": true}"$)
database.Put(20,$"{"ID": 20,"Name": "Jeanette Pate","Age": 59,"Country": 2,"Address": "P.O. Box 177, 7584 Amet, St.","Married": false}"$)
database.Put(21,$"{"ID": 21,"Name": "Kaden Hernandez","Age": 79,"Country": 3,"Address": "366 Ut St.","Married": true}"$)
database.Put(22,$"{"ID": 22,"Name": "Kenyon Stevens","Age": 20,"Country": 3,"Address": "P.O. Box 704, 4580 Gravida Rd.","Married": false}"$)
database.Put(23,$"{"ID": 23,"Name": "Jerome Harper","Age": 31,"Country": 5,"Address": "2464 Porttitor Road","Married": false}"$)
database.Put(24,$"{"ID": 24,"Name": "Jelani Patel","Age": 36,"Country": 2,"Address": "P.O. Box 541, 5805 Nec Av.","Married": true}"$)
database.Put(25,$"{"ID": 25,"Name": "Keaton Oconnor","Age": 21,"Country": 1,"Address": "Ap #657-1093 Nec, Street","Married": false}"$)
database.Put(26,$"{"ID": 26,"Name": "Bree Johnston","Age": 31,"Country": 2,"Address": "372-5942 Vulputate Avenue","Married": false}"$)
database.Put(27,$"{"ID": 27,"Name": "Maisie Hodges","Age": 70,"Country": 7,"Address": "P.O. Box 445, 3880 Odio, Rd.","Married": false}"$)
database.Put(28,$"{"ID": 28,"Name": "Kuame Calhoun","Age": 39,"Country": 2,"Address": "P.O. Box 609, 4105 Rutrum St.","Married": true}"$)
database.Put(29,$"{"ID": 29,"Name": "Carlos Cameron","Age": 38,"Country": 5,"Address": "Ap #215-5386 A, Avenue","Married": false}"$)
database.Put(30,$"{"ID": 30,"Name": "Fulton Parsons","Age": 25,"Country": 7,"Address": "P.O. Box 523, 3705 Sed Rd.","Married": false}"$)
database.Put(31,$"{"ID": 31,"Name": "Wallace Christian","Age": 43,"Country": 3,"Address": "416-8816 Mauris Avenue","Married": true}"$)
database.Put(32,$"{"ID": 32,"Name": "Caryn Maldonado","Age": 40,"Country": 1,"Address": "108-282 Nonummy Ave","Married": false}"$)
database.Put(33,$"{"ID": 33,"Name": "Whilemina Frank","Age": 20,"Country": 7,"Address": "P.O. Box 681, 3938 Egestas. Av.","Married": true}"$)
database.Put(34,$"{"ID": 34,"Name": "Emery Moon","Age": 41,"Country": 4,"Address": "Ap #717-8556 Non Road","Married": true}"$)
database.Put(35,$"{"ID": 35,"Name": "Price Watkins","Age": 35,"Country": 4,"Address": "832-7810 Nunc Rd.","Married": false}"$)
End Sub
So this is were you guys can come in!
Some suggestions:
1. Adapt my class so the fields are generic (maybe by passing a Map with field definitions in initialize and then 'build' the correct JavaScript string in FirstRun.
2. I only set some basic parameters (like sorting, filtering etc), but this component has a lot more to offer. They can become properties of the class. See the jsGrid link at the top of this article.
And please share your changes in this topic, so everyone can profit from it!
Lets do this
Attachments
Last edited: