Demo

<input type="text" class="form-control" value="html,css,js" id="example-basic" />

<script>
  UseBootstrapTag(document.getElementById('example-basic'))
</script>
<input type="text" class="form-control" placeholder="Add a tag then press comma or Enter" id="example-placeholder" />

<script>
  UseBootstrapTag(document.getElementById('example-placeholder'))
</script>
<!-- Using data-ub-tag-max attribute: -->
<input type="text" class="form-control" placeholder="Enter tags (max 3)" data-ub-tag-max="3" id="example-max" />

<script>
  UseBootstrapTag(document.getElementById('example-max'))
</script>
<!-- Using data-ub-tag-separator attribute: -->
<input type="text" class="form-control" placeholder="Add a color then press space or Enter" data-ub-tag-separator=" " id="example-separator" />

<script>
  UseBootstrapTag(document.getElementById('example-separator'))
</script>
<!-- Using data-ub-tag-duplicate attribute: -->
<input type="text" class="form-control" value="html,css,js,js" data-ub-tag-duplicate id="example-duplicate" />

<script>
  UseBootstrapTag(document.getElementById('example-duplicate'))
</script>
<!-- Using data-ub-tag-transform attribute: -->
<input type="text" class="form-control" value="HTML,CSS,JS" data-ub-tag-transform="input => input.toUpperCase()" id="example-transform" />

<script>
  UseBootstrapTag(document.getElementById('example-transform'))
</script>
<input type="text" class="form-control" value="html,css,js" id="example-disabled" disabled />

<script>
  UseBootstrapTag(document.getElementById('example-disabled'))
</script>
<!-- Using data-ub-tag-no-input-onblur attribute: -->
<input type="text" class="form-control" data-ub-tag-no-input-onblur id="example-no-input-onblur" />

<script>
  UseBootstrapTag(document.getElementById('example-no-input-onblur'))
</script>
<label for="example-label" class="form-label">Click here to focus</label>
<input type="text" class="form-control" value="html,css,js" id="example-label" />

<script>
  UseBootstrapTag(document.getElementById('example-label'))
</script>
<!-- Using data-ub-tag-x-position attribute: -->
<div class="vstack gap-2">
  <input type="text" class="form-control example-x-position" value="left" data-ub-tag-x-position="left" />
  <input type="text" class="form-control example-x-position" value="right (default)" data-ub-tag-x-position="right" />
</div>
<!-- Available x-positions: left, right (default) -->

<script>
  document.querySelectorAll('.example-x-position').forEach((input) => {
    UseBootstrapTag(input)
  })
</script>
<div class="vstack gap-2">
  <input type="text" class="form-control example-sizing form-control-sm" value="html,css,js" />
  <input type="text" class="form-control example-sizing" value="html,css,js" />
  <input type="text" class="form-control example-sizing form-control-lg" value="html,css,js" />
</div>

<script>
  document.querySelectorAll('.example-sizing').forEach((input) => {
    UseBootstrapTag(input)
  })
</script>
This field is required.
Looks good!
Server-side
This field is required.
Looks good!
<form class="needs-validation vstack gap-3" novalidate>
  <div>
    <input type="text" class="form-control example-validation" name="tags" placeholder="Add a tag" required id="example-validation" />
    <div class="invalid-feedback">This field is required.</div>
    <div class="valid-feedback">Looks good!</div>
  </div>
  <button class="btn btn-secondary" type="submit">Submit</button>
</form>

<script>
  document.querySelectorAll('.example-validation').forEach((input) => {
    UseBootstrapTag(input)
  })

  // Example starter JavaScript for disabling form submissions if there are invalid fields
  void (function () {
    document.querySelectorAll('.needs-validation').forEach((form) => {
      if (form instanceof HTMLFormElement) {
        form.addEventListener('submit', (event) => {
          if (!form.checkValidity()) {
            event.preventDefault()
            event.stopPropagation()
          }
          form.classList.add('was-validated')
        })
      }
    })
  })()
</script>

<!-- Server side: just add "is-invalid" or "is-valid" -->
<h6 class="mt-4">Server-side</h6>
<div class="vstack gap-3">
  <div>
    <input type="text" class="form-control example-validation is-invalid" placeholder="Add a tag" />
    <div class="invalid-feedback">This field is required.</div>
  </div>
  <div>
    <input type="text" class="form-control example-validation is-valid" placeholder="Add a tag" value="use,bootstrap,tag" />
    <div class="valid-feedback">Looks good!</div>
  </div>
</div>
<input type="text" class="form-control" value="html,css,js" id="example-methods" />

<div class="hstack gap-3 flex-wrap mt-3">
  <button class="btn btn-sm btn-success" type="button" id="addValue-string">addValue('react')</button>
  <button class="btn btn-sm btn-success" type="button" id="addValue-string-with-separator">addValue('vue,svelte')</button>
  <button class="btn btn-sm btn-success" type="button" id="addValue-array">addValue(['solid', 'qwik'])</button>
  <button class="btn btn-sm btn-warning" type="button" id="removeValue-string">removeValue('react')</button>
  <button class="btn btn-sm btn-warning" type="button" id="removeValue-string-with-separator">removeValue('vue,svelte')</button>
  <button class="btn btn-sm btn-warning" type="button" id="removeValue-array">removeValue(['solid', 'qwik'])</button>
  <button class="btn btn-sm btn-info" type="button" id="getValue">getValue()</button>
  <button class="btn btn-sm btn-info" type="button" id="getValues">getValues()</button>
</div>

<script>
  const example = UseBootstrapTag(document.getElementById('example-methods'))

  document.getElementById('addValue-string').addEventListener('click', () => {
    example.addValue('react')
  })
  document.getElementById('addValue-string-with-separator').addEventListener('click', () => {
    example.addValue('vue,svelte')
  })
  document.getElementById('addValue-array').addEventListener('click', () => {
    example.addValue(['solid', 'qwik'])
  })
  document.getElementById('removeValue-string').addEventListener('click', () => {
    example.removeValue('react')
  })
  document.getElementById('removeValue-string-with-separator').addEventListener('click', () => {
    example.removeValue('vue,svelte')
  })
  document.getElementById('removeValue-array').addEventListener('click', () => {
    example.removeValue(['solid', 'qwik'])
  })
  document.getElementById('getValue').addEventListener('click', () => {
    alert(example.getValue())
  })
  document.getElementById('getValues').addEventListener('click', () => {
    alert(JSON.stringify(example.getValues()))
  })
</script>
<div class="vstack gap-2">
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="primary" />
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="success" />
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="danger" />
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="warning" />
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="info" />
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="dark" />
  <input type="text" class="form-control example-variant" value="html,css,js" data-ub-tag-variant="light" />
</div>

<script>
  document.querySelectorAll('.example-variant').forEach((input) => {
    UseBootstrapTag(input)
  })
</script>