Tips_gui   >   Headedlists   >   Headed Lists (All Contents)
Of the available list objects in the
the Headed List Object is the favorite of most developers.The headed list box header buttons are clickable (if you enable them), so you can sort the list by the column heading which the user clicks on. See the
topic for a generic sort list method which you can use on any headed list.You can display whatever list variable column(s) you want in the headed list box, in whatever order you specify. You do not have to create a special list in the correct column order to match what you want to display.
One thing you must clearly understand when working with the headed list object is the difference between the list object and the list variable.
The list object displays to the user data that is stored in the list variable.
In some cases the list object and the list variable are quite tightly tied together. If the user clicks on a line in the headed list object, Omnis Studio immediately sets the current line in the list variable to the same line which the user clicked on in the headed list object. If $multipleselect is set to kTrue when the user selects lines in the headed list object, Omnis Studio immediately set the selected status of the lines in the list variable to match the selected lines in the headed list object.
However, if $multipleselect is set to kFalse, clicking on a line in the headed list object does not changed the selected line(s) in the list variable.
In other cases the list object and the list variable are not tightly tied together. If the user edits text in the headed list object, you the developer have to write code that traps the evHeadedListEditFinished event and copy the pNewText to the correct cell in the list variable.
You must clearly understand the difference between the list object and the list variable when working with headed lists and other list display objects. (Data grid, string grid, complex grid, etc.)There are a number of headed list object features which can only be set during runtime, that is the list has been or is in the process of being instantiated.
The runtime properties of the headed list are shown in green text in the
.To view the runtime properties be sure to have
turned on in the . To do so, right-click on the window and make sure has a check mark beside it. Make sure is checked on as well.In developer mode, when you click on a headed list object, press F6 to view the $setcolumnalign and $columwiths.
, select the tab (and others) and note the properties listed in green text. They are the runtime properties. e.g.Be sure to review the topic
Headed Lists ... a great feature of Studio! , it has saved me a lot of time and cut way back on the number of windows in my application.If you have a list variable defined with exactly the columns you want to displayed, in the right order you simply need to enter the list variable name in the $dataname property of the headed list object.
Since that is rarely the case, you would additionally use the $calculation property to specify the columns you want displays and the order you want them displayed by the headed list object.
The $calculation property accepts a tab delimited string of columns. An example might be:
con(iList.Qty,kTab,iList.Desc,kTab,iList.CostPer,...)Headed lists can have calculated columns. If you have a headed list with a Qty column and a CostPer column, you can display a ExtPrice column which is Qty*CostPer. The ExtPrice column does not exist in the list variable, only in the headed list object display. The $calculation property of the list might look like this:
; Set the $calculation property for the list object.
; The 5th column is a calculated column which is not in the list variable.
; Use the jst() function to set the 5th column to display 2dp.
Do irListObj.$calculation.$assign("con(iList.Qty,kTab,iList.Desc,kTab,iList.CostPer,ktab,iList.UM,ktab,jst(iList.Qty*iList.CostPer,'N2'))")
Do $cinst.$redraw()
If we want to sort the list by the calculated ExtPrice column, how do we sort the list? The column doesn't exist in the real list, it is only in the headed list display. Much to my amazement I discovered that OMST's $sort method accepts calculations!
Do iList.$sort(iList.Qty:*iList.CostPer)
Way to go OMST!Headed list columns are left justified by default. You can change the column alignment using notation.
Do ListObjRef.$setcolumnalign(ColumnNumber,kAlignment)
kJustify can be:
The alignment constants can be found in the kCenterJst, kRightJst, kLeftJst )
> tab > . (If you have a series of columns to set the alignment you can do it in a loop. A handy place to set the column alignment is in the $construct of the headed list object.
; If you have a series of columns to $setcolumnalign, you can do it in a loop.
For %N from 3 to 6 step 1
Do irListObj.$setcolumnalign(%N,kRightJst)
End For
The column widths are a runtime property which can be set using notation.
Do irListObj.$columnwidths.$assign('50,100,40')
The column widths are in pixels.
You can adjust column widths manually in design mode or you can set the widths in runtime using notation.
In my applications I save the $columnwidths property for each headed list in each window instance to the user's profile in the database. When the user reopens a window instance the headed list $columnwidths are restored from their user profile.
In the headed list properties, under the $multipleselect.
tab, there is a property calledIf you set it to kTrue, the user can Shift+click or Ctrl/Cmnd+click on the headed list to select multiple lines.
When $multipleselect is kFalse, clicking on different lines in the list object does not set or affect the selected lines in the list variable, it only changes the current line in the list variable. This can be confusing for the developer, because even though the current line looks as though it is the selected line in the list, the reality is that a totally different line may or may not be selected in the list variable. To keep things simple I include the following code in the $event method of my headed list object to keep th selected lines in the list variable in sync with the headed list object selected lines.
On evClick
; Multiple select headed list automatically sets the current and selected list line.
; Non-multiple select headed list does not set the current line to selected. This causes
; confusion because the current line looks like it is selected in the headed list object.
; If the list is not $multipleselect, deselect all the list lines, then selected the clicked line.
If not(irListObj.$multipleselect)
Do iList.$search(kFalse)
Do iList.[pLineNumber].$selected.$assign(kTrue)
End If
; If there are no lines selected, select the current line.
If iList.$totc(#LSEL)=0
Do iList.[pLineNumber].$selected.$assign(kTrue)
Do $cobj.$redraw()
End If
If the user clicks below the last line in the headed list object, pLineNumber will be the current line in the list.
The $columnscontextmenu property is a runtime property which can be set using notation. It is a comma separated string of the columns that you wish to allow the user to show/hide by way of a context menu which they can open by right-clicking on any of the column headers.
; Enable the columns context menu for columns 1, 3, & 5.
Do irListObj.$columnscontextmenu.$assign('1,3,5')
If you want to enable the columns context menu for all of the columns you can do a loop for $colcount.
; Enable the columns context menu for all of the columns.
For Count from 1 to irListObj.$colcount step 1
Calculate CSVString as con(CSVString,',',Count)
End For
Calculate CSVString as trim(CSVString,kTrue,kTrue,',')
Do irListObj.$columnscontextmenu.$assign(CSVString)
$setsortcolumn(iColumnnumber,bDescending)
Sets the sort column for the headed list,and whether the direction is ascending or descending. This controls the drawing of the sort arrow. To clear the sort column, pass zero in iColumnnumber.
It appears that only one column can hav the sort arrow, so you can't use this to communicate multi-column sorting.
There doesn't appear to be a property to let you know which column has the sort arrow and whether the arrow is ascending or descending, so if you use the $setsortcolumn method you will need to keep track of the current state of ascending or descending.
Use the evHeaderClick event to trap when the user clicks on the header and pColumnNumber to set the sort column.
; Set the sort column when the user clicks the header.
On evHeaderClick
Do irListObj.$setsortcolumn(pColumnNumber,kFalse) ;; (,Descending)
Be sure to enable the header for the headed list object.
; Enable the columns header.
Do irListObj.$enableheader.$assign(kTrue)
Outlook Express (and I expect other programs) have the following behavior for headed list column heading clicks:
The oHeadedList_sort object class has been created to mimic the above behavior for headed lists in Omnis Studio.
Multiple List Sorting
You may want to allow users to do multiple column sorting on headed lists. The user would click one column heading, then click a second column heading, etc. The last column clicked would be the 1st column sort, the 2nd last column clicked the 2nd column sort, etc.
The oHeadedList_sort object supports 3 levels of multiple column sorting.
Communicating to the user multiple column sorting is difficult. Using icons and text the oHeadedList_sort object returns a text string which can be displayed to the user in a headed list footer.
Total, Selected, and Non-Selected Records
Users like to know the total number of records in a list. Sometimes if they selected multiple records in a list, it is nice to know then number of selected and non-selected records.
The oHeadedList_sort object also returns the total, selected, and non-selected records for display in the footer. If there is just 1 record in the list, the text is left blank. If there is just 1 record selected, only the number of records in the list is returned.
Click the oHeadedList_sort object class.
button in the to see a headed list which usesAfter you have tested the demo:
It is possible to edit the text in a headed list object. In order to use this feature you have to set the $maxeditchars property to a value greater than zero. You either do this under the tab of the list properties, or you can do it with notation.
; Set the maximum edit characters to allow list text to be edited.
Do irListObj.$maxeditchars.$assign(1000)
Once you have set the $maxeditchars to a value greater than zero the user can click on a line, then click again on a cell. The text in the cell will then become editable.
There are several $event messages which get sent to the headed list object when the user edits a cell. In all of these events pColumnNumber indicates the list object column number, and pLineNumber indicates the list object line number. The events occur in the following order.
On evHeadedListEditStarting
; Don't allow the user to edit columns 3 or 5.
If pColumnNumber=3|pColumnNumber=5
Quit event handler (Discard event)
End If
On evHeadedListEditFinishing
; Copy the new text to the list variable and redraw the list object.
; The following calculation ONLY works if the list object column numbers
; match the list variable column numbers. If not, you need code to map them.
Calculate iList.C[pColumnNumber] as pNewText
Do $cobj.$redraw()
I find it a tedious job to tinker around with my mouse and the property manager fine tuning headed lists. You can skip all that by using notation to set everything on the headed list.
In my applications, I have a window class method called $constructHeadedList which is called from the $construct method of the window.
If I want to change anything in the headed list, I simply go to the method $constructHeadedList change the code, and the next time the window is instantiated the change is done. I find that a lot faster than setting the properties in the . It also makes it easer to maintain the application later on.
The following sample code give you some ideas on the code you can include in the $constructHeadedList method.
; Set the number of columns
Do irListObj.$colcount.$assign(7)
; Set the column header text
Do irListObj.$columnnames.$assign('Qty,Desc,Cost Per,UM,Ext Price')
Do irListObj.$columnwidths.$assign('75,125,90,65,125') ;; Set the column widths
; Set the column alignment
Do irListObj.$setcolumnalign(1,kRightJst)
Do irListObj.$setcolumnalign(3,kRightJst)
Do irListObj.$setcolumnalign(4,kCenterJst)
Do irListObj.$setcolumnalign(5,kRightJst)
; Set the $calculation property to the correct column names
Calculate String as "con(iList.Qty,kTab,iList.Desc,kTab,iList.CostPer,ktab,iList.UM,ktab,jst(iList.Qty*iList.CostPer,'N2'))"
Do irListObj.$calculation.$assign(String)
; Allow multiple select.
Do irListObj.$multipleselect.$assign(kTrue)
Quit method kTrue
The following information is adapted from the Omnis Technical Note TNGI0002 by Nicky Mason.
Styles are used within lists to change the appearance of any cell in one of the Omnis list objects. The objects that can use styles are:
You can change the font style of a particular cell to be bold, italic or underlined on Windows platforms, or set any of the Mac styles, eg. Shadow or outline for Mac platforms. You can change the color of the text and you can even add an icon to the text.
Examples of how to use styles follow, basically the style is embedded within the text, so to add a line to a list, with the first column a normal number and the second with green coloured text, you would use the following code:
Do List.$add(5,con(style(kEscColor,kGreen),'Hello'))
To add an blue dot icon just before the text, you would use the following code:
Do List.$add(5,con(style(kEscBmp,1756),'Hello'))
To change the style of the text, you would use the following :
Do List.$add(5,con(style(kEscStyle,kBold),'Hello'))
To add multiple different styles to some text, you would use the following:
Do List.$add(5,con(style(kEscStyle,kBold),style(kEscBmp,1750),style(kEscColor,kMagenta),'Hello'))
If you wanted to change a line in the list based on a users action, then you could do the
following:
On evDoubleClick
Calculate List.ColName as con(style(kEscColor,kRed),List.ColName)
One solution is to create a display list variable (e.g. iDisplayList') which has the same columns as the real list variable, but all of the columns are kCharacter, then merge the data from the real list variable. Point the list object to the display list variable. Styles can be applied to the display list, leaving the original data list values alone.
Personally, I don't think using styles with the headed list object is a good idea. In my opinion you are better off to use the complex grid object.