javascriptjquerybootstrap-4bootstrap-selectbootstrap-selectpicker

bootstrap-select identify button in for loop


i'm trying to display update button in for loop form with bootstrap-selectpicker.

i have a for loop, inside each loop i have a form with more than one select with selectpicker and a button (setted in display: none) to save the value of the all select in this form.

so at the end i will have n form and for each form x select and a button (setted in display: none) to update the value for the form.

with this code from selectpicker documentation

<script>
    $('.selectpicker').on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
        $('.button_update').show();
    });
</script>

i can show all update button, but i want to show only the update button inside the form where i change the value in the select.

START of LOOP

<form id="skill_form">
<div class="col-12">
    <div class="form-group">
        <select name="skill_1" id="skill_1"
                class="selectpicker form-control skill_select show-tick"
                data-live-search="true"
                data-size="10"
                data-width="fit"
                title="name">
            <option value="value">name</option>
        </select>
    </div>
</div>

<div class="col-12">
    <div class="form-group">
        <select name="skill_2" id="skill_2"
                class="selectpicker form-control skill_select show-tick"
                data-live-search="true"
                data-size="10"
                data-width="fit"
                title="name">
            <option value="value">name</option>
        </select>
    </div>
</div>

<div class="row" style="margin:0; display:none;">
    <!-- Update skills -->
    <div class="col-12" style="padding: 0; text-align: center;">
        <button type="submit"
                form="skill_form"
                class="btn btn-info button_update"
                style="display: none; font-size: 1em;">Update</button>
    </div>
</div>
</form>

END OF LOOP

<script>
    $('.selectpicker').on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
        $('.button_update').show();
    });
</script>

i tried to passing parameter but i don't know how and i can't put the jquery inside the loop passing the id of element that i looping.

Someone can help?


Solution

  • I'm not perfectly sure to correctly address the problem.

    Anyway here you have a demo that on document ready will create a number of forms (5 in this case) cloning a given template #skill_form having one select and one button inside a form. All the elements inside the template have no id so when it will be cloned to be appended to the document, the unique id requirement won't be violated.

    After the forms will be appended, the select elements will be initialized with .selectpicker() and a change event handler will be added to all of them.

    Such handler will rely on the event value (coming from e) to determine which element fired the event and what's its parent form that needs its own submit button to be showed.

    I simplified the scenario using one select only per form and cloning them all the same just for the sake of having a demo with multiple form instances.

    Each one might be populated with a different action or better differentiated in their structure.

    Since the select elements showed had only one option, I added an empty option to have the chance for the change event to trigger somehow.

    //creates n forms inside the target #formContainer (cloning the template #skill_form)
    function createForms(n){
      const templateForm = document.getElementById('skill_form');  
      const formContainer = document.getElementById('formContainer');
      for(let i=1; i<=n; i++){    
        const newForm = templateForm.content.cloneNode(true);    
        formContainer.appendChild(newForm);    
      }
    }
    
    //on document ready
    $(document).ready(()=>{
      
      //create the forms (5)
      createForms(5);
    
      //inits the .selectpicker(s)
      $('.selectpicker').selectpicker();
      
      //add change event handlers to all selects
      $('.selectpicker').on('changed.bs.select', function(e, clickedIndex, isSelected, previousValue) {
        //this is the element firing the change event
        const changedSelect = e.target;
        console.log(changedSelect);  
        //this is the parent form relative to the select firing the event
        const parentForm = changedSelect.closest('form');
        console.log(parentForm);    
        //show the child button update
        $(parentForm.querySelector('.button_update')).show();
      });
    });
    form {
      border: solid 1px darkgray;
      margin: 1rem 1rem;
      padding: 1rem
    }
    <!-- Bootstrap 4.0 required assets -->
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    
    <!-- bootstrap-select required assets -->
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css">
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>
    
    <div id="formContainer"></div>
    
    <template id="skill_form">
      <form>
        <div class="col-12">
          <div class="form-group">
            <select
              name="skill"          
              class="selectpicker form-control skill_select show-tick"
              data-live-search="true"
              data-size="10"
              data-width="fit"
              title="name">
              <option value=""></option>
              <option value="value">name</option>
            </select>
          </div>
        </div> 
    
        <div class="row" style="margin:0;">
          <!-- Update skills -->
          <div class="col-12" style="padding: 0; text-align: center;">
            <button
              type="submit"          
              class="btn btn-info button_update"
              style="display: none; font-size: 1em;">Update</button>
          </div>
        </div>
      </form>
    </template>