Class: cWebList

Properties  Events  Methods    Index of Classes

The Web Framework multi-row, multi-column list control

Hierarchy

cObject
---cWebObject
------cWebBaseUIObject
---------cWebBaseDEOServer
------------cWebBaseControl
---------------cWebList
------------------cWebGrid
------------------cWebHtmlList
------------------cWebPromptList

Library: Web Application Class Library

Package: cWebList.pkg

Description

Web list controls provide the basis for creating multi-row, multi-column display. Each column in a list is represented by a column object. cWebList objects use the cWebColumn, cWebColumnButton, cWebColumnCheckbox, cWebColumnCombo, cWebColumnDate, cWebColumnImage and cWebColumnLink classes for its column objects.



Lists are ideal for displaying and browsing a list of data with support for searching, sorting and selecting of rows in the list.

A list can be used with or without a data binding. When used with a data binding, the list rows and columns are populated from the data provided by the list's server data dictionary object. When used without a data binding, you will use the class interface to read or write the control value.

If you need to support editing the list data, then you should use the cWebGrid control instead.

If you need to show a list of data in a modal dialog, then return selected row information to the calling object, then you should use the cWebPromptList control, which has built-in support for these operations.

Topics





Object Name

The Web Framework uniquely identifies each web object via a combination of the object hierarchy (object nesting), and object name. This means that web object names must be unique within their parent (i.e. each sibling web object must have a unique name).

Object Placement

List controls must be placed within a web container (e.g. cWebPanel, cWebView or cWebModalDialog).

List controls may not be nested inside other web controls. You may not mix web panels and web controls as sibling objects.

Size and Location

Web controls are positioned by HTML flow layout (left to right, top to bottom). The relative position of the control in this flow is determined by the location of the object declaration in your code.

In addition to the flow layout, each web container is divided into a fixed number of equal-width layout columns (piColumnCount). Child controls are aligned to these layout columns to determine their horizontal position and width.

Set piColumnIndex to position a list control in a particular column of the parent container.

Set piColumnSpan to determine the width of the list control i.e., the number of layout columns occupied by the control. The actual width is determined by the number of columns and the width of the parent container.

For more information, see Positioning and Layout of Controls.

Each list control has a pre-determined minimum height according to the web application's CSS theme (psTheme). Set piHeight to set the list control to a fixed pixel height. You can also instruct a list control to occupy all available vertical height in its parent container by setting pbFillHeight to true.

The piHeight and pbFillHeight properties are mutually exclusive and should not be used together in the same object.

Ordering the Data

The ordering of the grid rows depends on how the data is served to the grid. This can be broken down into two categories: Data Aware Grids and Manually Loaded Grids.


Data Aware Lists

List objects support datasets served by a data dictionary object structure. The list's Server property specifies the list's connection to a DDO. By default, the list's server data dictionary is delegated to the Main_DD setting of the host view or dialog.

When the list has a data server, then each list column will support a data binding to a specific Table.Column from the data dictionary object structure. See cWebColumn for more information.

A data binding automatically provides the control's data type, tooltip and much more. These settings may also be controlled manually by setting properties.

Each time a request is processed by a view (or dialog), the list's psCurrentRowID property is set to the RowID of the list's currently selected row on the client. Use psCurrentRowID to retrieve the currently selected row.

The list object's pbDataAware property must be set to true in order for the control work with a data dictionary object structure. For more information, see "Manually Loaded Lists" below.

If pbDataAware = True and peDbGridType <> gtManual, then the grid is "data-aware" and it is populated automatically by the attached Server DDO.

When working with data-aware lists, follow these guidelines for controlling index order:

1. Use piSortColumn to control index order

2. Always set an initial piSortColumn value

3. If you need to further control index order, augment the IndexOrder function

4. Do not set these properties:


See Indexes and Ordering with Data Aware cWebLists for a more complete description of this process.

Sample

This sample demonstrates a data aware list. A web view (cWebView) object contains a DataDictionary object (DDO) and a list (cWebList) whose rows and columns are populated automatically from the data dictionary.

Object oCustomers is a cWebView
    Object oCustomer_DD is a Customer_DataDictionary
    End_Object

    Set Main_DD to oCustomer_DD
    Set Server to oCustomer_DD
    
    Procedure OnLoad
        Send Find of oCustomer_DD FIRST_RECORD 1
    End_Procedure

    Object oCustomerList is a cWebList
        Set pbFillHeight to True
                      
        Object oCustomer_Name is a cWebColumn
            Entry_Item Customer.Name
            Set psCaption to "Customer Name"
            Set piWidth to 50
        End_Object
    
        Object oCustomer_City is a cWebColumn
            Entry_Item Customer.City
            Set psCaption to "City"
            Set piWidth to 50
        End_Object
    
        Object oCustomer_State is a cWebColumnCombo
            Entry_Item Customer.State
            Set psCaption to "State"
            Set piWidth to 40
        End_Object
    
        Object oCustomer_Status is a cWebColumnCheckBox
            Entry_Item Customer.Status
            Set psCaption to "Active"
            Set piWidth to 15
        End_Object
    End_Object
