• 1

Read this first!

We do not monitor these forums. The forum is provided to exchange information and experience with other users ONLY. Forum responses are not guaranteed.

However, please submit a ticket if you have an active subscription and wish to receive support. Our ticketing system is the only way of getting in touch with RSJoomla! and receiving the official RSJoomla! Customer Support.

For more information, the Support Policy is located here.

Thank you!

TOPIC: Repeatable fields (or group of fields)

Repeatable fields (or group of fields) 1 month 5 days ago #44078

Hi,

I am building a complex form with RSForm! Pro and I am strugling with the possibility of having repeatable fields or group of fields.

I am aiming at having a result similar to the one described below:
jsfiddle.net/tZPg4/10485/

Is that possible with RSForm Pro?

Thank you again for this great tool!!!

Best
Gio
The administrator has disabled public write access.

Repeatable fields (or group of fields) 1 month 4 days ago #44079

  • iceferret
  • iceferret's Avatar
  • OFFLINE
  • Gold Boarder
  • Posts: 267
  • Thank you received: 70
Her'es a way to do that. I've tried to make it portable so you can change the field names to suit yourself but to start i'd suggest a simple form to try it out, works for me

Create a text box 'input-1' which is permanently visible
create 'extra-input-2 to 6 text boxes which wont be.. add a button 'add_field_button'

add the following code into the javascript area
<script>
(function() {
  // ===== Configurable variables =====
  const MAX_FIELDS = 6; // 1 permanent + 5 extra fields
  const ADD_BUTTON_ID = 'add_field_btn'; // ID of the Add button
  const PERMANENT_INPUT_ID = 'input-1'; // ID of the permanent input
  const EXTRA_WRAPPER_CLASS_PREFIX = 'rsform-block-extra-input-'; // prefix for extra field wrappers
 
  // ===== Functions =====
 
  // Wrap input in flex container with optional Remove button
  function wrapInputFlex(input, addRemoveButton = false) {
    if (!input) return;
    const controls = input.closest('.formControls');
    if (!controls) return;
    if (controls.querySelector('.d-flex')) return;
 
    const flex = document.createElement('div');
    flex.className = 'd-flex align-items-center gap-2';
    flex.appendChild(input);
 
    if (addRemoveButton) {
      const btn = document.createElement('button');
      btn.type = 'button';
      btn.textContent = 'Remove';
      btn.className = 'btn btn-secondary btn-sm remove-btn';
      btn.addEventListener('click', function(e) {
        e.preventDefault();
        input.value = '';
        const wrapper = input.closest('.rsform-block');
        if (wrapper) wrapper.style.display = 'none';
      });
      flex.appendChild(btn);
    }
 
    controls.insertBefore(flex, controls.firstChild);
  }
 
  // Find Add button
  function findAddButton() {
    return document.getElementById(ADD_BUTTON_ID) ||
      document.querySelector('.rsform-block-add-field-button .formControls button, .rsform-block-add-field-button .formControls input[type="button"]');
  }
 
  // Find wrapper for extra-input-N
  function findWrapper(index) {
    return document.querySelector(`.${EXTRA_WRAPPER_CLASS_PREFIX}${index}`);
  }
 
  // Count visible fields
  function computeCurrent(wrappers) {
    let visibleExtras = 0;
    wrappers.forEach(obj => {
      if (obj.wrapper && window.getComputedStyle(obj.wrapper).display !== 'none') visibleExtras++;
    });
    return 1 + visibleExtras; // permanent input
  }
 
  // Show next hidden wrapper
  function showNext(wrappers) {
    for (const obj of wrappers) {
      if (!obj.wrapper) continue;
      if (window.getComputedStyle(obj.wrapper).display === 'none') {
        obj.wrapper.style.display = 'flex';
        const input = obj.wrapper.querySelector('input, textarea, select');
        wrapInputFlex(input, true);
        return true;
      }
    }
    return false;
  }
 
  // ===== Initialization =====
  document.addEventListener('DOMContentLoaded', function() {
    const addBtn = findAddButton();
    if (!addBtn) return;
 
    // Wrap permanent input (no Remove button)
    const permInput = document.getElementById(PERMANENT_INPUT_ID);
    if (permInput) wrapInputFlex(permInput, false);
 
    // Hide extra field wrappers initially
    const wrappers = [];
    for (let i = 2; i <= MAX_FIELDS; i++) {
      const w = findWrapper(i);
      if (w) {
        wrappers.push({ index: i, wrapper: w });
        w.style.display = 'none';
      }
    }
 
    // Add button click handler
    addBtn.addEventListener('click', function(e) {
      e.preventDefault();
      if (computeCurrent(wrappers) >= MAX_FIELDS) {
        alert('Maximum of ' + (MAX_FIELDS - 1) + ' extra fields reached.');
        return;
      }
      showNext(wrappers);
    });
  });
})();
</script>
If you can keep your head when all about you are losing theirs, then you obviously don't understand the situation!
The administrator has disabled public write access.
The following user(s) said Thank You: gbastianelli

Repeatable fields (or group of fields) 1 month 3 days ago #44082

I've tried this solution and indeed it worked well. Thank you very much!!!!
The administrator has disabled public write access.

Repeatable fields (or group of fields) 1 month 3 days ago #44083

  • iceferret
  • iceferret's Avatar
  • OFFLINE
  • Gold Boarder
  • Posts: 267
  • Thank you received: 70
You're welcome B)
If you can keep your head when all about you are losing theirs, then you obviously don't understand the situation!
The administrator has disabled public write access.
  • 1

Read this first!

We do not monitor these forums. The forum is provided to exchange information and experience with other users ONLY. Forum responses are not guaranteed.

However, please submit a ticket if you have an active subscription and wish to receive support. Our ticketing system is the only way of getting in touch with RSJoomla! and receiving the official RSJoomla! Customer Support.

For more information, the Support Policy is located here.

Thank you!