Go to homepage

Projects /

Repeater

A plugin to repeat groups of elements.

View Demo

How to

The Repeater Plugin can be used to clone and delete a collection of items.

The element with a class of .js-repeater__item will be repeated each time the user clicks on the .js-repeater__add button; the new element is appended to the .js-repeater__list element.

<div class="js-repeater">
  <ul class="js-repeater__list">
    <li class="js-repeater__item">
      <!-- content to be repeated here -->
    </li>
  </ul>

  <button class="js-repeater__add" type="button">Add More</button>
</div>

Use a button with a class of .js-repeater__remove inside the .js-repeater__item element to have the option of removing clones.

If you want to add a custom class to the cloned elements, add a data-repeater-class attribute to the .js-repeater element:

<div class="js-repeater" data-repeater-class="repeater__item">
  <ul class="js-repeater__list">
    <li class="js-repeater__item">
      <!-- content to be repeated here -->
    </li>
  </ul>

  <button class="js-repeater__add" type="button">Add More</button>
</div>

For example, you can use this class to show the .js-repeater__remove button for clones, while keeping it hidden for the first item.

Form fields repeater #

If you are using this component to clone form fields, then each clone must have input elements with different name/id attributes.

For the plugin to work properly, all your inputs should have name and id values equal to customName[n][inputType], where:

  • customName: a custom label of your choice (same value for all your input elements);
  • n: index of the cloned element (starting from 0);
  • inputType: a custom label that identifies the input.

Add to the .js-repeater element a data-repeater-input-name attribute equal to customName[n].

Here's an example of a repeater for a user name/email block:

<div class="js-repeater" data-repeater-input-name="user[n]">
  <div class="js-repeater__list">
    <fieldset class="js-repeater__item">
      <div>
        <label for="user[0][name]">Name</label>
        <input type="text" name="user[0][name]" id="user[0][name]">
      </div>
  
      <div>
        <label for="user[0][email]">Email</label>
        <input type="email" name="user[0][email]" id="user[0][email]">
      </div>
    </fieldset>

    <!-- example of a cloned element -> [n] is now [1] -->
    <fieldset class="js-repeater__item">
      <div>
        <label for="user[1][name]">Name</label>
        <input type="text" name="user[1][name]" id="user[1][name]">
      </div>
  
      <div>
        <label for="user[1][email]">Email</label>
        <input type="email" name="user[1][email]" id="user[1][email]">
      </div>
    </fieldset>
  </div>

  <button class="btn btn--primary js-repeater__add" type="button">Add More</button>
</div>

Note that we have added a type="button" to the .js-repeater__add element. This will prevent the form from being submitted when the user clicks the button.

Default Values #

By default, the value of each cloned input element is set to empty. If you want to use a different default value, use the data-default attribute:

<div class="js-repeater" data-repeater-input-name="user[n]">
  <div class="js-repeater__list">
    <fieldset class="js-repeater__item">
      <div>
        <label for="user[0][name]">Name</label>
        <input type="text" name="user[0][name]" id="user[0][name]">
      </div>
  
      <div>
        <label for="user[0][email]">Email</label>
        <input type="email" name="user[0][email]" id="user[0][email]" data-default="[email protected]">
      </div>
    </fieldset>
  </div>

  <button class="btn btn--primary js-repeater__add" type="button">Add More</button>
</div>

If you are using radio or checkbox elements and you want to set their default status to checked, use data-default="true":

<div>
  <label for="user[0][newsletter]">Subscribe me</label>
  <input type="checkbox" name="user[0][newsletter]" id="user[0][newsletter]" data-default="true">
</div>

Dynamic Content #

Each time a js-repeater__item is cloned, the itemCloned custom event is emitted. Use this event to initialize the content of the cloned element if required:

var repeater = document.getElementsByClassName('js-repeater');
if(repeater.length > 0) {
  repeater[0].addEventListener('itemCloned', function(event) {
    // event.datail -> cloned element
  });
}

For example, if your cloned element includes an Input Number:

var repeater = document.getElementsByClassName('js-repeater');
if(repeater.length > 0) {
  repeater[0].addEventListener('itemCloned', function(event) {
    initDynamicInput(event.detail);
  });
}

function initDynamicInput(element) {
  var inputNumber = element.getElementsByClassName('js-number-input');
  for(var i = 0; i < inputNumber.length; i++) {
    new InputNumber(inputNumber[i]);
  }
};

Categories

Bug report & feedback

Component Github page ↗

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.