How to (Properly) add a Repeater control to your Custom Elementor Add-On

Cover image

Elementor has a special type of control called a Repeater, which can contain other controls.
Repeaters create sub-items that are usually duplicatable, deletable, and can be used for any element which includes repetitive functionality, such as list widgets (Price List, Icon List) and Carousels (Media Carousel, Reviews).
This blog post will explain and demonstrate how to create and use repeaters – the right way.
We will take a look at and analyze the Icon List widget, which is a very clear example of creating and using a repeater properly.
Repeaters are created in the register_controls() method, along with all of the other widget controls.
To create a repeater, initialize an instance of the Repeater class:
$repeater = new \Elementor\Repeater();

If you intend to use more than one repeater in your widget/extension, you should of course use different variable names for the additional repeaters.
Once a repeater is initialized, you can add controls to it, in the following manner:

$repeater->add_control(
	'text',
	[
		'label' => __( 'Text', 'elementor' ),
		'type' => Controls_Manager::TEXT,
		'label_block' => true,
		'placeholder' => __( 'List Item', 'elementor' ),
		'default' => __( 'List Item', 'elementor' ),
		'dynamic' => [
			'active' => true,
		],
	]
);

The Repeater’s add_control() method is a slightly modified version of the “regular” add_control() method used in all Elementor widgets, but it accepts the exact same parameters.

Please note that the instance you created of the repeater class does NOT create the repeater control itself. Once you’ve added all the controls you want to be included in each repeater item, you need to add the repeater itself as a control to the widget:

$this->add_control(
	'icon_list',
	[
		'label' => __( 'Items', 'elementor' ),
		'type' => Controls_Manager::REPEATER,
		'fields' => $repeater->get_controls(),
		'default' => [
			[
				'text' => __( 'List Item #1', 'elementor' ),
				'selected_icon' => [
					'value' => 'fas fa-check',
					'library' => 'fa-solid',
				],
			],
			[
				'text' => __( 'List Item #2', 'elementor' ),
				'selected_icon' => [
					'value' => 'fas fa-times',
					'library' => 'fa-solid',
				],
			],
			[
				'text' => __( 'List Item #3', 'elementor' ),
				'selected_icon' => [
					'value' => 'fas fa-dot-circle',
					'library' => 'fa-solid',
				],
			],
		],
		'title_field' => '{{{ elementor.helpers.renderIcon( this, selected_icon, {}, "i", "panel" ) || \'<i class="{{ icon }}" aria-hidden="true"></i>\' }}} {{{ text }}}',
	]
);

Notice the control 'type' – it has to have a value of Controls_Manager::REPEATER.

Another important control argument to notice in the example above is the 'fields' argument. The 'fields' argument contains the controls to be included in each repeater unit. Since you added each of the repeater’s nested controls using the $repeater->add_control() method, they are easily available to you via the Controls Stack get_controls() method.

Also worth talking about is the 'default' argument. This argument enables creating default repeater items that will be included in the repeater items list automatically when the widget containing the repeater is added to a page/post. In this image to the right, you can see the three default items which are created based on the example above, when you first drag an Icon List widget into a page/post.

Important Note on an Alternative Way of Adding Nested Controls to Repeaters

In Elementor Pro, in the Form Integration mechanism, we used a different method for adding repeater controls. Instead of using the add_control method for each nested control of the repeater, we added an array of controls directly into the 'fields' arguments. Starting from Elementor 3.1.0, we won’t use this method of adding controls to repeaters any more. It will not be available for use, and any extension using it will probably stop functioning properly.

Author

Udi Dollberg
Udi Dollberg
Udi is a talented developer in Elementor’s Editor team and loves cars, woodworking and classic jazz.

11 Responses

    1. Hi Nir,
      Thank you for your observation and involvement in improving our docs.

      In the end of the paragraph above the example snippet for adding a control to a repeater, there is a line explaining that you need to initialize the repeater before registering controls to it, with the same example code you are looking for.

  1. Going from Elementor 2.6.x to 2.9.x, I noticed an issue with multiple repeater fields in a single control section. I received a “TypeError: Cannot read property ‘id’ of undefined” JS error when dragging/reordering the repeater fields around. The fix I did was to separate the repeater fields into its own control section. So it looks like this:

    [start_controls_section]
    — [repeater field stuff]
    [end_controls_section]

    [start_controls_section 2]
    — [repeater field stuff 2]
    [end_controls_section 2]

    Hope this helps anyone having this same issue!

    1. ‘title_field’ is what will appear at the top of the repeater field section.

      In his example, it is the icon and “List Item #” in each box (in the first and last image).

      For example, in the first image title_field is represented by:
      &check; List Item #1

  2. Hi
    Can this be used to create a repeater field in my form in the front end?
    I need my users to be able to add new rows (text)

    thanks

  3. hello when i include a repeater i have this warning message in my website :

    Warning: array_merge(): Expected parameter 2 to be an array, string given in /home/vcap/app/wordpress/wp-content/plugins/elementor/includes/managers/controls.php on line 705

    do any one have a solution fo this !!!

  4. If you update the page when you add/edit/remove only repeater fields, the changes are not saved. You *must* also change a non-repeater field or it won’t save to the database

Leave a Reply

Your email address will not be published. Required fields are marked *