Repeater

in namespace DotVVM.Framework.Controls

Repeats a template for each item in the DataSource collection.

Usage & Scenarios

Repeats a template for each item in the DataSource collection.

Sample 1: Basic Repeater

The DataSource points to an IEnumerable or a GridViewDataSet object.

Inside the ItemTemplate, you can use _this to access the current data item.

<dot:Repeater DataSource="{value: Items}">
  <ItemTemplate>
    {{value: _this}}<br />
  </ItemTemplate>
</dot:Repeater>
using DotVVM.Framework.ViewModel;

namespace DotvvmWeb.Views.Docs.Controls.builtin.Repeater.sample1
{
    public class ViewModel : DotvvmViewModelBase
    {
        public string[] Items { get; set; } = { "First", "Second", "Third" };

    }
}

Sample 2: Wrapper Tag Customization

If you don't want to render <div>, just change the WrapperTagName property to something else. Or, set the RenderWrapperTag property to false if you don't want to render any wrapper tag.

<dot:Repeater DataSource="{value: Items}" WrapperTagName="ul">
    <ItemTemplate>
        <li>{{value: _this}}</li>
    </ItemTemplate>
</dot:Repeater>
using DotVVM.Framework.ViewModel;

namespace DotvvmWeb.Views.Docs.Controls.builtin.Repeater.sample2
{
    public class ViewModel : DotvvmViewModelBase
    {
        public string[] Items { get; set; } = { "First", "Second", "Third" };

    }
}

Sample 3: Real World Sample

A simple task list.

@viewModel DotvvmWeb.Views.Docs.Controls.builtin.Repeater.sample3.ViewModel, DotvvmWeb

<p>
    Create a new task: 
    <dot:TextBox Text="{value: NewTaskTitle}" /> 
    <dot:Button Text="Add" Click="{command: AddTask()}" />
</p>

<dot:Repeater DataSource="{value: Tasks}" WrapperTagName="table">
    <ItemTemplate>
        <tr>
            <td>{{value: Title}}</td>
            <td>{{value: Completed ? ("Finished: " + CompletionDate) : "Not yet"}}</td>
            <td>
                <dot:LinkButton Text="Done" 
                                Click="{command: CompleteTask()}" 
                                Visible="{value: !Completed}" />
            </td>
        </tr>
    </ItemTemplate>
</dot:Repeater>
using System;
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;

namespace DotvvmWeb.Views.Docs.Controls.builtin.Repeater.sample3
{
    public class ViewModel : DotvvmViewModelBase
    {
        public List<MyTask> Tasks { get; set; } = new List<MyTask>();

        public string NewTaskTitle { get; set; }

        public ViewModel()
        {
            Tasks.Add(new MyTask("Install the DotVVM VS Extension"));
            Tasks.Add(new MyTask("Create the first project"));
            Tasks.Add(new MyTask("Build your first app"));
            Tasks.Add(new MyTask("Buy Professional Edition of DotVVM VS Extension"));
        }

        public void AddTask()
        {
            Tasks.Add(new MyTask(NewTaskTitle));
            NewTaskTitle = null;
        }

    }

    public class MyTask
    {
        public string Title { get; set; }

        public bool Completed { get; set; } = false;

        public string CompletionDate { get; set; }

        public MyTask(string title)
        {
            Title = title;
        }

        public MyTask()
        {

        }

        public void CompleteTask()
        {
            Completed = true;
            CompletionDate = DateTime.Now.ToString();
        }
    }
}

Properties

Name Type Description Notes Default Value
property icon DataSource Object Gets or sets the source collection or a GridViewDataSet that contains data in the control.
attribute
inner element
static value
bindable
default
null
property icon EmptyDataTemplate ITemplate Gets or sets the template which will be displayed when the DataSource is empty.
attribute
inner element
static value
bindable
default
null
property icon ItemTemplate ITemplate Gets or sets the template for each Repeater item.
attribute
inner element
static value
bindable
default
null
property icon RenderAsNamedTemplate Boolean Gets or sets if the repeater should use inline template (the default, traditional way of doing things) or if it should use Knockout's named template (with the template in <script> tag).
attribute
inner element
static value
bindable
default
True
property icon RenderWrapperTag Boolean Gets or sets whether the control should render a wrapper element.
attribute
inner element
static value
bindable
default
True
property icon SeparatorTemplate ITemplate Gets or sets the template containing the elements that separate items.
attribute
inner element
static value
bindable
default
null
property icon WrapperTagName String Gets or sets the name of the tag that wraps the Repeater.
attribute
inner element
static value
bindable
default
div

HTML produced by the control

You can define, what tag the Repeater renders, using the WrapperTagName. The default is div:

<dot:Repeater DataSource="{value: Items}">
    <ItemTemplate>
        <p>{{value: Name}}</p>
    </ItemTemplate>
</dot:Repeater>

<!-- Client rendering mode -->
<div data-bind="template: { name: "hashOfTheTemplateContent", data = ...}">
</div>
<template id="hashOfTheTemplateContent">
    <p><span data-bind="..."></span></p>
</template>

<!-- Server rendering mode -->
<div>
    <p>Jim Hacker</p>
    <p>Humphrey Appleby</p>
    <p>Bernard Woolley</p>
</div>

The ItemTemplate is default element property and so the <ItemTemplate> element can be omitted if it's the only one inside the Repeater control.

Using the RenderWrapperTag you can turn off the wrapper tag. The Knockout comments will then be used in the client rendering mode:

<!-- ko foreach: ... -->
<p><span data-bind="..."></span></p>
<!-- /ko -->

Be careful. Knockout comment bindings don't work well if they are directly in the <table> element. Put the Repeater inside the <tbody> element and it will work.

From DotVVM 4.0, the Repeater control renders the <template> element by default instead of rendering the template inside the wrapper tag. If you want to fall back to the previous behavior, set the RenderAsNamedTemplate property to false.