Browse Sort Headers - Browse Column Not In View

Is there a way, or a template, to enable browse sort headers on browse columns that are not in the view? I have a column in the browse that shows if an invoice is open/closed. I cannot sort by this column because it is not in the view. I have a user that wants to sort the browse by this status.


Maybe @Graham_Dawson can find Jim Kane’s “Look Ma, No Keys” article on Clarionmag. A quick search didn’t turn it up. Maybe it could be useful. Graham is the only one who can find anything on that site. :slight_smile:

Easy one Jeff :slight_smile:

It’s the cmag-2001-01.pdf and associated source zip that you need.

Thanks a lot, Graham.

Worth disclosing my secret here :slight_smile:

I have all the monthly pdfs and source file zips downloaded locally and I use Agent Ransack to search that local folder to find the pdf. Then it’s just a matter of posting the url for the particular year.

Finding stuff using Confluence’s Search function is (as you’ve found) iffy at best.


Thanks Graham sharing your knowledge base, it is difficult to search directly on the web for those articles… but if I recall correctly that article was related to choosing orders for browses using fields in the view that does not belong to Keys and are not selectable through “Select Key from File” dialog double clicking in the main file below File-Browsing List Box in file schematics nor in Browse Box behavior / Conditional behavior / Key to Use template prompt… You can choose to not use keys but then you loose “Locator Behavior” dialog to use for example an Incremental locator, and that article neatly addressed that… but I think Marks wanter to use the Sort Header extended option to be able to sort on columns that are not related to fields in the view…

Mark, as Browse Template (+class in ABC) uses Clarion View to access data, and a QUEUE to hold the a page of data to show on the Listbox control (in the case ABC Browse it allows File Loaded option to load all the data on the QUEUE). The View engine can set sorted access to the records based on the Fields in the involved tables (not only the columns shown on the screen) and if the files are SQL, you could ask custom sorts to the database…

You could derive SortHeader classes (probably ValidField, GetSortingColumnString, QueueResorted…), detect the column clicked and decide what to do depending on if it is SQL or not, ABC or not, File loaded or Not.

I think I have misread Mark post, that he wanted to click on calculated columns

The sort column can be set manually without clicking to header by setting the PROPLIST:SortColumn property.

Is it documented?

On other thoughts, perhaps Mark only needs to override sort orders for columns in “Customize BrowseBox Sort Header” window, with the button below the place where sort headers are enabled (assuming using ABC)

1 Like

I don’t know. I wrote the code to support sort columns on May 2nd, 2013. But I was not a documentation writer.

It would depend on the details about Mark use case

I think PROPLIST:SortColumn only works when you set List{PROPLIST:HasSortColumn}=True which is documented in the Help:

PROPLIST:HdrSortTextColor PROPLIST:HdrSortBackColor PROPLIST:SortTextColor PROPLIST:SortBackColor

These 4 properties are to define text and background colors for cells and headers of a column set as a sort column. These properties have no effect if sort column is not turned on. This can be done by setting PROPLIST:HasSortColumn property to TRUE. If it is set to TRUE, clicking on a header for any visible column triggers the modal event EVENT:HeaderPressed.

In response to this event the program can either execute CYCLE (to ignore the event), or re-sort the source of listbox data (a QUEUE usually). If CYCLE isn’t called the RTL

changes the current sort column to the one which the header has been clicked. The header and cells of the current sort column are re-drawn using colors defined using the 4 properties from above.

Cells in selected rows are drawing using selection colors.

If you search LibSrc you’ll find BrwExt.CLW implements PropList:SortColumn. So that is an example of code using these new PROPs from SV. The below attachment is my example of using BrwExt I made for CIDC 2019. (2.2 KB)

I like the new PROPLIST:HasSortColumn and the way it generates EVENT:HeaderPressed. It is much more logical than the old way of catching the Mouse Left Alert Key in the Header row and not in the Resize Zone. The below attachment is an example of Column sort I made for CIDC 2019. It is very easy to use, you do not need BrwExt.clw (4.7 KB)

This GitHub project also demos the new column sorting. Search for “SortColumn” or “HeaderPressed”. It also shows an undocumented PROP to get a reference to a LIST FROM Queue that AS needed.

If PROPLIST:HasSortColumn is not TRUE, the PROPLIST:SortColumn property returns 0. But setting of this property can be done regardless value of PROPLIST:HasSortColumn. Set value if PROPLIST:HasSortColumn is FALSE is using almost nowhere. Looking at the code I think that it would be correct to change it to remove the word “almost”.

The EVENT:HeaderPressed event is executing only if PROPLIST:HasSortColumn is TRUE.

BRWEXT.CLW only gets value of the PROPLIST:SortColumn property, Setting of this property is using nowhere in distributed sources.

I dId not expect so many responses! Lots of good ideas for me to try out today (probably tomorrow since I’m leaving work early).


I’ll paste the code of one of the examples so it does not need to be downloaded to see. This one is of a Directory File:Queue with the File Name that is 1st in the Queue moved to last in the LIST using Format #1#.


