B4J Library [BANano] UOEGridTable: An interesting grid that you might like

Discussion in 'B4J Libraries & Classes' started by Mashiane, Apr 25, 2019.

Tags:
  1. Mashiane

    Mashiane Expert Licensed User

    Ola

    Seemingly I'm getting closer to my app goal for my next project, so here is something for the community again. A grid and there some very few things I like about it too. This is a wrap for this project here.

    Quick Reference

    ShowCase: Header Filters (onchange / onkeypress events)

    UOEFilter.gif

    Full Table

    UOENowGrid.png

    This is what you get:

    1. Sortable columns
    2. Table title
    3. Table headers themeable with css
    3. DropDown
    4. Checkbox
    5. Pager (limits, number of pages etc)
    6. Many interesting events and methods..

    It's also possible to set the custom view designer properties when using the designer.

    UOENowGridDesigner.png

    Ok, let me help you to succeed. Let's look at the definition of the component. This is based on gijgo again.

    UOENowGridTable
    • Cancel (pk As String)
      cancel operation for primary key
    • SetDataSource (rows As List) As UOENowGridTable
      set data source
    • GetRecordFromEvent (e As BANanoEvent) As Map
      get record from event
    • SetColumnGroupBy (colField As String) As UOENowGridTable
      set columns to group by
    • SetColumnEditors (colField As List) As UOENowGridTable
      set columns editors
    • SetColumnModeReadOnly (colField As List) As UOENowGridTable
      set columns editor mode to readonly
    • SetColumnModeEditOnly (colField As List) As UOENowGridTable
      set columns editor mode to editor only
    • SetColumnDataSource (colField As String, colDataSource As Object, colValueField As String, colEditField As String) As UOENowGridTable
      set columns data source for dropdown
    • GetByPos (rowPos As Int) As Map
      get data for primary key
    • GetRowsVisible() As List
      get all visible rows data
    • GetRows() As List
      get all rows data
    • GetById (id As String) As Map
      get data by id
    • SearchFor (searchValues As Map)
      search the grid, use a map that has the field names and values to search for
    • Reload
      reload, if autoload is false
    • Clear
      clear the data
    • HideColumn (colName As List)
      hide columns via code
    • ShowColumn (colField As List)
      show columns via code
    • RemoveRow (pk As String)
      remove a row by id
    • CountVisible As Int
      count visible records
    • CountAll As Int
      count all records
    • Refresh As UOENowGridTable
      refresh the grid
    • UpdateRow (rowData As Map)
      update an existing row of data
    • AddColumn (colName As String, colTitle As String, colType As String, colWidth As Int, colSortable As Boolean, colAlign As String) As UOENowGridTable
      add a column
    • AddIcon (colField As String, colTitle As String, colIcon As String, colWidth As String, colAlign As String)
      add Icon
    • AddIconEdit (colField As String, colTitle As String, colWidth As String, colAlign As String)
      add edit icon
    • AddIconDelete (colField As String, colTitle As String, colWidth As String, colAlign As String)
      add delete icon
    • AddTemplate (colField As String, colTitle As String, colTemplate As String, colWidth As String, colSortable As Boolean, colAlign As String)
      add template
    • SetColumnTmpl (colName As String, coltmpl As String) As UOENowGridTable
      set the column data template
    • SetColumnClickEvent (colField As String, stopPropagation As Boolean)
      set column click event
    • SetColumnEvent (colField As String, colEvent As String, stopPropagation As Boolean)
      set column event
    • SetColumnMinWidth (colField As String, colMinWidth As Int, colPriority As Int) As UOENowGridTable
      set the column min width
    • GetSelected As String
      get selected record id
    • GetSelections As List
      get all selected record ids
    • SelectAll
      select all records
    • UnSelectAll
      un-select all records
    • ExpandAll
      expand all records
    • CollapseAll
      collapse all records
    • SetSelected (rowPos As Int)
      set a selection
    • SetColumnName (colField As String, colName As String) As UOENowGridTable
      set the column name
    • SetColumnToolTip (colName As String, colToolTip As String) As UOENowGridTable
      set the column tooltip
    • SetColumnStopPropagation (colName As String, colStopPropagation As Boolean) As UOENowGridTable
      set the column stop probagation for events
    • GetChanges As List
      get changed records on table for only changed fields and primary key
    • SetColumnIcon (colName As String, colIcon As String) As UOENowGridTable
      set the column icon
    • SetColumnHidden (colName As String) As UOENowGridTable
      set column visibility
    • SetColumnSortable (colName As String, colSortable As Boolean) As UOENowGridTable
      set column sortable
    • AddRow (rowData As Map)
      add a row dynamically
    • DownloadCSV (fileName As String)
      download data as csv
    • GetCSV
      get data as csv
    • SetColumnItalic (colName As String) As UOENowGridTable
      set header italic
    • SetColumnHeaderCSS (colName As String, headerCssClass As String) As UOENowGridTable
      set header css
    • SetColumnFilterable (colName As String, colFilter As Boolean) As UOENowGridTable
      set column filterable
    • SetColumnCSS (colName As String, colCSS As String) As UOENowGridTable
      set the column class
    • SetColumnFormat (colName As String, colFormat As String) As UOENowGridTable
      set the column data format
    • Destroy
      removes all data and events and keep table and wrapper
     

    Attached Files:

    Last edited: Apr 29, 2019
    SNOUHyhQs2, amaxco, Don Oso and 7 others like this.
  2. Mashiane

    Mashiane Expert Licensed User

    To add the grid, one needs to use the abstract designer and then generate the necessary events needed. Lets journey ahead.

    Let's define the structure of the grid first by defining the columns and their attributes.

    Code:
    'define the columns
        uoegrid.PrimaryKey = "id"
        uoegrid.AddColumn(
    "id","#",uoegrid.COLUMN_TEXT, 56False, uoegrid.ALIGN_CENTER)
        uoegrid.AddColumn(
    "Name","Name",uoegrid.COLUMN_TEXT, 0True, uoegrid.ALIGN_LEFT)
        
    'make the column header italic
        uoegrid.SetColumnItalic("Name")
        
    'set the column tooltip
        uoegrid.SetColumnToolTip("Name","Full name of player.")
        uoegrid.AddColumn(
    "CountryName","Country Name",uoegrid.COLUMN_DROPDOWN,200,True,uoegrid.ALIGN_LEFT)
        uoegrid.AddColumn(
    "PlaceOfBirth","Place of Birth",uoegrid.COLUMN_TEXT, 0True, uoegrid.ALIGN_LEFT)
        uoegrid.AddColumn(
    "DateOfBirth","Date of Birth", uoegrid.COLUMN_DATE,150,False,uoegrid.ALIGN_CENTER)
        
    'set the column data format
        uoegrid.SetColumnFormat("DateOfBirth","dd.mm.yyyy")
        
    'uoegrid.AddColumn("tmpl","Template", uoegrid.COLUMN_String,0,False,uoegrid.ALIGN_LEFT)
        uoegrid.AddColumn("IsActive","Active?",uoegrid.COLUMN_CHECKBOX,80,False,uoegrid.ALIGN_CENTER)
        
    'add buttons
        uoegrid.AddMaterialEdit("EditRecord","",64, uoegrid.ALIGN_CENTER)
        uoegrid.SetColumnClickEvent(
    "EditRecord",True)
        uoegrid.AddMaterialDelete(
    "DeleteRecord","",64, uoegrid.ALIGN_CENTER)
        uoegrid.SetColumnClickEvent(
    "DeleteRecord",True)
    The assumption here is that the data to be loaded will be read directly from a database. By using an AddColumn method, it means we can easily add and remove column definitions anytime we want as each column is individually defined. This improves code maintenance too. The grid needs to have a primarykey which will be used to identify each unique record in the grid. Each column is linked to a field in our database records, thus we identify these, their titles, the widths, whether sortable or not and their alignment.

    After we have added the column definitions, we also add action buttons and add click events for the two, being edit / delete buttons. One can then write their code to manage that as each click event returns the record being accessed.
     
    Johan Schoeman, fredo and joulongleu like this.
  3. Mashiane

    Mashiane Expert Licensed User

    The next phase of the example is adding records. When reading records from a db, these will be returned as JSON string, basically meaning these will be a list of map records, each with field definitions and values. The data in this example is dependent of a countries list and is being referenced by the players records. All of this can be read from a database and then added to the UOEGrid.

    Code:
    Dim countries As List
        countries.Initialize
        countries.Add(CreateMap(
    "id":18"text""Bulgaria"))
        countries.Add(CreateMap(
    "id":12"text""Brazil"))
        countries.Add(CreateMap(
    "id":16"text""England"))
        countries.Add(CreateMap(
    "id":17"text""Germany"))
        countries.Add(CreateMap(
    "id":19"text""Poland"))
        countries.Add(CreateMap(
    "id":14"text""Colombia"))
        countries.Add(CreateMap(
    "id":15"text""South Africa"))
        uoegrid.SetColumnDataSource(
    "CountryName", countries, "id""CountryID")
          
        
    'add the datasource
        Dim dataSource As List
        dataSource.Initialize
        dataSource.Add(CreateMap(
    "id"1"Name""Hristo Stoichkov""PlaceOfBirth""Plovdiv, Bulgaria","DateOfBirth":"/Date(-122227200000)/","IsActive":False,"CountryID":18,"CountryName""Bulgaria"))
        dataSource.Add(CreateMap(
    "id"2"Name""Ronaldo Luis Nazario de Lima""PlaceOfBirth""Rio de Janeiro, Brazil""DateOfBirth":"/Date(211878000000)/","IsActive":False,"CountryID":12,"CountryName""Brazil"))
        dataSource.Add(CreateMap(
    "id"3"Name""David Platt""PlaceOfBirth""Chadderton, Lancashire, England","DateOfBirth":"/Date(-112122000000)/","IsActive":False,"CountryID":16,"CountryName""England"))
        dataSource.Add(CreateMap(
    "id"4"Name""Manuel Neuer""PlaceOfBirth""Gelsenkirchen, West Germany""DateOfBirth":"/Date(512294400000)/""IsActive":True"CountryID":17"CountryName""Germany"))
        dataSource.Add(CreateMap(
    "id"5"Name""James Rodríguez""PlaceOfBirth""Cúcuta, Colombia""IsActive":True"CountryName""Colombia","DateOfBirth":"/Date(349689600000)/","CountryID":14))
        dataSource.Add(CreateMap(
    "id"6"Name""Dimitar Berbatov""PlaceOfBirth""Blagoevgrad, Bulgaria""IsActive":False"CountryName""Bulgaria","DateOfBirth":"/Date(349689600000)/","CountryID":18))
        dataSource.Add(CreateMap(
    "id"7"Name""Robert Lewandowski""PlaceOfBirth""Warsaw, Poland""DateOfBirth":"/Date(588150000000)/""CountryID":19"CountryName""Poland""IsActive":True))
        uoegrid.SetDataSource(dataSource).Refresh
        
    'add a row dynamically
        uoegrid.AddRow(CreateMap("id"8"Name""Mashy""PlaceOfBirth""East London, Eastern Cape""DateOfBirth":"/Date(588150000000)/""CountryID":15"CountryName""South Africa""IsActive":True))
    We first define the countries records. These have id and text fields. For this component, when referencing such data, one needs to give the description field to be text, thus, id and text for the countries records.

    Then we build the example data as if it will be sourced directly from the database, as individual records (maps). We have text boxes, a dropdown, a checkbox etc. The records are added to the grid and the grid is refreshed.

    To demonstrate adding records dynamically to the grid without a complete record reload, we have added an .AddRow call after refresh.

    SetDataSource is a memory list and its compulsory that after adding records this way, one does a refresh. With .AddRow, one does not have to do a refresh as records are added as and when they are added to the grid after the last added record. The structure of the added record should meet the column definition with the exception of the Edit/Delete buttons.

    For the dropdown, we have added a column called CountryName on the grid. The countryname is linked to the countryid. To establish this link, we call SetColumnDataSource specifying the column that will display the country name as CountryName, from the countries source. The value field on the countries list is 'id' and this will be linked as CountryID on the table. Yes, I noted, a little data redudancy here for this to be effective.
     
    Johan Schoeman, fredo and joulongleu like this.
  4. Mashiane

    Mashiane Expert Licensed User

    We have a couple of events that we have added. These are...

    Code:
    #Event: RowDataBound (e As BANanoEvent, row As Object, id as Object, record As Object)
    #Event: RowRemoving (e As BANanoEvent, row As Object, id as Object, record As Object)
    #Event: RowSelect (e As BANanoEvent, row As Object, id as Object, record As Object)
    #Event: RowUnSelect (e As BANanoEvent, row As Object, id as Object, record As Object)
    #Event: CellDataChanged (e As BANanoEvent, cell As Object, column As Object, record As Object, newValue As Object)
    #Event: RowDataChanged (e As BANanoEvent, id As Object, record As Object)
    #Event: Click (e As BANanoEvent)
    These do different things as per their definitions..

    Code:
    Sub uoegrid_click(e As BANanoEvent)
        
    Dim record As Map = uoegrid.GetRecordFromEvent(e)
        
    Log(record)
    End Sub


    Sub uoegrid_CellDataChanged (e As BANanoEvent, cell As Object, column As Object, record As Object, newValue As Object)
        
    'Log(cell)
        'Log(column)
        'Log(record)
        'Log(newValue)
    End Sub

    Sub uoegrid_RowDataChanged (e As BANanoEvent, id As Object, record As Object)
        
    Log(record)
    End Sub


    Sub uoegrid_RowDataBound (e As BANanoEvent, row As Object, id As Object, record As Object)
        
    'Log(record)
    End Sub

    Sub uoegrid_RowRemoving (e As BANanoEvent, row As Object, id As Object, record As Object)
        
    'Log("row removed")
        'Log(record)
    End Sub

    Sub uoegrid_RowSelect (e As BANanoEvent, row As Object, id As Object, record As Object)
        
    'Log("row selected")
        'Log(record)
    End Sub

    Sub uoegrid_RowUnSelect (e As BANanoEvent, row As Object, id As Object, record As Object)
        
    'Log("row un-selected")
        'Log(record)
    End Sub
    The click event for edit and delete will return the record being accessed. One can write their own code to handle that.
     
    Johan Schoeman, fredo and joulongleu like this.
  5. Mashiane

    Mashiane Expert Licensed User

    On the designer, there are some settings that one can set to make the grid work for them.

    Code:
    #DesignerProperty: Key: Width, DisplayName: Width, FieldType: Int, DefaultValue: 0, Description: Width
    #DesignerProperty: Key: PagerLimit, DisplayName: PagerLimit, FieldType: Int, DefaultValue: 10, Description: Pager Width, List: 5|10|15|20|25|30|35|40|45|50
    #DesignerProperty: Key: PrimaryKey, DisplayName: PrimaryKey, FieldType: String, DefaultValue: id, Description: PrimaryKey
    #DesignerProperty: Key: AutoLoad, DisplayName: AutoLoad, FieldType: Boolean, DefaultValue: True, Description: AutoLoad
    #DesignerProperty: Key: BodyRowHeight, DisplayName: BodyRowHeight, FieldType: String, DefaultValue: autogrow, List: fixed|autogrow
    #DesignerProperty: Key: SelectionType, DisplayName: SelectionType, FieldType: String, DefaultValue: single, List: single|multiple
    #DesignerProperty: Key: ColumnReorder, DisplayName: ColumnReorder, FieldType: Boolean, DefaultValue: True, Description: ColumnReorder
    #DesignerProperty: Key: KeepExpandedRows, DisplayName: KeepExpandedRows, FieldType: Boolean, DefaultValue: False, Description: KeepExpandedRows
    #DesignerProperty: Key: FixedHeader, DisplayName: FixedHeader, FieldType: Boolean, DefaultValue: False, Description: FixedHeader
    #DesignerProperty: Key: HeaderFilter, DisplayName: HeaderFilter, FieldType: Boolean, DefaultValue: False, Description: HeaderFilter
    #DesignerProperty: Key: HeaderFilterType, DisplayName: HeaderFilterType, FieldType: String, DefaultValue: onchange, List: onchange|onenterkeypress
    #DesignerProperty: Key: ResizableColumns, DisplayName: ResizableColumns, FieldType: Boolean, DefaultValue: False, Description: ResizableColumns
    #DesignerProperty: Key: ShowHiddenColumnsAsDetails, DisplayName: ShowHiddenColumnsAsDetails, FieldType: Boolean, DefaultValue: False, Description: ShowHiddenColumnsAsDetails
    #DesignerProperty: Key: Title, DisplayName: Title, FieldType: String, DefaultValue: , Description: Title
    #DesignerProperty: Key: RowReorder, DisplayName: RowReorder, FieldType: Boolean, DefaultValue: False, Description: RowReorder
    #DesignerProperty: Key: SelectionMethod, DisplayName: SelectionMethod, FieldType: String, Description: SelectionMethod, DefaultValue: checkbox, List: checkbox|basic
    For example, RowReorder enables one to drag and drop rows where ever in the grid.
    ColumnRecorder enables one to move columns whilst FixedHeader ensures that your header does not scroll where many records are concerned.
     
    Johan Schoeman, fredo and joulongleu like this.
  6. Mashiane

    Mashiane Expert Licensed User

    One of the things I like about this grid is the possibility to ensure that when you want to select All Records, you can change the selection methods and selection types and a checkbox column avails itself. This you can easily do on the designer.

    UOESelection.png
     
    Johan Schoeman, fredo and joulongleu like this.
  7. Mashiane

    Mashiane Expert Licensed User

    With just one line of code, you easily activate inline editing that uses built in components to render, date picker, dropdown and input controls.

    Code:
    uoegrid.SetColumnEditors(Array("Name","PlaceOfBirth","DateOfBirth","IsActive","CountryName"))
    UOEInlineEditing.png

    For inline editing, you can trap the RowChanged event to get record fields that have changed and update your records.
     
    Johan Schoeman and joulongleu like this.
  8. Mashiane

    Mashiane Expert Licensed User

    I also needed to group my players by country of birth including detailed information about the place of birth. This was easily done by specifying a grouping field and also the detailed template.

    Code:
    uoegrid.DetailTemplate = $"<div style="text-align: left"><b>Place Of Birth:</b> {PlaceOfBirth}</div>"$
        uoegrid.SetColumnGroupBy(
    "CountryName")
    And this resulted in..

    UOEGroupBy.png

    Providing collapsible content that I can easily expand and collapse as per need. With DownloadCSV, the content of the grid is directly exported to Excel CSV without any dependencies.

    Enjoy

    Ta!

    PS: As this is a custom component, you are welcome to do as you please with it as the source is attached. I only effected the necessary stuff for use in my project and shared to help others succeed. If you find it useful all the better.
     
    Last edited: Apr 25, 2019
    Johan Schoeman and joulongleu like this.
  9. joulongleu

    joulongleu Active Member

    :)UoeGrid is very glad,When push Checkbox The following error occurred ::)
    file:///C:/Users/joulo/DOWNLO~1/UOEGrid/BANANO~1/Objects/UOETreeView/fonts/gijgo-material.ttf?235541 net::ERR_FILE_NOT_FOUND
     
    Last edited: Apr 25, 2019
    Mashiane likes this.
  10. Mashiane

    Mashiane Expert Licensed User

    Thanks for pointing this out, please download the font files from the repo, https://github.com/atatanasov/gijgo, they are under the dist/combined/fonts folder. I will also test on my side. I appreciate your feedback, thanks.
     
    joulongleu likes this.
  11. joulongleu

    joulongleu Active Member

    Yes,Thank You :)
    Two other questions:
    1.uoegrid.Title how to center?
    2. In addition to edit, delete how to use select icon?
     
    Mashiane likes this.
  12. GanjaKyp

    GanjaKyp Member

    It's perfect, thanks!
    How to reload grid with changed DataSource?
     
    Mashiane and joulongleu like this.
  13. Mashiane

    Mashiane Expert Licensed User

    There is a method to pass your own css to the header however I don’t think I added it. You can check their docs. What you can do is create your own container and use LoadLayout to load the grid inside that container that can have your own controls. I will check it later for you though.
     
    joulongleu likes this.
  14. Mashiane

    Mashiane Expert Licensed User

    There are two methods to load the data sources, one for a combo field, just run the methods again passing updated lists of records. There should be a clear method, I’m not infront of my laptop now I will check it for you later.

    I think it’s SetDataSource and SetColumnDataSource. Remember to also run the .Refresh method.
     
    joulongleu likes this.
  15. GanjaKyp

    GanjaKyp Member

    I try to update with timer, but table doesn't changed

    Code:
    Sub Timer_Tick
    BANano.GetElement(
    "#countvisible").SetText(DateTime.Time(DateTime.Now))
    Dim json As BANanoJSONParser
    json.Initialize(BANano.CallAjaxWait(
    "http://10.20.2.7:88/crmset.aspx?query=exec call_list 1556301600000,0,'Все менеджеры'""GET""jsonp"""FalseNull))
    uoegrid.SetDataSource(json.NextArray).Refresh
    End Sub
     
  16. Mashiane

    Mashiane Expert Licensed User

    Edit and delete do the same function of getting the record in question, you can then define your own code to manipulate them. There is a RemoveRow method that you can pass the id of the record though. You will have to add your own confirmation dialog if needed and link the deleted record back to your datasource and thus the underlying database.

    The removerow has an event where you can trap the record removal and then expand. I will work on an example to showcase such CRUD functionality with an dB soon for you.
     
    joulongleu likes this.
  17. joulongleu

    joulongleu Active Member

    :)I am looking forward,CRUD functionality Can with PHP? Thank You.
     
  18. swamisantosh

    swamisantosh Member Licensed User

  19. Mashiane

    Mashiane Expert Licensed User

    joulongleu likes this.
  20. swamisantosh

    swamisantosh Member Licensed User

    thanks...option to print
     
    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