TRepeater

API Manual

TRepeater displays its content repeatedly based on the data fetched from DataSource. The repeated contents in TRepeater are called items which are controls accessible through Items property. When dataBind() is invoked, TRepeater creates an item for each row of data and binds the data row to the item. Optionally, a repeater can have a header, a footer and/or separators between items.

The layout of the repeated contents are specified by inline templates. In particular, repeater items, header, footer, etc. are being instantiated with the corresponding templates when data is being bound to the repeater.

Since v3.1.0, the layout can also be specified by renderers. A renderer is a control class that can be instantiated as repeater items, header, etc. A renderer can thus be viewed as an external template (in fact, it can also be non-templated controls). A renderer can be any control class. By using item renderers, one can avoid writing long and messy templates. Since a renderer is a class, it also helps reusing templates that previously might be embedded within other templates. If implemented with one of the following interfaces, a renderer will be initialized with additional properties relevant to the repeater items:

  • IDataRenderer - the Data property will be set as the row of the data bound to the repeater item. Many PRADO controls implement this interface, such as TLabel, TTextBox, etc.
  • IItemDataRenderer - the ItemIndex property will be set as the zero-based index of the item in the repeater item collection, and the ItemType property as the item's type (such as TListItemType::Item). As a convenient base class, TRepeaterItemRenderer implements IDataItemRenderer and can have an associated template because it extends from TTemplateControl.

The following properties are used to specify different types of template and renderer for a repeater. If an item type is defined with both a template and a renderer, the latter takes precedence.

  • ItemTemplate, ItemRenderer - for each repeated row of data.
  • AlternatingItemTemplate, AlternatingItemRenderer: for each alternating row of data. If not set, ItemTemplate or ItemRenderer will be used instead, respectively.
  • HeaderTemplate, HeaderRenderer - for the repeater header.
  • FooterTemplate, FooterRenderer - for the repeater footer.
  • SeparatorTemplate, SeparatorRenderer - for content to be displayed between items.
  • EmptyTemplate, EmptyRenderer - used when data bound to the repeater is empty.

To populate data into the repeater items, set DataSource to a valid data object, such as array, TList, TMap, or a database table, and then call dataBind() for the repeater. That is,

class MyPage extends TPage {
    public function onLoad($param) {
        parent::onLoad($param);
        if(!$this->IsPostBack) {
            $this->Repeater->DataSource=$data;
            $this->Repeater->dataBind();
        }
    }
}

When dataBind() is called, TRepeater undergoes the following lifecycles for each row of data:

  1. create item based on templates or renderers
  2. set the row of data to the item
  3. raise an OnItemCreated event
  4. add the item as a child control
  5. call dataBind() of the item
  6. raise an OnItemDataBound event

Normally, you only need to bind the data to repeater when the page containing the repeater is initially requested. When the page is post back, the repeater will restore automatically all its contents, including items, header, footer and separators. However, the data row associated with each item will not be recovered and thus become null.

To access the repeater item data in postbacks, use one of the following ways:

  • Use DataKeys to obtain the data key associated with the specified repeater item and use the key to fetch the corresponding data from some persistent storage such as DB.
  • Save the whole dataset in viewstate, which will restore the dataset automatically upon postback. Be aware though, if the size of your dataset is big, your page size will become big. Some complex data may also have serializing problem if saved in viewstate.

TRepeater raises an OnItemCommand event whenever a button control within some repeater item raises a OnCommand event. Therefore, you can handle all sorts of OnCommand event in a central place by writing an event handler for OnItemCommand.

The following example shows how to use TRepeater to display tabular data.

TRepeater can be used in more complex situations. As an example, we show in the following how to use nested repeaters, i.e., repeater in repeater. This is commonly seen in presenting master-detail data. To use a repeater within another repeater, for an item for the outer repeater is created, we need to set the detail data source for the inner repeater. This can be achieved by responding to the OnItemDataBound event of the outer repeater. An OnItemDataBound event is raised each time an outer repeater item completes databinding. In the following example, we exploit another event of repeater called OnItemCreated, which is raised each time a repeater item (and its content) is newly created. We respond to this event by setting different background colors for repeater items to achieve alternating item background display. This saves us from writing an AlternatingItemTemplate for the repeaters.

Besides displaying data, TRepeater can also be used to collect data from users. Validation controls can be placed in TRepeater templates to verify that user inputs are valid.

The PRADO component composer demo is a good example of such usage. It uses a repeater to collect the component property and event definitions. Users can also delete or adjust the order of the properties and events, which is implemented by responding to the OnItemCommand event of repeater.

See in the following yet another example showing how to use repeater to collect user inputs.

This sample shows how to use "drop-in" item renderers, available since v3.1.0. These renderers come in the PRADO release. They are essentially controls implementing the IDataRenderer interface. Common Web controls, such as TTextBox, TLabel, all implement this interface. When such controls are used item renderers, their Data property is assigned with the row of the data being bound to the repeater item.

More often, one needs to customize the layout of repeater items. The sample above relies on OnItemCreated to adjust the appearance of the renderer. Templated item renderers are perferred in this situation, as they allow us to put in more complex layout and content in a repeater item. The following sample reimplements the nested repeater sample using a templated item renderer called RegionDisplay. As we can see, the new code is much easier to understand and maintain.