Duplication

Using Duplication you can take a single element and produce new elements based on it. A plain Duplication will simply clone the target element a given number of times. However, you can also pass a modification, which is a Spell to be applied during each Duplication.

All this is wrapped into Element's method foreachIn(Collection) whose usage is shown below.


<div>
  <h3>Receipt</h3>
  <ul class="receipt">
    <li>
      <span class="item">Milk</span>
      <span class="price">0.99 €</span>
    </li>
  </ul>
</div>

+

val items = List("Bread" -> 1.99, "Butter" -> 0.49, "Jam" -> 1.00)

$("ul.receipt li").foreachIn(items) { case (li, (item, price)) =>
  li.insert(" - ")
  li.get(".item").text = item
  li.get(".price").text = price+" €"
}

As its second argument the method expects a function which takes a SelectableElement firstly and an item from the collection secondly. If you leave the body of that function empty it will translate to a plain Duplication, which merely clones the target element without changing it. You could then simply write e.clone(3) instead.

The SelectableElement can be used to modify the target element itself and to select child elements to modify them, too.

List<String[]> items = Arrays.asList(
    new String[] { "Bread", "1.99" },
    new String[] { "Butter", "0.49" },
    new String[] { "Jam", "1.00" });

get("ul.receipt li").foreachIn(items).apply(new Plan<String[]>() {
    public void execute(SelectableElement li, final String[] item) {
        li.insert(" - ");
        li.get(".item").getText().setContent(item[0]);
        li.get(".price").getText().setContent(item[1] + " €");
    }
});

The first argument to foreachIn is the collection of items for which the target element gets duplicated. There is an optional second parameter which plays a role with Reductions.
The method returns an object providing a method apply which takes a Plan describing what to do during each duplication.

||

<div>
  <h3>Receipt</h3>
  <ul class="receipt">
    <li> -
      <span class="item">Bread</span>
      <span class="price">1.99 €</span>
    </li>
    <li> -
      <span class="item">Butter</span>
      <span class="price">0.50 €</span>
    </li>
    <li> -
      <span class="item">Jam</span>
      <span class="price">1.00 €</span>
    </li>
  </ul>
</div>


There is also a method foreachWithIndexIn(Collection) which in addition to the current item of the collection passes the item's index within the sequence of duplications.

In order to implement the foreach functionality Duplication actually has to be combined with a couple of 'utility Spells' which are not further discussed here. You can find all Spells in the API Doc, though.