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')
.