Drag and Drop Repeater Rows

Est. Reading: 3 minutes
By: FDM Digital
Created: 06/30/2021
Difficulty: Intermediate

Drag and Drop Repeater Rows

This demo shows how you can use jQuery UI to apply click & drag functionality to Formidable Forms Repeaters and re-order the rows as required. We have combined this with a row counter to add extra functionality when reviewing your data in the back end.

You can read the full tutorial, and see a demo, HERE.

How to achieve this:

The solution to this is actually quite simple and uses the jQuery UI plugin that we also used in our drag & drop fields demo.

The first thing to do is to build your form:

  1. Add a repeater field to your form and select the formatting of your choice: Default, Inline or Grid.
  2. Add some fields to your repeater.
  3. Add a hidden or text field to your repeater that will be used as the row counter.
  4. Save your form.
  5. Go to the form Settings > Customise HTML > Before fields section and add the following:
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="/wp-includes/js/jquery/jquery.ui.touch-punch.js"></script>

What this does: This adds the jQuery UI plugin to your form and also includes the jQuery UI touch punch script so the drag and drop feature will work on touch enabled devices like smart phones and tablets.

Next, add this script directly underneath:

<!-- Default Repeater -->
<script type="text/javascript">
   document.addEventListener("DOMContentLoaded", updateRepeatCountFields );
   jQuery(document).on('frmAfterAddRow', updateRepeatCountFields );
   jQuery(document).on('frmAfterRemoveRow', updateRepeatCountFields );
   function updateRepeatCountFields(){
   var countFields = document.querySelectorAll( '.frm_field_2064_container input');
       for ( var i = 0, len=countFields.length; i<len; i++ ) {
           countFields[i].value = i+1;
       $( '#frm_field_2059_container' ).sortable({
           cursor: "grabbing",
           stop: function () {
               var countFields = document.querySelectorAll( '.frm_field_2064_container input');
               for ( var i = 0, len=countFields.length; i<len; i++ ) {
                   countFields[i].value = i+1;

Change 2059 to the ID of your repeater field and 2064 to the ID of your hidden or text field in 2 places.

Next scroll down and find the HTML for the repeater field you added and replace all of it with this:

<div class="ListContainer">
   <h3 class="frm_pos_[label_position][collapse_class]">[field_name]</h3>
   <div id="frm_field_[id]_container" class="frm_form_field frm_section_heading form-field[error_class]">
   [if description]
   <div class="frm_description">[description]</div>
   [/if description]

Now save the form.

View your form on the front end and you will see the default behaviour of the repeater row. At this stage the jQuiry UI script hasn’t been called yet as your repeater only has 1 row but when you click on the ‘Add‘ button for the first time the script will be called and you will then be able to click and drag your rows into any order you wish.

You will also see the row number field updating as you re-order the rows as per the examples above.

The final thing to do is to apply some styling to make it look a bit nicer and also work well with your theme.

Here is some example CSS that we used for the above demo:

/* Drag & Drop CSS */

.ListContainer h3 {
	font-size: 20px !important;
	line-height: 28px !important;

.divider-block {
	display: block;
	width: 100%;
	border-top: 2px dashed #eaeaea;
	margin-top: 50px;
	padding-top: 20px;

.ListContainer {
	overflow: hidden;

.ListContainer>div {
	white-space: nowrap;
	overflow-x: auto;
	overflow-y: hidden;

.frm_repeat_inline {
	background-color: #fff;
	border: 1px solid #eaeaea !important;
	padding: 20px !important;
	margin: -1px 0 auto !important;

.frm_repeat_grid {
	background-color: #fff;
	border: 1px solid #eaeaea !important;
	padding: 20px 20px 0 20px !important;
	margin: -1px 0 auto !important;

#sortable {
	margin: 0 !important;

.ui-sortable>div {
	cursor: move;
	cursor: grab;
	cursor: -moz-grab;
	cursor: -webkit-grab;

.ui-sortable>div:before {
	content: "f047";
	display: block;
	position: absolute;
	top: 5px;
	right: 10px;
	font-size: 22px;
	color: #999;
	font-family: FontAwesome;

.ListContainer .form-field {
	animation-name: none !important;

.ui-sortable-helper {
	box-shadow: 0 10px 50px rgba(0, 0, 0, 0.08), 0 13px 45px rgba(0, 0, 0, 0.08);

.frm_repeat_grid:first-of-type {
	border-top-right-radius: 4px;
	border-top-left-radius: 4px;

.frm_repeat_grid:last-child {
	border-bottom-right-radius: 4px;
	border-bottom-left-radius: 4px;

.ListContainer>div {
	padding-top: 1px;

You will probably need to adjust the CSS above to work with your theme and website styling. In particular the use of the FontAwesome icon might not work with your website but this can be adjusted as required.

PLEASE NOTE: This is an experimental feature and might not work well in all browsers / environments so i'd suggest testing it out before trying it on a live form.

Tutorial Gallery

One comment on “Drag and Drop Repeater Rows”

  1. Although you posted this a couple of years ago I was delighted to find it!

    I have used it to get round a big problem with repeaters: I wanted individual rows of a repeater to be editable in a view but Formidable Forms support tell me that although it was considered as an enhancement it has been turned down as too complicated. The only way to edit indivdual rows is to use a back-end form edit [formidable id=x fields="nnn,nn1"]. The problem with this is it is not possible to always display rows alphabetically (based on a name field); they appear in order of entry. Delete and add is cumbersome but had been the only option so far.

    Your drag and drop works brilliantly in that the rows can easily be dragged into alphabetical order manually! When the form edit is invoked our user can easily find a row to edit because they are in order.

    Thank you for this brilliant piece of code.

    I am surprised Formidable has not already implemeted the functionality as part of the base product.


Leave a Reply

Making the Best WordPress Plugin even better - Together

Take on bigger projects with confidence knowing you have access to an entire community of Formidable Experts and Professionals who have your back when the going gets tough. You got this!
Join the community