End_Object

The list contains four column objects, each with a data binding to the Customer table. Two cWebColumn objects are used to display the customer name and city text values; a cWebColumnCombo object is used to display a list of combo items to display and select a state; a cWebColumnCheckbox object is used to display the customer active status in a column of checkboxes.

The OnLoad event is fired when the view is first loaded to the client. This has been augmented to 'seed' the Customer data dictionary with the first record in the table. This seeding will cause the list to fill its rows with data from the customer table starting with the record found in the OnLoad event.


Row IDs and Web Lists/Grids

When the grid or list is data-aware, then the RowID that is stored for each row is the same as the database record's RowID, i.e. the database record row ID is the value stored in the grid row ID.

If the grid or list is not data-aware, then the RowID that is stored for each row is simply a unique row id determined by the developer.


Manually Loaded Lists

Set pbDataAware to False or peDbGridType to gtManual if you want to populate a list object programmatically, i.e. without using DataDictionary objects or data-bound columns. In this case, you will need to implement the list's OnManualLoadData event to populate the rows and columns with your desired data.

The OnManualLoadData event passes back an array of tWebRow structs, where each array member represents a row of column data for the list. The order of array members will determine the order of rows. The tWebRow - aCells member is the array you will need to populate to represent the column values for each row. The 0th member of this array represents the leftmost column. The sRowId member is populated with a value that is unique for each row.

You must provide a unique RowId for each row in a manually loaded list, or numerous list features simply won't work or won't work right. When using a data-bound list, this is handled for you by the DataDictionary, with manual lists, it is the developer's responsibility to provide unique RowIds.

The OnManualLoadData event is not automatically fired. You will need to write code in your view to trigger it. Typically you would augment the list's OnLoad event to do this by signaling the client to perform a GridRefresh, for example:

Procedure OnLoad
    Forward Send OnLoad    
    Send GridRefresh
End_Procedure

Refer to the Sample section below for an example demonstrating how to manually populate a grid.

Once the grid data has been loaded and displayed on the client, you may need to make specific changes to some of its data. Use the DataSetAppendRow, DataSetInsertRowBefore, DataSetRemoveRow and DataSetUpdateRow helper methods to manipulate the data of a manually loaded grid.

When working with manually loaded lists, you may need access to the full set of list data. You can call ProcessDataSet to do so.

Sample

This sample demonstrates a list whose rows are 'manually' populated with data. We call this a non-data aware list, i.e. it is not connected to any data dictionary Server and its columns do not have any data binding.

Use cWebView.pkg
Use cWebPanel.pkg
Use cWebForm.pkg 
Use cWebList.pkg
Use cWebColumn.pkg

Object oManualWebListView is a cWebView
    Set piWidth to 400
    Set piHeight to 320
    Set psCaption to "Planets List"


    // Your DDO structure will go here

    Object oWebMainPanel is a cWebPanel
        Set piColumnCount to 12
        
        // place controls here.
        // Your view will grow as controls are added
        Object oPlanetsList is a cWebList
            Set pbFillHeight to True
            Set pbDataAware to False
            
            Object oPlanetColumn is a cWebColumn
                Set psCaption to "Planet"
            End_Object
    
            Object oDistanceColumn is a cWebColumn
                Set psCaption to "Distance from Sun"
                Set peAlign to alignRight
                Set peDataType to typeNumber
                Set psMask to "*.## AU"
            End_Object
    
            Procedure OnManualLoadData tWebRow[] ByRef aTheRows String ByRef sCurrentRowID
                Integer iNum
                
                Forward Send OnManualLoadData (&aTheRows) (&sCurrentRowID)
                
                Move 0 to iNum
                Move iNum       to aTheRows[iNum].sRowID
                Move "Planet"   to aTheRows[iNum].sCssClassName
                Move "Mercury"  to aTheRows[iNum].aCells[0].sValue
                Move (ConvertToClient(typeNumber, 0.387)) to aTheRows[iNum].aCells[1].sValue
                
                Increment iNum
                Move iNum       to aTheRows[iNum].sRowID
                Move "Planet"   to aTheRows[iNum].sCssClassName
                Move "Venus"    to aTheRows[iNum].aCells[0].sValue
                Move (ConvertToClient(typeNumber, 0.722)) to aTheRows[iNum].aCells[1].sValue
                
                Increment iNum
                Move iNum       to aTheRows[iNum].sRowID
                Move "Planet"   to aTheRows[iNum].sCssClassName
                Move "Mars"     to aTheRows[iNum].aCells[0].sValue
                Move (ConvertToClient(typeNumber, 1.52)) to aTheRows[iNum].aCells[1].sValue
                
                Increment iNum
                Move iNum       to aTheRows[iNum].sRowID
                Move "Planet"   to aTheRows[iNum].sCssClassName
                Move "Jupiter"  to aTheRows[iNum].aCells[0].sValue
                Move (ConvertToClient(typeNumber, 5.2)) to aTheRows[iNum].aCells[1].sValue
            End_Procedure
        End_Object
    
        Procedure OnLoad
            Forward Send OnLoad
            Send GridRefresh to oPlanetsList
        End_Procedure

    End_Object 

