skip to Main Content

I’m facing an issue with form validation in a tabbed interface. I’m using regular tabs with radio buttons to switch between them. However, upon submitting the form, it fails to validate fields located in inactive tabs.

My aim is to have the form validate all fields, regardless of their visibility within the tabs. This ensures that all required fields are correctly filled out before the form is submitted, even if they are not currently visible to the user.

Instead of displaying validation for fields in inactive tabs, I encounter an error message in the console stating that the field is not focusable.

<form>
  <div class="tabset">

    <!-- Tab 1 -->
    <input type="radio" name="tabset" id="tab_datospersonales" aria-controls="datos_personales" checked>
    <label for="tab_datospersonales">Datos Personales</label>
    <!-- Tab 2 -->
    <input type="radio" name="tabset" id="tab_datostrabajador" aria-controls="datos_trabajador">
    <label for="tab_datostrabajador">Datos del Trabajador</label>

    <div class="tab-panels">
      <!-- datos_personales -->
      <section id="datos_personales" class="tab-panel">
        <!--mbre-->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Nombre 1</span>
          <input type="text" class="form-control" id="input_trabajador_nombre" required autocomplete="off" placeholder="Ingrese su primer nombre">
        </div>

        <!-- Apellido P-->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Apellido P.</span>
          <input type="text" class="form-control" id="input_trabajador_apellido_p" required autocomplete="off" placeholder="Ingrese su primer apellido">
        </div>
      </section>

      <!-- datos_Trabajador -->
      <section id="datos_trabajador" class="tab-panel">

        <!-- trabajador_cargo -->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Cargo/Responsabilidad</span>
          <input type="text" class="form-control" id="input_trabajador_cargo" required autocomplete="off" maxlength="40" placeholder="Ingrese su Cargo/Responsabilidad">
        </div>

        <!-- trabajador_categoria -->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Categoría</span>
          <select class="form-control custom-select" id="input_trabajador_categoria" required>
            <option value="" disabled>seleccione...</option>
            <option value="I">Trabajador Interno</option>
            <option value="E">Trabajador Externo</option>
          </select>
        </div>
        <button id="btnGuardarNewTrabajador" type="submit">Guardar Trabajador</button>
      </section>
    </div>
  </div>
</form>

I’m seeking guidance on how to ensure that all fields are validated, regardless of their visibility within the tabs, and how to appropriately display validation errors.

2

Answers


  1. This is maybe not production ready (…), but the point is that you can disable the default invalid message (e.preventDefault() in the invalid call back function) and use CSS to "signal" what form fields and tabs are invalid.

    You are probably creating the visual layout of the tabs different then what I have done, so create some selector that matches your setup, and style the tab in a way that makes sense to you.

    document.forms.form01.addEventListener('invalid', e => {
      e.preventDefault();
      e.target.classList.add('invalid');
      let id = e.target.closest('section').id;
      e.target.form.querySelector(`label[for="tab_${id}"]`).classList.add('invalid');
    }, true);
    
    document.forms.form01.addEventListener('input', e => {
      if (e.target.validity.valid) {
        e.target.classList.remove('invalid');
        let section = e.target.closest('section');
        if (section) {
          e.target.form.querySelector(`label[for="tab_${section.id}"]`).classList.remove('invalid');
        }
      }
    });
    section {
      display: none;
    }
    
    input[name="tabset"]:checked+section {
      display: block;
    }
    
    form {
      display: flex;
      flex-direction: row;
      align-items: flex-start;
      flex-wrap: wrap;
    }
    
    label {
      order: 1;
      border-width: thin;
      border-color: black black white black;
      border-style: solid;
      padding: .1em;
      margin: 0 .1em;
      z-index: 100;
    }
    
    section {
      order: 2;
      width: 100%;
      border-width: thin;
      border-color: black;
      border-style: solid;
      padding: 1em;
    }
    
    .invalid {
      background-color: red;
    }
    <form name="form01">
      <!-- Tab 1 -->
      <label for="tab_datospersonales">Datos Personales</label>
      <input type="radio" name="tabset" id="tab_datospersonales" aria-controls="datos_personales" checked hidden>
      <!-- datos_personales -->
      <section id="datospersonales" class="tab-panel">
        <!--mbre-->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Nombre 1</span>
          <input type="text" class="form-control" id="input_trabajador_nombre" required autocomplete="off" placeholder="Ingrese su primer nombre">
        </div>
    
        <!-- Apellido P-->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Apellido P.</span>
          <input type="text" class="form-control" id="input_trabajador_apellido_p" required autocomplete="off" placeholder="Ingrese su primer apellido">
        </div>
      </section>
    
      <!-- Tab 2 -->
      <label for="tab_datostrabajador">Datos del Trabajador</label>
      <input type="radio" name="tabset" id="tab_datostrabajador" aria-controls="datos_trabajador" hidden>
      <!-- datos_Trabajador -->
      <section id="datostrabajador" class="tab-panel">
    
        <!-- trabajador_cargo -->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Cargo/Responsabilidad</span>
          <input type="text" class="form-control" id="input_trabajador_cargo" required autocomplete="off" maxlength="40" placeholder="Ingrese su Cargo/Responsabilidad">
        </div>
    
        <!-- trabajador_categoria -->
        <div class="input-group input-group-sm mb-3">
          <span class="input-group-text" id="inputGroup-sizing-sm">Categoría</span>
          <select class="form-control custom-select" id="input_trabajador_categoria" required>
            <option value="">seleccione...</option>
            <option value="I">Trabajador Interno</option>
            <option value="E">Trabajador Externo</option>
          </select>
        </div>
        <button id="btnGuardarNewTrabajador" type="submit">Guardar Trabajador</button>
      </section>
    </form>
    Login or Signup to reply.
  2. I have that problem with the tabs when I’m on the last tab and click the button, it doesn’t validate the empty fields on the other tabs, giving me this error.

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search