B4A Library [Class] Flexible Table

Discussion in 'Additional libraries, classes and official updates' started by melamoud, Jun 30, 2013.

  1. klaus

    klaus Expert Licensed User

    Unfortunately, this is not possible in the current version because the rows are updated dynamically.
     
  2. luciano deri

    luciano deri Active Member Licensed User

    it seems to me that this can work. What do you think about it?
    Code:
    'caller
    sub loadtable
    table.setSelMu(
    "2")
    tabel.setAllowSelection(
    False)
    StrQuery = 
    "SELECT  Codice, descrizione, x  FROM table "
    table.LoadSQLiteDB(dbSql, StrQuery,
    False)
    end sub

    Sub table_CellClick (Col As Int, Row As Int)
        fmu 
    As Int
        StrQuery = 
    "SELECT x FROM table WHERE Codice =
           table.GetValue(0,Row) & "'"
        DbCur = dbSql.ExecQuery(StrQuery)
        fmu = 
    0
        
    If DbCur.RowCount > 0 Then
            DbCur.Position = 
    0
            fmu = DbCurArt.GetInt(
    "x")
        
    else
            
    return
        
    End If
            
        
    If fmu = 1 Then
            multipla_count = multipla_count - 
    1
            StrQuery = 
    "UPDATE table SET X = 0 WHERE
                   codice = '" & table.GetValue(0,Row) & "'"
            dbSql.ExecNonQuery(StrQuery)
            table.SetValue(
    2, Row, "0")
            table.refreshTable
        
    Else
            multipla_count = multipla_count + 
    1
            StrQuery = 
    "UPDATE table SET x = 1 WHERE
                    table.GetValue(0,Row) & "'"
            dbSql.ExecNonQuery(StrQuery)
            table.SetValue(
    2, Row, "1")
            table.refreshTable
        
    End If

    End Sub

    'Class table

    'Set the colum where is a value to test for multi selection. Is string because 0 is a right 'value, but "" not valid value, so i can know when this
    Public Sub setSelMu(SelMu As String)
        cSelMu = SelMu     
    End Sub

    Private Sub ShowRow(Row As Int)
        
    If visibleRows.ContainsKey(Row) Then Return
        
    'Log("ShowRow: " & Row)
     
        
    Dim lbls() As Label
        
    Dim values() As String
        lbls = GetLabels(Row)
        values = Data.get(Row)
        visibleRows.Put(Row, lbls)
        
    Dim rowColor() As Object
        
    If (SelectedRows.indexof(Row) <> -1 )Then
            rowColor = SelectedDrawable
        
    Else If Row Mod 2 = 0 Then
            rowColor = Drawable1
        
    Else
            rowColor = Drawable2
        
    End If
     
        
    For I = 0 To lbls.Length - 1
            
    If (Header.GetView(I).Width > 1 ) Then
                SV.Panel.AddView(lbls(I), Header.GetView(I).Left, Row * cRowHeight, Header.GetView(I).Width, cRowHeight - cLineWidth)
                lbls(I).Text = values(I)
             
                
    If I = SelectedCol And (SelectedRows.indexof(Row) <> -1Then
                    lbls(I).Background = SelectedCellDrawable
                
    Else
                    lbls(I).Background = rowColor(I)
                
    End If
                
    'Manual color multiselction
                If IsNumber(cSelMu) And cSelMu <= (lbls.Length - 1Then
                    
    If values(cSelMu) = "1" Then
                        lbls(I).Background = SelectedCellDrawable
                    
    Else 
                        
    If Row Mod 2 = 0 Then
                            rowColor = Drawable1
                        
    Else
                            rowColor = Drawable2
                        
    End If
                    
    End If
                
    End If
                
    ' end  Manual color multiselction
                If MultiAlignments = False Then
                    lbls(I).Gravity = cAlignment
                
    Else
                    lbls(I).Gravity = cAlignments(I)
                
    End If
            
    End If
          

        
    Next

    End Sub
     
    Last edited: May 21, 2018
  3. klaus

    klaus Expert Licensed User

    I will have a look at it next week, I am absent til monday.
     
  4. klaus

    klaus Expert Licensed User

    Well, if it works for you it's OK.
    I don't want to add this into the class, because it's too specific.

    This looks strange to me:
    Code:
    StrQuery = "UPDATE table SET X = 0 WHERE
           codice = '" & table.GetValue(0,Row) & "'"
     
  5. luciano deri

    luciano deri Active Member Licensed User

    No, in the class is only this
    Code:
    Class table

    'Set the colum where is a value to test for multi selection. Is string because 0 is a right 'value, but "" not valid value, so i can know when this
    Public Sub setSelMu(SelMu As String)
        cSelMu = SelMu     
    End Sub

    Private Sub ShowRow(Row As Int)
        
    If visibleRows.ContainsKey(Row) Then Return
        
    'Log("ShowRow: " & Row)
     
        
    Dim lbls() As Label
        
    Dim values() As String
        lbls = GetLabels(Row)
        values = Data.get(Row)
        visibleRows.Put(Row, lbls)
        
    Dim rowColor() As Object
        
    If (SelectedRows.indexof(Row) <> -1 )Then
            rowColor = SelectedDrawable
        
    Else If Row Mod 2 = 0 Then
            rowColor = Drawable1
        
    Else
            rowColor = Drawable2
        
    End If
     
        
    For I = 0 To lbls.Length - 1
            
    If (Header.GetView(I).Width > 1 ) Then
                SV.Panel.AddView(lbls(I), Header.GetView(I).Left, Row * cRowHeight, Header.GetView(I).Width, cRowHeight - cLineWidth)
                lbls(I).Text = values(I)
            
                
    If I = SelectedCol And (SelectedRows.indexof(Row) <> -1Then
                    lbls(I).Background = SelectedCellDrawable
                
    Else
                    lbls(I).Background = rowColor(I)
                
    End If
                
    'Manual color multiselction
                If IsNumber(cSelMu) And cSelMu <= (lbls.Length - 1Then
                    
    If values(cSelMu) = "1" Then
                        lbls(I).Background = SelectedCellDrawable
                    
    Else
                        
    If Row Mod 2 = 0 Then
                            rowColor = Drawable1
                        
    Else
                            rowColor = Drawable2
                        
    End If
                    
    End If
                
    End If
                
    ' end  Manual color multiselction
                If MultiAlignments = False Then
                    lbls(I).Gravity = cAlignment
                
    Else
                    lbls(I).Gravity = cAlignments(I)
                
    End If
            
    End If
          

        
    Next

    End Sub
    Afther, in the cell_click, i must edit the field shown in cSelmu column for could test here
     
  6. klaus

    klaus Expert Licensed User

    I know.

    But the code, I mentioned in my post #824 looks strange to me.
    Sorry, I don't understand.
     
    Last edited: May 21, 2018
  7. luciano deri

    luciano deri Active Member Licensed User

    when i click on cell of table, return on event table_CellClick pass Col and Row, this is standard.
    Inside this sub i must read clicked row and change "x" column that contain state of select value .
    Change this state with query, change corrispondent value in table with table.SetValue(...) and refresh table with table.refreshTable.



    Code:
    Sub table_CellClick (Col As Int, Row As Int)
        fmu 
    As Int
        StrQuery = 
    "SELECT x FROM table WHERE Codice =
           table.GetValue(0,Row) & "'"
        DbCur = dbSql.ExecQuery(StrQuery)
        fmu = 
    0
        
    If DbCur.RowCount > 0 Then
            DbCur.Position = 
    0
            fmu = DbCurArt.GetInt(
    "x")
        
    else
            
    return
        
    End If
            
        
    If fmu = 1 Then
            multipla_count = multipla_count - 
    1
            StrQuery = 
    "UPDATE table SET X = 0 WHERE
                   codice = '" & table.GetValue(0,Row) & "'"
            dbSql.ExecNonQuery(StrQuery)
            table.SetValue(
    2, Row, "0")
            table.refreshTable
        
    Else
            multipla_count = multipla_count + 
    1
            StrQuery = 
    "UPDATE table SET x = 1 WHERE
                    table.GetValue(0,Row) & "'"
            dbSql.ExecNonQuery(StrQuery)
            table.SetValue(
    2, Row, "1")
            table.refreshTable
        
    End If

    End Sub
     
  8. klaus

    klaus Expert Licensed User

    Does it work for you?
    If yes, everything is OK.
     
    Peter Simpson likes this.
  9. luciano deri

    luciano deri Active Member Licensed User

    At 90%. I see a strange color effect, sometimes the panel became smaller than cell, but when table refresh return ok. I can' t understand , seems something with keyboard show but i'm not call nothing. How you can see focus not change, and there is nothing about table, only automatic show of keyboard by os.
    See image
     

    Attached Files:

  10. epsharp

    epsharp Member Licensed User

    I have been programming in B4PPC since its inception. When I first started, I noticed that Table Views lacked many functions. I wrote a library in C# to create a DataGridView from a SQL Query. It was reusable and served me well over the years.

    I am now in B4A struggling with this custom table view. It works very similar to my old DGV and it was very easy for me to get my data to display in table form, but I soon ran into three missing common options. These are my wish list options for future updates:

    1. Set Single Column Color (SetColColor(col as Int, row as Int, color as Color):
    While taking a customer order and displaying items previously purchased, set background color to GREEN for items already existing in this order.
    Display a list of options where you can select one or several; The First, Left Colum is "APPLY" color Green and the Last, Right Column is "DISMISS" color Red.

    2. Set Single Column Alignment (SetColAlign(col as Int, row as Int, align as Int)
    All columns are Center align. One column looks funny so you change is to Right align.

    3. Set Single Column (or All Columns) to Word Wrap On
    There is no way, when using SQL, to embed a CRLF in a text field to simulate word-wrap. Without word-wrap, fixed width columns truncate. Rum & Orange Juice comes out "Rum & Oran".

    Thank you in advance for your time and consideration.

    Regards

    Ed Sharp
     
  11. klaus

    klaus Expert Licensed User

    1. You can use SetColumnColors(ColumnColors() As Int)
    2. You can use SetCellAlignments(Alignments() As Int)
    3. This is a bit more complicated. The height of all rows is the same. Therefore you would need to use a height for all rows allowing 2 lines or more.
    You can use automatic widths.
     
  12. epsharp

    epsharp Member Licensed User

    Thank you Klaus for your reply. My problem is:

    1. I don't want to set all column colors, only a single column [for example Column 3 in Row 5 ie. SetColumnColor(3,5,Colors.Red) ]

    2. I use your solution as a work-around but again, looking for a simple way to change a single column [ SetColumnAlign(3,Gravity.Left) ]

    3. This one is the killer. I have set the row height to accommodate three lines but it still truncates. Nothing I have been able to do will make it word-wrap. I use automatic widths for now but because of the narrow width of most phones, this causes very distorted views:

    From my POS system, three drinks ordered:

    DESCRIPTION QTY AMOUNT
    Rum&Coke 1 $3.00
    Belvedere Vodka Citrus & Orange Juice(Tall Glass,Lots Ice) 1 $5.00
    Bud Bot 1 $2.00

    You need to slide the table left to view the quantity. I even tried modifying the table data itself, inserting carriage returns, etc. but still no word wrap. The work-around here was put the quantity as the first column of the table. Would love to have Table.WordWrap = True

    Thanks again for your assistance. It's just my wish list.
     
  13. klaus

    klaus Expert Licensed User

    For point 3, can you try the following code,
    add this line L.SingleLine = False.

    Code:
    Private Sub CreateNewLabels As Label()
        
    Dim lbls(mNumberOfColumns) As Label
        
    For i = 0 To mNumberOfColumns - 1
            
    Dim rc As RowCol
            rc.Col = i
            
    Dim L As Label
            L.Initialize(
    "Cell")
           
            L.TextSize = cTextSize
            L.SingleLine = 
    False
     
  14. vecino

    vecino Well-Known Member Licensed User

    Sintax error in v1.44?
    Hello, I think there is an error in this line:
    Code:
    Public Sub SetHeader (Values () As String)
       ..
       ..
       
    If HeaderWidths (col)> ColumnWidths (col) Then OR HeaderWidths (col)> ColumnWidths (col) Then
       ..
       ..
    Best regards.
     
  15. klaus

    klaus Expert Licensed User

    Thank you!
    It should be:

    Code:
    Public Sub SetHeader (Values () As String)
       ..
       ..
       
    If HeaderWidths (col)> ColumnWidths (col) Then 
       ..
       ..
    The file has been updated in the first post.
     
    vecino likes this.
  16. Seneca

    Seneca Active Member Licensed User

    Hi,

    Is it possible to consult the sorted column and the dir?

    Regards
     
  17. klaus

    klaus Expert Licensed User

    You have the Data list containing all data from the table, this list is updated during sorting, a String Array with the values of each row.
    Code:
    Private RowData() As String
    RowData = Table1.Data.Get(RowIndex)
    For col = 0 To RowData.Length - 1
        
    Log(RowData(col))
    Next
    Then you have the GetValue(col, row) method to get the value in the given row and column.
    And the GetValues(row) method to get the array of strings of the values in the given row.

    The direction is not available, you can check the first and the last value of the column to get the direction.
     
    Seneca likes this.
  18. Seneca

    Seneca Active Member Licensed User

    Hi.

    I meant to know the number of the column that has been sorted.

    In my humble opinion, a practical way could be through the member Header_Click. It could return not only the number of the header pressed, but also the direction.


    Code:
    Private Sub Header_Click
        ............
        ............
        ............
        
        
    If SubExists(cCallBack, cEventName & "_HeaderClick"Then
            
    CallSub2(cCallBack, cEventName & "_HeaderClick", col) '<------- Here could you indicate the column and the direction?

        
    End If



    End Sub
     
  19. klaus

    klaus Expert Licensed User

    Why do you need this information?
     
    Seneca likes this.
  20. Seneca

    Seneca Active Member Licensed User

    Hi,

    I need to save the number of the column that the user has ordered so that the next time the table is displayed it appears ordered with that same column.
     
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