ListSort:HasSortColumn_ColumnReorder    PROCEDURE()
DirQ    QUEUE(FILE:Queue),PRE(DirQ)
        END ! DirQ:Name  DirQ:ShortName(8.3?)  DirQ:Date  DirQ:Time  DirQ:Size  DirQ:Attrib
SortNow     SHORT
SortLast    SHORT
SortNowWho  STRING(128)
SortLastWho STRING(128)

FilesWindow WINDOW('#1# Columns not in Order - Sort "PROPLIST:HasSortColumn" '),AT(350,1,343,250),GRAY,SYSTEM,FONT('Segoe UI',9,, |
                      STRING('Column 5 Name is Q Field #1#. C9 PROPLIST:HasSortColumn and EVENT:HeaderPressed.'),AT(2,2),USE(?HowSort)
        LIST,AT(1,15),FULL,USE(?ListFiles),VSCROLL,TIP('Click heads to sort, Click again to reverse'), |
                FROM(DirQ),FORMAT('52L(1)|M~Short Name~@s13@#2#40R(1)|M~Date~C(0)@' & |
    LOOP QNdx = RECORDS(DirQ) TO 1 BY -1        !--Keep directories, Delete files, Case Name
         IF BAND(DirQ:Attrib,FF_:Directory) OR DirQ:Name='.' OR DirQ:Name='..'   !. or .. Dirs
            DirQ:Name=UPPER(DirQ:Name[1]) & DirQ:Name[2 : SIZE(DirQ:Name) ]
    0{PROP:Text}=CLIP(0{PROP:Text}) &'  '& WinTempBS & ' (' & RECORDS(DirQ) &' records) '
    !To setup for new LIST HasSortColumn MUST set PROPLIST:HasSortColumn=1
    ?ListFiles{PROPLIST:HdrSortBackColor} = COLOR:HIGHLIGHT                 !Color Header Background    
    ?ListFiles{PROPList:HdrSortTextColor} = COLOR:HIGHLIGHTtext             !Color Header Text
    ?ListFiles{PROPList:SortBackColor}    = 80000018h !COLOR:InfoBackground !Color List Background
    ?ListFiles{PROPList:SortTextColor}    = 80000017h !COLOR:InfoText       !Color List Text     
       CASE EVENT()
       OF EVENT:OpenWindow
          ?ListFiles{PROPLIST:SortColumn}    =5     !Color column 5 as sorted, really Q field 1
          ?ListFiles{PROPList:MouseDownField}=5     !Force Initial Sort Column - You can Write this Property
          DO TakeEVENT:HeaderPressed                !Use Click Column code to Sort Queue and set variable
          ?ListFiles{PROP:Selected}=1               !First time select row 1 of sorted 
       CASE FIELD()
       OF ?ListFiles
          CASE EVENT()
          OF EVENT:HeaderPressed
             DO TakeEVENT:HeaderPressed 

          OF EVENT:NewSelection !DblClick to View 1 File
             IF KEYCODE()=MouseLeft2 THEN
                MESSAGE(CLIP(DirQ:Name) &'|'& DirQ:ShortName &'|'& DirQ:Date &'|'& DirQ:Time &'|'& DirQ:Size |
                        &'|'& DirQ:Attrib,'File '&CHOICE(?ListFiles),,,,2)
          END ! Case EVENT()
       END ! Case FIELD()

TakeEVENT:HeaderPressed ROUTINE !Sort the Queue just using column numbers
    GET(DirQ, CHOICE(?ListFiles))                  !To preserve selected row
    SortNow=?ListFiles{PROPList:MouseDownField}    !This is really LIST Column and NOT Q Field
    SortNow=?ListFiles{PROPLIST:FieldNo,SortNow}   !This is Q Field No. Required here because Name uses #1#
    IF SortNow<>ABS(SortLast) THEN SortLastWho=',' & SortNowWho.
    SortNowWho=CHOOSE(SortNow=SortLast,'-','+') & WHO(DirQ,SortNow)
    0{PROP:Text}='#1# Order - HasSortColumn: SORT (' & SortNow &' /'& SortLast &') ' & CLIP(SortNowWho) & SortLastWho
    SORT(DirQ,CLIP(SortNowWho) & SortLastWho)
    SortLast = CHOOSE(SortNow=ABS(SortLast),-1*SortLast,SortNow) 
    GET(DirQ, DirQ:Name)                           !If no Unique field to GET() then Loop until find it
    ?ListFiles{PROP:Selected}=POINTER(DirQ)        !Preserved the selected record


Much easier if you are using a SQL database and a SQL VIEW as the basis for your browse.

Got it working with a combination of adding some hot fields from a related table and customizing the sort headers with multiple columns. Thanks!

Any thought given to making this available as a GPT with OpenAI? Not sure who owns the copyright or what the related issues are, but access to that could be huge beneficial.

Hi Mark,

Maybe add the column to the list-box fields but set its width to zero. That way it is in the view but not visible (although users might find a sort on an invisible field a bit odd?).

Then you can use the ‘additional sort’ in the template’s action button.

Or, have the field visible and use the sort columns option in the template (assuming you are using ABC templates).

I hope that helps.