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.
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).
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.
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.
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.
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.
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.
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.
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.
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.sValue Move (ConvertToClient(typeNumber, 0.387)) to aTheRows[iNum].aCells.sValue Increment iNum Move iNum to aTheRows[iNum].sRowID Move "Planet" to aTheRows[iNum].sCssClassName Move "Venus" to aTheRows[iNum].aCells.sValue Move (ConvertToClient(typeNumber, 0.722)) to aTheRows[iNum].aCells.sValue Increment iNum Move iNum to aTheRows[iNum].sRowID Move "Planet" to aTheRows[iNum].sCssClassName Move "Mars" to aTheRows[iNum].aCells.sValue Move (ConvertToClient(typeNumber, 1.52)) to aTheRows[iNum].aCells.sValue Increment iNum Move iNum to aTheRows[iNum].sRowID Move "Planet" to aTheRows[iNum].sCssClassName Move "Jupiter" to aTheRows[iNum].aCells.sValue Move (ConvertToClient(typeNumber, 5.2)) to aTheRows[iNum].aCells.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.
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.
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.
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.
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.
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.
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:
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
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.
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.
Styling Web Applications