skip to Main Content

In my web application, There is a table and Add button.

Whenever the user clicks on the Add button, from javascript, I load the new row to the table.

In the row, there is a element and for that class, I added the Select2 js-dropdown class when adding to the new row.

But when it was added, Js-dropdown class was not applied.

How can I add it?

this is the current code.

<table class="table table-striped" id="submissionTable">
  <thead>
    <tr>
      <th>#</th>
      <th>ITEM</th>
      <th>QTY</th>
      <th>MEASURE BY</th>
      <th>UNIT PRICE</th>
      <th>LINE TOTAL</th>
    </tr>
  </thead>
  <tbody class="table-border-bottom-0">
    <tr id="tablerow0"></tr>
  </tbody>
</table>

This is the javascript code.

  $(function () {

    $("#add").click(function () {
      var newRow = $(
        '<tr id="tablerow' +
        counter +
        '"> ' +
        "<td>" +
        '<label id="CountItems"><strong>' +
        counter +
        "</strong></label>" +
        "</td>" +
        '<td width="40%">' +
        '<select onchange="sendInfo(this)" class="form-select js-dropdown" data-id= ' + counter + ' name="Item_Id[' +
        counter +
        ']" id="ItemId"' + counter + 'required="required" ' +
        "</select>" +
        "</td>" +
        '<td width="10%">' +
        '<input type="text" class="form-control" name="Qty[' +
        counter +
        ']" value="1" id="Qty[' + counter + ']" onchange="calQtyBase(this)" data-QtyId= ' + counter + ' required="required" />' +
        "</td>" +
        '<td width="10%">' +
        '<input type="text" class="form-control" name="MeasureBy[' +
        counter +
        ']" value="" id="MeasureBy[' + counter + ']" readonly />' +
        "</td>" +
        '<td width="20%">' +
        '<input type="text" class="form-control" name="Unit_Price[' +
        counter +
        ']" value="0.00" id="UnitPrice[' + counter + ']"  onchange="priceBase(this)" data-PriceId= ' + counter + '  required="required" />' +
        "</td>" +
        '<td width="20%">' +
        '<input type="text" class="form-control" name="Line_Total[' +
        counter +
        ']" value="0.00" id="LineTotal[' + counter + ']"    required="required" />' +
        "</td>" +
        "<td>" +
        '<button type="button" class="btn btn-danger" onclick="removeTr(' +
        counter +
        ');">x</button>' +
        "</td>" +
        "</tr>"
      );

      var selectElement = newRow.find("select"); // Find the <select> element in the new row

      // Populate the <select> element with options
      dropdownOptions.forEach(function (option) {

        var optionElement = $("<option>").val(option.Value).text(option.Text);

        selectElement.append(optionElement);

      });

      newRow.appendTo("#submissionTable");
      counter++;
      return false;
    });

  });

2