End_Object

In this example, GridRefresh is sent during the cWebView object's OnLoad event. This means that just before the view is sent to the client, GridRefresh will be sent. Since pbDataAware is False, the GridRefresh will trigger the OnManualLoadData event where the logic for populating the row data is implemented.

Within OnManualLoadData: aTheRows is an array of tWebRow structs that is populated to give the grid its data. The sRowId member is populated with a value that is unique for each row. The actual data to display in the grid is stored in the aCells array member.

Special attention is needed when populating a column whose data type (peDataType) is typeNumber, typeDate or typeDateTime, to ensure the values are sent to the client in a standard format. This is performed by applying the ConvertToClient function to each value.

Manually Loaded Grids

Set pbDataAware to False if you want to populate a grid object programmatically, i.e. without using data dictionary objects or data-bound columns. In this case you will need to implement the grid's OnManualLoadData event to populate the rows and columns with your desired data.

The OnManualLoadData event passes back an array of tWebRow structs where each array member represents a row of column data for the list. The order of array members will determine the order of rows.

The tWebRow - aValues member is the array you will need to populate to represent the column values for each row. The 0th member of this array represents a unique row identifier. You may set this to any value you wish but you must ensure that each row has a unique value. The remaining values in this member represent the values to be displayed in each column from left to right.

The OnManualLoadData event is not automatically fired. You will need to write code in your view to trigger it. Typically you would augment the grid's OnLoad event to do this by signaling the client to perform a GridRefresh, for example:

Procedure OnLoad
    Forward Send OnLoad    
    Send GridRefresh
End_Procedure

See below for information on saving a manually loaded grid.

For information about manually loading a data aware grid refer to the help section on Web Framework Lists & Grids.


Changing Rows

Use the following interface to programmatically manipulate the currently selected row:

Send MoveToFirstRow to make the first row the selected row.
Send MoveToLastRow to make the last row the selected row.
Send MovePageUp to select the row one page up. The size of a page depends on the height of the list.
Send MovePageDown to select the row one page down. The size of a page depends on the height of the list.
Send MoveUpRow to select the previous row.
Send MoveDownRow to select the next row.
Send MoveToRow to select a specific row by its row index.
Send MoveToRowByID to selects a specific row by its RowId.


Configurable Column Layout

The cWebList and cWebGrid classes allow for a configurable column layout, which inlcudes moving and hiding columns.

pbAllowColumnReordering determines whether columns can be reordered by dragging them to a different position. Dragging is done by picking up the column by its header.

pbAllowColumnHiding determines whether columns can be hidden. Hiding can be done using a context menu on the header or by dragging them outside of the grid.

pbStoreColumnLayout indicates whetehr the column layout is automatically stored locally on the client using local storage. When the application / view is loaded, it will check and automatically apply a stored layout.


Searching

List objects support a search capability. If the list object has the focus then simply begin typing the row value you are looking for. This pops-up a search window where you can continue typing the value that you are searching for. The search value is used to locate the closest matching row according to the current sort order of list rows.

Set pbAutoSearch to false to disable the automatic search capability.

Send Search to programmatically pop-up the search dialog to initiate a search.

OnChangeCurrentRow Event

By default, the list class does not send the OnChangeCurrentRow event to the server each time the currently selected row is changed. This is to optimize the performance of row selection in the cWebList class.

Set pbOfflineEditing to true to enable OnChangeCurrentRow events.

Drag and Drop Support

Drag Support

This control allows parts of itself to be picked up and dragged to other places in your interface. To do this, register it as a drag source in a cWebDragDropHelper.

Supported drag actions for this control are:
- C_WebDragListRow

Drop Support

This control can be used as a valid drop target by registering it as such in a cWebDragDropHelper object.

The supported drop actions for this control are:
- C_WebDropOnControl, C_WebDropListRow

File Drop Support

This allows the control to accept data dragged from elsewhere in the control (if configured that way) and can also be used to accept files when registered within a cWebDragDropFileHelper.


Appearance

The colors used by a list (or grid) control are determined by the web application's CSS theme (psTheme). You can define additional or replacement CSS styles in your web application's application.css file.

Set psCSSClass to the CSS class you would like to be applied to the overall list control.

Implement the OnDefineRowCssClass even to apply individual CSS styles to each row.

Each column class defines additional properties and events for applying special CSS styles to the column.

See Also

Styling Web Applications