Search code examples
javascriptslimselect

multiple single select using slim select


I am attempting to clone a SlimSelect instance. However, after cloning the select element and trying to initialize the SlimSelect on the cloned element, I encounter a problem. The value of the cloned select element remains the same as the original one, and the dropdown menu fails to open. Could you assist me in identifying what might be missing or incorrect in my code?

const btn = document.getElementById("add-button");
const formClone = document.querySelector(".clone");
const parentForm = document.querySelector(".wrappers");
    
    btn.addEventListener("click", (e) => {
      e.preventDefault();
      const newId = makeid(10);
      const clone = formClone.cloneNode(true);
      const arr = clone.querySelector("[name='ArrLists']").id;
      arr += newId;
      parentForm.appendChild(clone);
    
      const deleteForm = document.createElement("button");
      deleteForm.innerText = "X";
      deleteForm.classList.add("btn", "btn-danger", "btn-sm");
      clone.appendChild(deleteForm);
      
      new SlimSelect({
  select: arr
});
    
      deleteForm.addEventListener("click", (e) => {
        e.preventDefault();
        e.target.parentElement.remove();
      });
    });
    
new SlimSelect({
  select: '#single'
});
    
    function makeid(length) {
    let result = '';
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const charactersLength = characters.length;
    let counter = 0;
    while (counter < length) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
      counter += 1;
    }
    return result;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link href="https://unpkg.com/slim-select@latest/dist/slimselect.css" rel="stylesheet">

<button id="add-button" class="btn btn-primary mb-3">Add Form</button>
<div class="wrappers">
  <div class="row clone mb-2">
    <div class="col px-0">
      <select id="single" name="ArrLists">
        <option value="" selected disabled>Choose</option>
        <option value="value 1">Value 1</option>
        <option value="value 2">Value 2</option>
        <option value="value 3">Value 3</option>
      </select>
    </div>
  </div>
</div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+" crossorigin="anonymous"></script>
<script src="https://unpkg.com/slim-select@latest/dist/slimselect.min.js"></script>


Solution

  • Cloning the element that you already applied SlimSelect to, appears to be leading to trouble. Clone an unmodified select element instead.

    I added the hidden attribute to your "original" of the row to be cloned here, so that the "naked" select doesn't show up. You might want to place it outside of your actual form, so that this row doesn't submit a value as well. (Or you could use a template element for this part to begin with.)

    And then I simply trigger a click on your "Add Form" button, to get the first initial SlimSelect set up.

    Note that your makeid can create IDs that start with a digit - which leads to trouble when using that value in an ID selector, #1foo is simply an invalid selector, it would need additional escaping. I removed the digits from your string of possible characters - fell free to add them again, but make sure the first character is always a letter then.

    const btn = document.getElementById("add-button");
    const formClone = document.querySelector(".clone");
    const parentForm = document.querySelector(".wrappers");
    
    btn.addEventListener("click", (e) => {
      e.preventDefault();
      const newId = makeid(10);
      const clone = formClone.cloneNode(true);
      clone.removeAttribute('hidden');
      clone.querySelector("[name='ArrLists']").id = newId;
      parentForm.appendChild(clone);
    
      const deleteForm = document.createElement("button");
      deleteForm.innerText = "X";
      deleteForm.classList.add("btn", "btn-danger", "btn-sm");
      clone.appendChild(deleteForm);
    
      new SlimSelect({
        select: '#'+newId
      });
    
      deleteForm.addEventListener("click", (e) => {
        e.preventDefault();
        e.target.parentElement.remove();
      });
    });
    
    btn.click();
    
    function makeid(length) {
      let result = '';
      const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
      const charactersLength = characters.length;
      let counter = 0;
      while (counter < length) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
        counter += 1;
      }
      return result;
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    <link href="https://unpkg.com/slim-select@latest/dist/slimselect.css" rel="stylesheet">
    
    <button id="add-button" class="btn btn-primary mb-3">Add Form</button>
    <div class="wrappers">
      <div class="row clone mb-2" hidden>
        <div class="col px-0">
          <select id="single" name="ArrLists">
            <option value="" selected disabled>Choose</option>
            <option value="value 1">Value 1</option>
            <option value="value 2">Value 2</option>
            <option value="value 3">Value 3</option>
          </select>
        </div>
      </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/slim-select@latest/dist/slimselect.min.js"></script>