Exclude List Rows from Sorting

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
Joerg Hamacher
Posts: 53
Joined: Thu Feb 11, 2016 12:01 am

Exclude List Rows from Sorting

Post by Joerg Hamacher » Fri Apr 20, 2018 12:36 am

Hi,

on a web page we have a list to show sales and profit values of customers.
The last row of the list contains the toal sums of all the values above.
All columns are defined with SortOnClick = Yes.

Disadvantage is: The total sums row is always included into the sort mechanism and appears somewhere in the list depending on the total values or the column selected.
How can this be prevented? The total sums row always has to be the last row of the list.

Best regards and many thanks in advance,
Joerg

caseywhite
Posts: 110
Joined: Thu May 26, 2016 1:17 am

Re: Exclude List Rows from Sorting

Post by caseywhite » Fri Apr 20, 2018 3:22 am

Here is some sample code that will do what you want. The premise is that you add a hidden column that is long enough to hold the contents of any visible column that will be sortable. You then have a method that puts the contents of the column that has been clicked into this hidden field. For the TOTAL Row (or any of the fixed rows for that matter if you want more than 1 fixed row) you conditionally set it to a value that will guarantee it sorts to the bottom based on whether the sort is being set to ascending or descending.

For solution 1 you use the sortonclick property and set the sortoncolumn to the hidden column. For solution 2 you don't use the sortonclick property and instead manually control the full sortonclick logic.

For a really large list this approach might not perform well. At 400 entries that I tested it seems to work well though. At 2000 entries there was a noticeable lag but is still usable.

Both solutions below are generic and would work for any number of columns that you want to sort. You just need to make sure the umResetList method has code for each of your sortable column names (i.e. 2 extra lines per sortable column). The only drawback to solution 1 is that if you repeatedly click really fast the TOTAL row can end up on the top when you stop clicking. If this is a deal breaker, check out the second sample web page which uses a custom sort indicator which appears to the left of the column text and doesn't have this issue. It requires some extra code to control the sorting but is still generic. Personally I prefer #2 because you don't have to worry about the issue and the extra code you need isn't that much.

Solution 1 - Using Native Sort On Click Property

Code: Select all

