Repeater



You will need to add JavaScript to make it work.

<div class="block-repeater">
    <label class="block-repeater-label form-label">Custom Fields</label>

    <ul class="block-repeater-list">
        <li class="block-repeater-item">
            <button class="block-repeater-sort">⋮⋮</button>
            <div class="block-repeater-primary">
                <div class="form-field">
                    <label class="form-label">Field</label>
                    <input type="text" class="form-input" />
                </div>
                <div class="form-field">
                    <label class="form-label">Value</label>
                    <input type="text" class="form-input" />
                </div>
            </div>
            <div class="block-repeater-secondary">
                <button class="button button-outline button-danger button-icon">
                    <i class="iconoir-xmark"></i>
                    Remove
                </button>
            </div>
        </li>
        <li class="block-repeater-item">
            <button class="block-repeater-sort">⋮⋮</button>
            <div class="block-repeater-primary">
                <div class="form-field">
                    <label class="form-label">Field</label>
                    <input type="text" class="form-input" />
                </div>
                <div class="form-field">
                    <label class="form-label">Value</label>
                    <input type="text" class="form-input" />
                </div>
            </div>
            <div class="block-repeater-secondary">
                <button class="button button-outline button-danger button-icon">
                    <i class="iconoir-xmark"></i>
                    Remove
                </button>
            </div>
        </li>
    </ul>

    <button class="button button-icon">
        <i class="iconoir-plus"></i>
        Add More Fields
    </button>
</div>

Following code has been used to make it work

class BlockRepeater {
    constructor() {
        this.init();
    }

    init() {
        this.addNewFieldButtonClickHandler();
        this.removeFieldButtonClickHandler();
        this.dragHandler();
    }

    addNewFieldButtonClickHandler() {
        $(".js-add-field").on("click", function () {
            const cloneElement = $(this)
                .closest(".block-repeater")
                .find(".block-repeater-list .block-repeater-item")
                .last()
                .clone();

            $(this)
                .closest(".block-repeater")
                .find(".block-repeater-list")
                .append(cloneElement);

            cloneElement.find(".form-input").val("").first().trigger("focus");
        });
    }

    removeFieldButtonClickHandler() {
        $(".block-repeater-list").on("click", ".js-remove-field", function () {
            console.log(this);

            if (confirm("Are you sure you want to remove this field?")) {
                $(this).closest(".block-repeater-item").remove();
            }
        });
    }

    dragHandler() {
        let $draggedItem = null;

        $(".block-repeater-list").on(
            "dragstart",
            ".block-repeater-item",
            function (e) {
                $draggedItem = $(this);
                $(this).addClass("dragging");
                e.originalEvent.dataTransfer.effectAllowed = "move";
            }
        );

        $(".block-repeater-list").on(
            "dragend",
            ".block-repeater-item",
            function () {
                $(this).removeClass("dragging");
                $draggedItem = null;
            }
        );

        $(".block-repeater-list").on(
            "dragover",
            ".block-repeater-item",
            function (e) {
                e.preventDefault();
                e.originalEvent.dataTransfer.dropEffect = "move";
            }
        );

        $(".block-repeater-list").on(
            "dragenter",
            ".block-repeater-item",
            function (e) {
                e.preventDefault();

                if ($(this).is($draggedItem)) {
                    return;
                }

                const draggedIndex = $draggedItem.index();
                const targetIndex = $(this).index();

                if (draggedIndex < targetIndex) {
                    $(this).after($draggedItem);
                } else {
                    $(this).before($draggedItem);
                }
            }
        );

        $(".block-repeater-list").on("drop", function (e) {
            e.preventDefault();
        });
    }
}

new BlockRepeater();