Using Bootstrap Validation with HTMX as Extension

See gist: https://gist.github.com/marcus-at-localhost/c9f0a34a2e19d666fd95f61f002ea516

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.min.js"></script>
<div class="container my-5">
<form 

	hx-post="/foo"
  hx-ext="bs-validation"

  class="row g-3 needs-validation" 
  novalidate
>
  <div class="col-md-4">
    <label for="validationCustom01" class="form-label">First name</label>
    <input type="text" class="form-control" id="validationCustom01" value="Mark" required>
    <div class="valid-feedback">
      Looks good!
    </div>
  </div>
  <div class="col-md-4">
    <label for="validationCustom02" class="form-label">Last name</label>
    <input type="text" class="form-control" id="validationCustom02" value="Otto" required>
    <div class="valid-feedback">
      Looks good!
    </div>
  </div>
  <div class="col-md-4">
    <label for="validationCustomUsername" class="form-label">Username</label>
    <div class="input-group has-validation">
      <span class="input-group-text" id="inputGroupPrepend">@</span>
      <input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
      <div class="invalid-feedback">
        Please choose a username.
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <label for="validationCustom03" class="form-label">City</label>
    <input type="text" class="form-control" id="validationCustom03" required>
    <div class="invalid-feedback">
      Please provide a valid city.
    </div>
  </div>
  <div class="col-md-3">
    <label for="validationCustom04" class="form-label">State</label>
    <select class="form-select" id="validationCustom04" required>
      <option selected disabled value="">Choose...</option>
      <option>...</option>
    </select>
    <div class="invalid-feedback">
      Please select a valid state.
    </div>
  </div>
 ...

JavaScript

// https://gist.github.com/marcus-at-localhost/c9f0a34a2e19d666fd95f61f002ea516
htmx.defineExtension('bs-validation', {
  onEvent: function (name, evt, data) {
  
    if (name !== "htmx:afterProcessNode") {
  		return;
  	}
    console.log('event ' + name);

    let form = evt.detail.elt;

		// check if trigger attribute and submit event exists
    // for the form
    if(!form.hasAttribute('hx-trigger')){
    	// set trigger for custom event bs-send
      form.setAttribute('hx-trigger','bs-send');
			// and attach the event only once
      form.addEventListener('submit', function (event) {
        if (form.checkValidity()) {
          // trigger custom event hx-trigger="bs-send"
          htmx.trigger(form, "bsSend");
          console.log('bsSend')
        }

        console.log('prevent')       
        event.preventDefault()
        event.stopPropagation()

        form.classList.add('was-validated')
      }, false)  
    } 
  }
});