Omnis Technical Note TNWE0025 March 2010

Multiple Selections in Web Tree Objects

for Omnis Studio 4/5
By Andreas Pfeiffer

Multiple Selections in Web Tree Objects

For Omnis Studio 4/5
By Andreas Pfeiffer

Normally the Web Tree Control in Omnis Studio does not support multiple selections, but with a little trick you can force the Web Tree Control to allow multiple selections.

Creating the data format for the Web Tree Control is different to the Tree control for the thick client version of Omnis, so the data is not created with the method $setnodelist(). You can in fact assign a structured list directly to the $dataname of the Web Tree Control. The structure of the list depends on how the $datamode property of the component is set, that is, you can set it to either kTreeData FlatList or kTreeDataFlatListWithTags. (Note the other data mode constants are reserved for the oXML component.)

In the following example, I decided to use the option "withTags" since it has the advantage of being able to store application specific information as well as the tree structure. You can define a list for the example using the following code, which can be placed in the $construct() method of the remote form; note the list has eight columns, each with a specific data type:

Do iTreeList.$cols.$add('col1',kCharacter,kSimplechar,255)
Do iTreeList.$cols.$add('col2',kCharacter,kSimplechar,255)
Do iTreeList.$cols.$add('iconid',kInteger,kLongint)
Do iTreeList.$cols.$add('ident',kInteger,kLongint)
Do iTreeList.$cols.$add('enterable',kInteger,kShortint)
Do iTreeList.$cols.$add('expand',kInteger,kShortint)
Do iTreeList.$cols.$add('textcolor',kInteger,kLongint)
Do iTreeList.$cols.$add('tag',kInteger,kLongint)

For the purposes of this example, I entered some data in the list using the following code. (Normally you would fetch the data from a database and add the lines with $mergelist into the list iTreeList.):

Do iTreeList.$add('root','',iUncheckedIcon,,1)
Do iTreeList.$add('root','item1',iUncheckedIcon,,1)
Do iTreeList.$add('root','item2',iUncheckedIcon,,1)
Do iTreeList.$add('root','item3',iUncheckedIcon,,1)
Do iTreeList.$add('root2','',iUncheckedIcon,,1)
Do iTreeList.$add('root2','item1',iUncheckedIcon,,1)
Do iTreeList.$add('root2','item2',iUncheckedIcon,,1)
Do iTreeList.$add('root2','item3',iUncheckedIcon,,1)

In the form I have got two instance variables "iCheckedIcon" and "iUncheckedIcon". I have assigned the initia values to them like this (in the Variable definition pane in the method editor):

iCheckedIcon = Long Integer, Init. Val =1832+k16x16
iUncheckedIcon = Long Integer, Init. Val =206+k16x16

Both values (1832 and 206) each represent the Omnis Icon ID for the selected and for the not selected icon. Please note that these values must be added with the size constant "k16xk16". You can use any icons for this, so long as they are 16 x 16 pixels, they are included in the #ICONS or in one of the two icon datafiles (Userpic.df1 or Omnispic.df1), and they must have a unique Icon ID. Please note also that the Icon Page containing the icons in the remote form must be included in $iconpages property to make sure they can be assigned to the client. So for our example, you have to add the icon pages "Toolbar Components" and "Multistate 2" from the Omnispic icon datafile to the $iconpages property of the remote form, to include the icons with IDs 1832 and 206.

As an additional little trick I have entered the row number in the "ident" column:

Do iTreeList.$sendall($ref.ident.$assign($sendallref.$line))

This enables us to easily synchronise the list with the Tree component. Alternatively you can of course write a real Ident into this column as long as this is unique in the entire tree list.

And when it is ready filled with data our list looks like this:

webtree list

When you add this list to a Web Tree component in the $dataname you will see it as a multiple select list if the property $datamode of the component is set to kTreeDataFlat ListWithTags.

Please note that the "expand" column of the list in each row is set to 0. Thereby the entire tree is collapsed. In the $event method of the web tree component, we have to synchronise the list variable with the tree accordingly.

Remember you have to add the evWTreeNodeExpand, evWTreeNodeCollapse, and evWTreeIconClick events to the $events property of the web tree control; without doing this the events will not be reported.

When a node in the tree is expanded the "expand" property has to be set to 2:

On evWTreeNodeExpand
 Do iTreeList.$search($ref.ident=pNodeIdent,kTrue,kFalse,kFalse,kFalse)
 Do iTreeList.expand.$assign(2)

This prevents the tree collapsing at a "$redraw()". "pNodeIdent" is an event parameter that returns the Ident of the current selected node. In return we must of course set the "expand" property back when the node is collapsed again.

On evWTreeNodeCollapse
 Do iTreeList.$search($ref.ident=pNodeIdent,kTrue,kFalse,kFalse,kFalse)
 Do iTreeList.expand.$assign(0)

In the end we switch the Icon ID in the list, depending on whether the row found has already been selected or not. Afterwards the row in the list is selected and de-selected respectively. Thus the selection of the list is synchronised with expanding the node in the Tree component:

On evWTreeIconClick
 Do iTreeList.$search($ref.ident=pNodeIdent,kTrue,kFalse,kFalse,kFalse)
 Do iTreeList.iconid.$assign(pick(
      iTreeList.$selected,iCheckedIcon,iUncheckedIcon))
 Do iTreeList.$selected.$assign(not(iTreeList.$selected))
 Do $cinst.$redraw()

Depending on the selection of a row in the list, the pick() function returns either the Icon number for iCheckedIcon or for iUncheckedIcon.

The completed tree should look like this; note we have adjusted the setting of $treeidentlevel to space out the icons and node text a little better:

webtree

Click here to download a sample library. (Studio 5 library only)