# GvaScript.Repeat

Support for repeated sections

### Table of contents

NAME
SYNOPSIS
DESCRIPTION
Terminology
HTML
Markup of repeat elements
String substitutions within repeat elements
METHODS
init
add
EVENTS
onRepeat

## NAME

GvaScript.Repeat - Support for repeated sections

## SYNOPSIS

      <div repeat="foo">
        <h2>Foo #{foo.ix}</h2>
        This is the repeated foo section
        <table>
          <tr repeat="bar">
            <td>Item #{bar.ix}</td>
            <td><input name="#{bar.path}.buz"></td>
          </tr>
        </table>
         <button onclick="GvaScript.Repeat.add('#{foo.path}.bar')">Add a bar</button>
      </div>
      <button onclick="GvaScript.Repeat.add('foo')">Add a foo</button>

      <script>
        GvaScript.Repeat.init(document.body);
      </script

## DESCRIPTION

Implements a mechanism for repeated elements within an HTML page. The main use is within forms, for dynamic expansion of subforms (see Alien::GvaScript::Form); however the mechanism will work for any kind of HTML element.

### Terminology

At initialization stage, the DOM is inspected for finding repeat elements (elements having a `repeat` attribute). These elements are removed from the DOM and replaced by placeholders (empty DOM elements, just marking where the repetition blocks should be inserted). Each placeholder stores a template, which is a plain string representation of the repeat element, with special markup for template instanciation. The template may then be dynamically instanciated into repetition blocks by calling the /add method.

     - can be nested
     - inspired by Web Forms

## HTML

### Markup of repeat elements

      <div repeat="foo" repeat-start="3" repeat-min="2" repeat-max="6"
                        repeat-prefix="">
        <!-- content to be repeated, using #{foo.ix}, #{foo.path}, etc. -->
      </div>

Any element marked with a non-empty `repeat` attribute is a repeat element; the value of that attribute defines the repeat name. Other attributes are optional. Here is the complete list of repeat attributes :

- repeat

  marks the element as a repeat element, and defines the repeat name.

- repeat-start

  defines how many repetition blocks should be automatically created as initialization time. Default is 1.

- repeat-min

  minimum number of repetition blocks. Prevents deletion of repetition blocks under that number. Default is 1.

- repeat-max

  maximum number of repetition blocks. Prevents addition of repetition blocks over that number. Default is 99.

- repeat-prefix

  defines the initial fragment of the `repeat path` (see explanation below). Only valid for top-level repetition elements, because nested repetition elements are automatically prefixed by their parent repetition element. Default is the empty string.

### String substitutions within repeat elements

The content of a repeat element may contain special markup for repetition variables, which will be replaced by values when the element is instanciated into a repetition block.

Variables are written `#{<repetition name>.<variable>}`, like for example `#{foo.ix}` or `#{bar.path}`. The repetition name is the value of the `repeat` attribute of the repeat element, as explained above; in this namespace, the following variables are defined

- ix

  integer index of the current repetition block, starting at 1.

- path

  cumulated list of repetition name and repetition indices, separated by dots.

- count

  current number of repetition blocks for that repeat element.

- min

  value of the `repeat-min` attribute.

- max

  value of the `repeat-max` attribute.

The `path` is unique within any nesting of repeat elements, and therefore is typically used for ids or for names of input elements :

      <tr repeat="bar">
        <td>Item #{bar.ix}</td>
        <td><input name="#{bar.path}.buz"></td>
      </tr>

Within the 3rd repetition block of `bar`, nested within the 2nd repetition block of `foo`, the value of `#{bar.path}` will be `foo.2.bar.3` and therefore in this example the input name would be `foo.2.bar.3.buz`.

Implementation note: the `#{...}` syntax for variables is borrowed from `prototype.js`'s `Template` class; however, the implementation of substitutions is done in plain javascript, without calling `Template.evaluate()` method.

## METHODS

### init

      GvaScript.Repeat.init(element)

Walks down the DOM under the given element, finds all elements having a `repeat` attribute, replaces these by placeholders.

The `element` argument will be fed to `prototype.js`'s `$()` function, so it can be either a DOM element or an id string.

### add

      GvaScript.Repeat.add(repeat_name)

Creates a new repetition block in the DOM, by instanciating the repeat element `repeat_name` (including prefix). So if the repeat structure looks like

      <div repeat="foo" repeat-prefix="top">
         <div repeat="bar">

then a new `foo` repetition block is instanciated through `add('top.foo')`, and a new `bar` repetition block is instanciated through `add('#{foo.path}.bar')`.

## EVENTS

### onRepeat