Search code examples
c#jqueryfunctioncloneonchange

Cloned Form elements -> Ids updated with a number -> Get value of the dropdown


Cloned a form based on number selected in a dropdown. select and input fields ids on cloned forms are updated with a number such as OrderType1, OrderType2 etc....Now I need to retrieve the value of the dropdown OrderType1 and show a div.

Below is the code. Cloning works perfectly.

//DUPLICATE PLUGIN
            $.fn.duplicate = function (count, cloneEvents) {
                var tmp = [];
                for (var i = 0; i < count; i++) {
                    $.merge(tmp, this.clone(cloneEvents).get());
                }
                return this.pushStack(tmp);
            };

            //SELECT CHANGE FUNCTION (on change get value and clone)
            $('#case').change(function () {  // on change...
                var numOfClones = $(this).val();    // get value...

                $('#holder').html('');              // empty holder if there are some old clones
                $('#caseNumber').duplicate(numOfClones).addClass('new').appendTo('#holder').show();
                $('#caseNumber.new').each(function (idx) {
                    idx = $(this).index() + 1;
                    $('select', this).each(function () {
                        $(this).attr('name', $(this).attr('name') + idx).attr('id', $(this).attr('name'));
                    });
                    $('input', this).each(function () {
                        $(this).attr('name', $(this).attr('name') + idx).attr('id', $(this).attr('name'));
                    });
                    $('#caseNumbering', this).each(function () {
                        $(this).text("Case Number " + idx++);
                    });
                });

            });






            $("#orderType-req1").change(function (event) {
                alert("You have Selected  :: " + $(this).val());
            });
       

Thanks


Solution

  • I am not certain that I understand perfectly what you are trying to achieve, but I think I've got the gist.

    The trouble is that both the id and name attributes of your dynamically cloned Order Type <select> elements so that you do not have a static selector for which to bind an event handler.

    My suggestion is to add an attribute to the original <select> that will be a static one that is common to all clones - for example, a data-attribute, like data-order-type.

    Then, using Event Delegation, we can attach an event handler that will listen for changes to any [data-order-type] element and handle them accordingly.

    $(document).on('change', '[data-order-type]', function () {
      const $this = $(this);
      const val = $this.val();
    
      $this.parent().find('.blind').toggle(val === 'Other');
      alert("You have Selected  :: " + val);
    });
    

    Added to your code, we get:

    $.fn.duplicate = function(count, cloneEvents) {
       var tmp = [];
       for (var i = 0; i < count; i++) {
         $.merge(tmp, this.clone(cloneEvents).get());
       }
       return this.pushStack(tmp);
     };
    
     //SELECT CHANGE FUNCTION (on change get value and clone)
     $('#case').change(function() { // on change...
       var numOfClones = $(this).val(); // get value...
    
       $('#holder').html(''); // empty holder if there are some old clones
       $('#caseNumber').duplicate(numOfClones).addClass('new').appendTo('#holder').show();
       $('#caseNumber.new').each(function(idx) {
         idx = $(this).index() + 1;
         $('select', this).each(function() {
           $(this).attr('name', $(this).attr('name') + idx).attr('id', $(this).attr('name'));
         });
         $('input', this).each(function() {
           $(this).attr('name', $(this).attr('name') + idx).attr('id', $(this).attr('name'));
         });
         $('#caseNumbering', this).each(function() {
           $(this).text("Case Number " + idx++);
         });
       });
    
     });
    
    
    $(document).on('change', '[data-order-type]', function () {
      const $this = $(this);
      const val = $this.val();
    
      $this.parent().find('.blind').toggle(val === 'Other');
      alert("You have Selected  :: " + val);
    });
    #holder {
      border: 1px solid red;
    }
    
    .blind {
      display: none;
    }
    
    .new {
      border: 1px solid blue;
      padding: 10px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <select id="case">
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
    </select>
    
    
    <div id="caseNumber">
      <select data-order-type name="orderType">
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>Other</option>
      </select>
      <input name="OrderType">
      <div class="blind">
        <p>
          This is hidden stuff.
        </p>
      </div>
    </div>
    
    
    <div id="holder"></div>