Wish B4XTableColumn InternalSortMode

Alain75

Member
The property InternalSortMode of a B4XTABLE column may be set by code with "ASC" or "DESC". In that case :
  • Header displays an arrow showing the direction of the sorting option (ascending or descending)
  • Content column is sorted, case sensitive
As this property is probably added to the SQLite sort command, I discover that setting "COLLATE NOCASE ASC" or "COLLATE NOCASE DESC" works fine and sorts the content column case insensitively :) But unfortunately, the header displays the wrong arrow (descending) as the property is not equal to "ASC".

@Erel : could it be fixed in a next release or is there a way to change the displayed arrow ?

Thanks a lot !
 

Attachments

  • Image.jpg
    Image.jpg
    338.5 KB · Views: 131

Alain75

Member
Hi,
unfortunately, I am not able to modify the file B4XTable.b4xlib or I don't know the way to (@Erel ?). May I suggest a simple fix to deal with the header click "cycling", enabling InternalSortMode to be initialized empty (standard sort) or with "COLLATE NOCASE " (case insensitive sort) ?

Pseudo code:
... variable ISM supposed to contain current property column InternalSortMode
Select True
   Case "COLLATE NOCASE ".contains(ISM)   ' No current sort : go to ascending mode
      ISM = ISM & "ASC"
      ...Show ascending arrow...
   Case ISM.EndsWith("ASC")               ' Current sort ascending : go to descending mode
      ISM = ISM.replace("ASC","DESC")
      ...Show descending arrow...
   Case Else                              ' Current sort descending : go to no sort
      ISM = ISM.replace("DESC","")
      ...Hide arrow...
End Select
... SQLlite command ended with "SORT BY ... ISM"

Thanks !
 

Alain75

Member
@Erel : I did it :) In attachment, the library version 1.24 and below the modifications.

Sub modified:
Sub BuildQuery
   ...
   If Not("COLLATE NOCASE ".Contains(c.InternalSortMode)) Then
      SortColumn = " ORDER BY " & c.SQLID & " " & c.InternalSortMode
   End If
   ...
Sub HeaderClicked
   ...
   If c = col Then
      If c.InternalSortMode.EndsWith("ASC") Then
         c.InternalSortMode = c.InternalSortMode.Replace("ASC","DESC")
      Else if c.InternalSortMode.EndsWith("DESC") then
         c.InternalSortMode = c.InternalSortMode.Replace("DESC","ASC")
      else
         c.InternalSortMode = c.InternalSortMode & "ASC"
      End if
   Else
      c.InternalSortMode = c.InternalSortMode.Replace("ASC","").Replace("DESC","")
   End If
   ...
Sub UpdateSortIcon
   ...
   If Not("COLLATE NOCASE ".Contains(col.InternalSortMode)) Then
   ...
   If col.InternalSortMode.Contains("ASC") Then lblSort.Text = Chr(0xF0DE) Else lblSort.Text = Chr(0xF0DD)
   ...
 

Attachments

  • B4XTable.b4xlib
    14.2 KB · Views: 130

Alain75

Member
@Erel : Here is a better, simpler and nicer way to cope with : I just added a new property "CaseInsensitive" for the column and took it into account in the sorting option !

2 lines modified:
Sub Class_Globals
   ...
   Type B4XTableColumn (Title As String, Id As String, ColumnType As Int, Sortable As Boolean, Searchable As Boolean, _
      Formatter As B4XFormatter, SQLID As String, Width As Int, ComputedWidth As Int, CellsLayouts As List, _
      Panel As B4XView, LabelIndex As Int, DisableAutoResizeLayout As Boolean, InternalSortMode As String, CaseInsensitive As Boolean)
   ...
Sub BuildQuery
   ...
   If c.InternalSortMode <> "" Then
      SortColumn = " ORDER BY " & c.SQLID & IIf(c.CaseInsensitive," COLLATE NOCASE "," ") & c.InternalSortMode
   End if
   ...
 

Attachments

  • B4XTable.b4xlib
    14.1 KB · Views: 139

Mahares

Expert
Licensed User
Longtime User
added a new property "CaseInsensitive" for the column
Your change to the B4XTable class works well where an internal column sorting can be either Case Sensitive or Insensitive. But, what is the purpose of using the InternalSort because if you click on another column header the sorting gets all changed again, unless you disable sorting for all other columns.
Can you include a sample project to test
 
Last edited:

Alain75

Member
The purpose is to always retrieve the same sort order for the columns, case sensitive or case insensitive. In my "package manager" application, when some packages have been updated, I automatically display the list by "update date" descending. The click on the column header "application" restores the default sort order, name ascending case insensitive. And I switch frequently from one to another sorting easily.
 

Alain75

Member
No need to attach a project (I don't have a sample) if you have already your own one. In this case, you just have to :
  1. Copy the library in your external library folder under a different name, for instance B4XTableNew.b4xlib
  2. On your project in B4A
  3. In the library manager uncheck the internal library B4XTable and check the external one
  4. Set CaseInsensitive on a column with text content (for instance with something like YourB4XTable.GetColumn("xxxx").CaseInsensitive = True
  5. Recompile
  6. Click on the header of the column to see the result of the sort case insensitive ;)
 

Mahares

Expert
Licensed User
Longtime User
Actually, there is a way to accomplish the sorting caseinsensitive without modifying the B4XTable library by Erel. The reason I asked for your project is to test my code on yours to see how it performs and to convince myself that what I have would work without any B4XTable library modifications. Any time you can do something without having to change a library is a plus to avoid confusions down the road when a library is updated.
 

Alain75

Member
Well, even if my modifications are very light, I am very interested in the way to sort case insensitive when clicking on the header of a column with standard class B4XTable without the use of CreateDataView !
 
Top