Answers


  1. If you want to select2 jquery plugin work on new select element added to DOM, you need to initialize it on this select.

    $(()=>{
      
      let $target = $("#target");
      let $btn = $("#add");
      
      $btn.on('click', function(){
        let $select = $("<select><option>first</option><option>second</option></select>");
        $target.append($select);
        $select.select2(); // this must be called after append
      });
    
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
    
    <div id="target"></div>
    <button id="add">Add</button>

    edit

    You have a syntax error, so it may not work for you.
    replace
    ']" id="ItemId"' + counter + 'required="required" ' +
    On
    ']" id="ItemId' + counter + '" required="required" ' +
    I fixed this error see below.

    $(function () {
      let counter = 1;
      let dropdownOptions = [{Value:'0', Text: 'first'}, {Value:'1', Text: 'second'}];
        $("#add").click(function () {
          var newRow = $(
            '<tr id="tablerow' +
            counter +
            '"> ' +
            "<td>" +
            '<label id="CountItems"><strong>' +
            counter +
            "</strong></label>" +
            "</td>" +
            '<td width="40%">' +
            '<select onchange="sendInfo(this)" class="form-select js-dropdown" data-id= ' + counter + ' name="Item_Id[' +
            counter +
            ']" id="ItemId' + counter + '" required="required" ' +
            "</select>" +
            "</td>" +
            '<td width="10%">' +
            '<input type="text" class="form-control" name="Qty[' +
            counter +
            ']" value="1" id="Qty[' + counter + ']" onchange="calQtyBase(this)" data-QtyId= ' + counter + ' required="required" />' +
            "</td>" +
            '<td width="10%">' +
            '<input type="text" class="form-control" name="MeasureBy[' +
            counter +
            ']" value="" id="MeasureBy[' + counter + ']" readonly />' +
            "</td>" +
            '<td width="20%">' +
            '<input type="text" class="form-control" name="Unit_Price[' +
            counter +
            ']" value="0.00" id="UnitPrice[' + counter + ']"  onchange="priceBase(this)" data-PriceId= ' + counter + '  required="required" />' +
            "</td>" +
            '<td width="20%">' +
            '<input type="text" class="form-control" name="Line_Total[' +
            counter +
            ']" value="0.00" id="LineTotal[' + counter + ']"    required="required" />' +
            "</td>" +
            "<td>" +
            '<button type="button" class="btn btn-danger" onclick="removeTr(' +
            counter +
            ');">x</button>' +
            "</td>" +
            "</tr>"
          );
    
          var selectElement = newRow.find("select"); // Find the <select> element in the new row
    
          // Populate the <select> element with options
          dropdownOptions.forEach(function (option) {
    
            var optionElement = $("<option>").val(option.Value).text(option.Text);
    
            selectElement.append(optionElement);
          });
    
          
          newRow.appendTo("#submissionTable");
          selectElement.select2();
          
          
          counter++;
          return false;
        });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
    
    <table class="table table-striped" id="submissionTable">
      <thead>
        <tr>
          <th>#</th>
          <th>ITEM</th>
          <th>QTY</th>
          <th>MEASURE BY</th>
          <th>UNIT PRICE</th>
          <th>LINE TOTAL</th>
        </tr>
      </thead>
      <tbody class="table-border-bottom-0">
        <tr id="tablerow0"></tr>
      </tbody>
    </table>
    
    <button id="add">click me</button>
    Login or Signup to reply.
  2. A little different approach; sorry this is just a really really fast post here:

    • use an object to hold the constants and not global.
    • No need for global counter; seems overly complex to even NEED that used (use classes?)
    • use a template and cloned that to make markup simpler to edit/understand
    • some simple wire-up of event handlers that do little here.
    $(function() {
      function handleTableRowRemoval(event) {
        const row = event.target.closest('tr.row-thing');
        const rowCount = row.dataset.Count;
        $(row).remove();
        //whatever else needs done: removeTr(rowCount);
      }
    
      function handlePriceBaseEvent(event) {
        //do whatever calQtyBase(this);
      }
    
      function handleSelectChangeEvent(event) {
        // whatever sendInfo(this);
      }
      $("#add").on('click', function(event) {
        const newThings = {
          templateselector: "#new-row",
          rowIdBase: "tablerow-",
          newRowId: "",
          tableSelector: '#submissionTable tbody',
          selectSelector: '.form-select.js-dropdown.item-id',
          count: 0,
          dropdownOptions: [{
            Value: '0',
            Text: 'first'
          }, {
            Value: '1',
            Text: 'second'
          }]
        };
    
        const table = document.querySelector(newThings.tableSelector);
        const template = document.querySelector(newThings.templateselector);
        const cloneRow = template.content.firstElementChild.cloneNode(true);
        newThings.currentCount = $(table).data("currentcount") * 1;
    
        // id might not be needed?
        newThings.newRowId = newThings.rowIdBase + newThings.count;
        cloneRow.id = newThings.newRowId;
        // what we work with 
        const selectControl = cloneRow.querySelector(newThings.selectSelector);
        const qtyBase = cloneRow.querySelector('.form-control.qty-base');
        const unitPrice = cloneRow.querySelector('.form-control.unit-price');
        const measureBy = cloneRow.querySelector('.form-control.measure-by');
        const lineTotal = cloneRow.querySelector('.form-control.line-total');
    
        //put the event hanldlers on
        selectControl.addEventListener("change", handleSelectChangeEvent);
        unitPrice.addEventListener("click", handlePriceBaseEvent);
        cloneRow.querySelector('.remove-row').addEventListener("click", handleTableRowRemoval);
    
        // add count where needed
        cloneRow.dataset.Count = newThings.count;
        cloneRow.id = `tablerow${newThings.count}`;
    
        selectControl.name = `Item_Id[${newThings.count}`;
        selectControl.textContent = newThings.count;
        selectControl.dataset.Id = newThings.count;
    
        measureBy.name = `MeasureBy[${newThings.count}`;
        measureBy.id = `MeasureBy[${newThings.count}`;
    
        qtyBase.name = `Qty[${newThings.count}`;
        qtyBase.id = `Qty[${newThings.count}`;
        qtyBase.dataset.QtyId = newThings.count;
    
        unitPrice.name = `Unit_Price[${newThings.count}`;
        unitPrice.id = `Unit_Price[${newThings.count}`;
        unitPrice.dataset.PriceId = newThings.count;
    
        lineTotal.name = `Line_Total[${newThings.count}`;
        lineTotal.id = `Line_Total[${newThings.count}`;
        lineTotal.dataset.PriceId = newThings.count;
    
        // Populate the <select> element with options
        newThings.dropdownOptions.forEach(function(option) {
          const optionElement = $("<option>").val(option.Value).text(option.Text);
          $(selectControl).append(optionElement);
        });
    
        // append new row to table after all that 
        table.appendChild(cloneRow);
        //only seems to work after append
        $(table).find(newThings.selectSelector).last().select2();
        return false;
      });
    });
    /* if for example using bootstrap can perhaps use classes from there instead */
    
    .forty-percent {
      width: 40%;
    }
    
    .ten-percent {
      width: 10%;
    }
    
    .twenty-percent {
      width: 10%;
    }
    
    .count-items .label-count-value {
      font-weight: 600;
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" referrerpolicy="no-referrer"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    <button id="add" type="button" class="add-new-row">Add new row</button>
    <table class="table table-striped" id="submissionTable" data-currentcount="0">
      <thead>
        <tr>
          <th>#</th>
          <th>ITEM</th>
          <th>QTY</th>
          <th>MEASURE BY</th>
          <th>UNIT PRICE</th>
          <th>LINE TOTAL</th>
        </tr>
      </thead>
      <tbody class="table-border-bottom-0 ">
        <tr id="tablerow0"></tr>
      </tbody>
    </table>
    <template id="new-row">
    <tr id="tablerow" class="row-thing"> 
      <td><label class="count-items"><strong class="label-count-value"></strong></label></td>
      <td class="forty-percent"><select class="form-select js-dropdown item-id" required="required" ></select></td>
      <td class="ten-percent"><input type="text" class="form-control qty-base" value="1" data-qty-Id='' required="required" /></td>
      <td class="ten-percent"><input type="text" class="form-control measure-by" value="" readonly /></td>
      <td class="twenty-percent"><input type="text" class="form-control unit-price"  value="0.00" data-PriceId='xx' required="required" /></td>
      <td class="twenty-percent"><input type="text" class="form-control line-total"  value="0.00" required="required" /></td>
      <td><button type="button" class="btn btn-danger remove-row">x</button></td>
    </tr>
    </template>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search