skip to Main Content

I use bootstrap 5.3.3 and have this structure
see css used to create a big checkbox.

.form-check-input[type=checkbox].big-checkbox {
  transform: scale(3);
  margin: 1.5rem;
  border-radius: 0;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">

<!-- Table and checkbox inside it without validation -->
<table>
  <tr>
    <td>
      <input type="checkbox" id="exampleOne" name="exampleOne" 
              class="form-check-input big-checkbox"
              checked
              >
    </td>
    <td>
      <label class="form-check-label" for="exampleOne">
        This checkbox does not have validation
      </label>
    </td>
  </tr>
</table>

<!-- Turn this into table with same layout and working validation feedback -->
<form id="form" novalidate>
  <div class="form-check mt-4 mb-3">
    <input type="checkbox" id="exampleTwo" name="exampleTwo"
           class="form-check-input big-checkbox"
           required
           >
    <label class="form-check-label" for="exampleTwo">
      This checkbox has validation 
      <a href="#" data-bs-toggle="modal" 
         data-bs-target="#universalModal"
         data-modal-id="testModal" 
         class="test-link"
         >
        Test link
      </a>
    </label>
    <div class="invalid-feedback">I am a red invalid feedback text.</div>
  </div>
</form>

I want to make the lower checkbox behave the same as the upper one, but it must include Bootstrap’s form validation, as it currently does with the smaller checkbox version. If I implement the layout using a table like this

<table>
  <tr>
    <td>
      <input type="checkbox" id="exampleTwo" name="exampleTwo"
              class="form-check-input big-checkbox"
              required
              >
    </td>
    <td>
      <label class="form-check-label" for="exampleTwo">
        This checkbox has validation 
        <a href="#" data-bs-toggle="modal" data-bs-target="#universalModal"
           data-modal-id="testModal" class="test-link"
           >
          Test link
        </a>
      </label>
      <div class="invalid-feedback">
        I am a red invalid feedback text.
      </div>
    </td>
  </tr>
</table>

the large checkbox does turn red when invalid, but the label does not change red, and the invalid-feedback text does not appear at all.
I believe this is because the <input> resides in a different table data cell than the label and the <div id="termsFeedback" class="invalid-feedback">.
For form validation to work correctly, they all need to be within the same parent element, I gather. It goes without saying that applying the big-checkbox class to a non-table layout completely messes up the appearance.

How would you implement this so that the form validation works as expected, just like it does in Bootstrap normally?

2

Answers


  1. Well, it won’t work in that case, so you need to do add validation feedback manually.
    You’re correct, the styling also depends on position of elements, they’re meant to be subsequent-siblings.

    So, you could try overriding the usual BS form controls style to look like table, or do the validation manually with JavaScript, and then check the checkbox, and add validation classes manually, and also listen to the checkbox changes, to toggle them (and do the same for the rest form controls).

    function toggler(el, add) {
      if (add) {
        label.classList.add('invalid-feedback', 'd-block');
      } else {
        label.classList.remove('invalid-feedback', 'd-block');
      }
    }
    
    checkBox.addEventListener('change', (e) => {
      if (e.target.validity.valid) {
        toggler(e.target, false);
      } else {
        toggler(e.target, true);
      }
    });
    

    demo:

    .as-console-wrapper { max-height: 50px !important; bottom: 0; }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
      <title>Bootstrap Example</title>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
      <style>
        .form-check-input[type=checkbox].big-checkbox {
          transform: scale(3);
          margin: 1.5rem;
          border-radius: 0;
        }
      </style>
    </head>
    
    <body class="p-3 m-0 border-0 bd-example m-0 border-0">
      <form class="row g-3" novalidate="" id="myForm">
        <table>
          <tr class="big-checkbox-cont">
            <td>
              <input type="checkbox" id="exampleOne" name="exampleOne" class="form-check-input big-checkbox" required>
            </td>
            <td>
              <label class="form-check-label" for="exampleOne">
                  This checkbox does not have validation
                </label>
            </td>
          </tr>
        </table>
    
        <div class="col-12">
          <button class="btn btn-primary mt-2" type="submit">Submit form</button>
        </div>
      </form>
    
      <script>
        const checkBoxCont = document.querySelector('.big-checkbox-cont');
        const checkBox = checkBoxCont.querySelector('input');
        const label = checkBoxCont.querySelector('label');
    
        function toggler(el, add) {
          if (add) {
            label.classList.add('invalid-feedback', 'd-block');
          } else {
            label.classList.remove('invalid-feedback', 'd-block');
          }
        }
    
        checkBox.addEventListener('change', (e) => {
          if (e.target.validity.valid) {
            toggler(e.target, false);
          } else {
            toggler(e.target, true);
          }
        });
    
        document.querySelector('#myForm').addEventListener('submit', (e) => {
          e.preventDefault();
    
          const form = e.target;
    
          if (form.checkValidity()) {
            console.log('form valid');
          } else {
            console.log('form not valid');
            form.classList.add('was-validated');
    
            if (!checkBox.validity.valid) {
              toggler(e.target, true);
            }
          }
        });
      </script>
    
      <!-- End Example Code -->
    </body>
    
    </html>
    Login or Signup to reply.
  2. This issue is rare but has a simple fix. Bootstrap is a CSS library, and sometimes it conflicts with custom styles, causing small problems.

    In your case, everything is set up correctly, but the form-check class in Bootstrap adds some padding by default, which is causing the issue. To fix this, add the p-0 class (to remove the padding) and adjust the alignment.

    Here’s an example of how you can update your code:

    Your code:

    <div class="form-check mt-4 mb-3">
    

    Updated code:

    <div class="form-check mt-4 mb-3 p-0 d-inline-flex align-items-center">
    

    In the updated code, I’ve added p-0 to remove the padding and used d-inline-flex align-items-center to make the elements align in the center.

    I hope this works for you 🙂

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