Begin_Com Role(*EXTENDS #PRIM_WEB)
Define_Com Class(#PRIM_LIST) Name(#List1) Displayposition(1) Left(160) Parent(#COM_OWNER) Tabposition(1) Top(84) Width(673) Height(213)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnEMPNO1) Columnwidth(33) Displayposition(1) Parent(#List1) Source(#EMPNO) Sortonclick(True) Sortascolumn(#ColumnSTD_TEXTL1) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnSURNAME1) Columnwidth(33) Displayposition(2) Parent(#List1) Source(#SURNAME) Sortonclick(True) Sortascolumn(#ColumnSTD_TEXTL1) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.Number) Name(#ColumnSALARY1) Columnwidth(33) Displayposition(3) Increment(1) Parent(#List1) Source(#SALARY) Wrap(False) Sortascolumn(#ColumnSTD_TEXTL1) Sortonclick(True) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnSTD_TEXTL1) Columnwidth(5) Displayposition(4) Parent(#List1) Source(#STD_TEXTL) Columnvisible(False)
Define_Com Class(#PRIM_TIMR) Name(#Timer1) Startup(Manual) Interval(5)

Evtroutine Handling(#Com_owner.Initialize)
#EMPNO := 'A'
#SURNAME := 'FRED'
#SALARY := 423
#STD_CHAR := 'A'
#STD_FLAG := 'A'
Add_Entry To_List(#List1)

#EMPNO := 'B'
#SURNAME := 'WILMA'
#SALARY := 923
#STD_CHAR := 'B'
#STD_FLAG := 'B'
Add_Entry To_List(#List1)

#EMPNO := 'C'
#SURNAME := 'BARNEY'
#SALARY := 323
#STD_CHAR := 'C'
#STD_FLAG := 'C'
Add_Entry To_List(#List1)

#EMPNO := 'TOTAL'
#SURNAME := ''
#SALARY := 9999
#STD_CHAR := 'Z'
#STD_FLAG := '0'
Add_Entry To_List(#List1)
Endroutine

Evtroutine Handling(#ColumnEMPNO1.ColumnClick #ColumnSURNAME1.ColumnClick #ColumnSALARY1.ColumnClick) Com_Sender(#iColumn)
* Find the total row and change the value so that it will always be at the bottom based on the sort
If Cond(#iColumn.SortDirection = Ascending)
#com_owner.umResetList Icolumnname(#iColumn.Name) Isortdirection('A')
Else
#com_owner.umResetList Icolumnname(#iColumn.Name) Isortdirection('D')
Endif
Endroutine

Mthroutine Name(umResetList)
Define_Map For(*INPUT) Class(#PRIM_ALPH) Name(#iColumnName)
Define_Map For(*INPUT) Class(#STD_ALPHA) Name(#iSortDirection)

Selectlist Named(#List1)
If Cond(#EMPNO = 'TOTAL')
If Cond(#iSortDirection = 'A')
#STD_TEXTL := 'Z'
Else
#STD_TEXTL := '0'
Endif
Else
Case Of_Field(#iColumnName)
When Value_Is(= 'COLUMNEMPNO1')
#STD_TEXTL := #EMPNO
When Value_Is(= 'COLUMNSURNAME1')
#STD_TEXTL := #SURNAME
When Value_Is(= 'COLUMNSALARY1')
#STD_TEXTL := #SALARY.AsString
Endcase
Endif
Upd_Entry In_List(#List1)
Endselect
Endroutine

End_Com

Solution 2 - Controlling the Sort On Click Yourself

Code: Select all

Begin_Com Role(*EXTENDS #PRIM_WEB)
Define_Com Class(#PRIM_LIST) Name(#List1) Displayposition(1) Left(144) Parent(#COM_OWNER) Tabposition(1) Top(84) Width(673) Height(213)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnEMPNO1) Columnwidth(33) Displayposition(1) Parent(#List1) Source(#EMPNO) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnSURNAME1) Columnwidth(33) Displayposition(2) Parent(#List1) Source(#SURNAME) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.Number) Name(#ColumnSALARY1) Columnwidth(33) Displayposition(3) Increment(1) Parent(#List1) Source(#SALARY) Wrap(False) Columnunits(Proportion)
Define_Com Class(#PRIM_LIST.String) Name(#ColumnSTD_TEXTL1) Columnwidth(5) Displayposition(4) Parent(#List1) Source(#STD_TEXTL) Columnvisible(False)

Evtroutine Handling(#Com_owner.Initialize)
#EMPNO := 'A'
#SURNAME := 'FRED'
#SALARY := 423
#STD_CHAR := 'A'
#STD_FLAG := 'A'
Add_Entry To_List(#List1)

#EMPNO := 'B'
#SURNAME := 'WILMA'
#SALARY := 923
#STD_CHAR := 'B'
#STD_FLAG := 'B'
Add_Entry To_List(#List1)

#EMPNO := 'C'
#SURNAME := 'BARNEY'
#SALARY := 323
#STD_CHAR := 'C'
#STD_FLAG := 'C'
Add_Entry To_List(#List1)

#EMPNO := 'TOTAL'
#SURNAME := ''
#SALARY := 9999
#STD_CHAR := 'Z'
#STD_FLAG := '0'
Add_Entry To_List(#List1)
Endroutine

Evtroutine Handling(#ColumnEMPNO1.ColumnClick #ColumnSURNAME1.ColumnClick #ColumnSALARY1.ColumnClick) Com_Sender(#iColumn)
If Cond(#iColumn.SortDirection = Ascending)
* Find the total row and change the value so that it will always be at the bottom based on the sort
#com_owner.umResetList Icolumnname(#iColumn.Name) Isortdirection('D')

* Set any other column that can be sorted to have SortPosition0
#ColumnSTD_TEXTL1.SortPosition := 1
#ColumnSTD_TEXTL1.SortDirection := Descending
#iColumn.SortDirection := Descending

* Set the appropriate sort image
#iColumn.ColumnPopupImage <= #xImageDown16
Else
#com_owner.umResetList Icolumnname(#iColumn.Name) Isortdirection('A')

* Set any other column that can be sorted to have SortPosition0
#ColumnSTD_TEXTL1.SortPosition := 1
#ColumnSTD_TEXTL1.SortDirection := Ascending
#iColumn.SortDirection := Ascending

* Set the appropriate sort image
#iColumn.ColumnPopupImage <= #xImageUp16
Endif

Endroutine

Mthroutine Name(umResetList)
Define_Map For(*INPUT) Class(#PRIM_ALPH) Name(#iColumnName)
Define_Map For(*INPUT) Class(#STD_ALPHA) Name(#iSortDirection)

* Clear any sort images
For Each(#Column) In(#List1.Columns)
#Column.ColumnPopupImage <= *NULL
Endfor

Selectlist Named(#List1)
If Cond(#EMPNO = 'TOTAL')
If Cond(#iSortDirection = 'A')
#STD_TEXTL := 'Z'
Else
#STD_TEXTL := '0'
Endif
Else
Case Of_Field(#iColumnName)
When Value_Is(= 'COLUMNEMPNO1')
#STD_TEXTL := #EMPNO
When Value_Is(= 'COLUMNSURNAME1')
#STD_TEXTL := #SURNAME
When Value_Is(= 'COLUMNSALARY1')
#STD_TEXTL := #SALARY.AsString
Endcase
Endif
Upd_Entry In_List(#List1)
Endselect
Endroutine

End_Com

Joerg Hamacher
Posts: 53
Joined: Thu Feb 11, 2016 12:01 am

Re: Exclude List Rows from Sorting

Post by Joerg Hamacher » Fri Apr 20, 2018 10:51 pm

Hi Casey,
thank you very much for these detailled examples!

Have a nice weekend,
Joerg

Post Reply