function Add and Remove input dropdown fields with javascript not work properly

Viewed 807

now i'm doing laravel project. i implement Dynamic Adding and removing input dropdown fields use javascript. function for adding and removing can work properly. but the problem is in the dropdown fields. inside dropdown, i add option "other", so when it selected "other", input type text will display.

i just able to display the input type text just only first line. but in other line is not correct. heres is my code

<div id="AddItemOption">
            <div class="d-flex justify-content-center align-items-center">
                <table class="table table-striped table-condensed table-additems">
                    <thead>
                        <tr>
                            <th class="align-middle border-0">items</th>
                            <th class="align-middle border-0">Delete</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr id="row1">
                            <td>
                                <select  name="items[]" class="form-control sellitem">
                                    <option value="book">book</option>
                                    <option value="pencil">pencil</option>
                                    <option value="pen">pen</option>
                                    <option value="other">other</option>
                                </select>

                                 <input type="text" class='form-control inputother' style="display: none;" name="other[]"  >

                            </td>
                            <td class="action">
                                <button type="submit" class="btn btn-danger ">
                                    Delete
                                </button>
                            </td>
                        </tr>
                        <tr>
                            <td colspan="4">
                                <button type="button" class="btn btn-default btn-xs">+ Add New Item</button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

and here is the script

<script>
        var i=1;
    $('#AddItemOption .btn-default').on('click', function(e) {
        i++;
        var el = $('.table-additems tbody tr:eq(0)').clone();
        $(el).find('option:selected').removeAttr('selected');
        $(el).find(':input').each(function(){
            $(this).removeAttr('value');
        });

        $(this).closest('tr').before('<tr id="row'+i+'" >'+$(el).html()+'</tr>');
    });
    $(document).on('click', '#AddItemOption .btn-danger', function(e) {
        if ($('.table-additems tbody tr').length == 2) {
            var el = $('.table-additems tbody tr:eq(0)');
            $(el).find('select:eq(0)').val($(el).find('select:eq(0) option:first').val());
            $(el).find('select:eq(1)').val($(el).find('select:eq(1) option:first').val());
            $(el).find('input:eq(0)').val('');
            e.preventDefault();
        }
        else {
            $(this).closest('tr').remove();
        }
    });

    $('.sellitem').change(function(){
        if ($(this).val() == 'other') {
            $('.inputother').css({'display':'block'});
        }else{
            $('.inputother').css({'display':'none'});
        }
    }); 

    </script>

and here is the link that i made for testing test add and remove function made by me just click "run" button to test the code

i want that. display input type text when select "other" is not in all line. but in each line. and when we add 'add new item' i just display default selection without display input type text..

please help

2 Answers

Under click event of #AddItemOption you can hide the input which is cloned by default and when the select-box is changed you can use $(this).closest("tr").find('.inputother') to show or hide only that input which is below the select-box .

Demo Code :

var i = 1;
$('#AddItemOption .btn-default').on('click', function(e) {
  i++;
  var el = $('.table-additems tbody tr:eq(0)').clone();
  $(el).find('option:selected').removeAttr('selected');
  $(el).find(':input').each(function() {
    $(this).removeAttr('value');
  });
  //while cloning hide other input
  $(el).find('.inputother').css({
    'display': 'none'
  });

  $(this).closest('tr').before('<tr id="row' + i + '" >' + $(el).html() + '</tr>');
});
$(document).on('click', '#AddItemOption .btn-danger', function(e) {
  if ($('.table-additems tbody tr').length == 2) {
    var el = $('.table-additems tbody tr:eq(0)');
    $(el).find('select:eq(0)').val($(el).find('select:eq(0) option:first').val());
    $(el).find('select:eq(1)').val($(el).find('select:eq(1) option:first').val());
    $(el).find('input:eq(0)').val('');
    e.preventDefault();
  } else {
    $(this).closest('tr').remove();
  }
});
//use this because other slect-box are dynmically created
$(document).on('change', '.sellitem', function(e) {
  if ($(this).val() == 'other') {
  //find this ->closest trs-> get input box show
    $(this).closest("tr").find('.inputother').css({
      'display': 'block'
    });
  } else {
    $(this).closest("tr").find('.inputother').css({
      'display': 'none'
    });
  }
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>repl.it</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>

<body>
  <div class="ajaxModalBody">
    <div class="container-fluid">
      <div id="AddItemOption">
        <div class="d-flex justify-content-center align-items-center">
          <table class="table table-striped table-condensed table-additems">
            <thead>
              <tr>
                <th class="align-middle border-0">items</th>
                <th class="align-middle border-0">Delete</th>
              </tr>
            </thead>
            <tbody>
              <tr id="row1">
                <td>
                  <select name="items[]" class="form-control sellitem">
                    <option value="book">book</option>
                    <option value="pencil">pencil</option>
                    <option value="pen">pen</option>
                    <option value="other">other</option>
                  </select>

                  <input type="text" class='form-control inputother' style="display: none;" name="other[]">

                </td>
                <td class="action">
                  <button type="submit" class="btn btn-danger ">
                                    Delete
                                </button>
                </td>
              </tr>
              <tr>
                <td colspan="4">
                  <button type="button" class="btn btn-default btn-xs">+ Add New Item</button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
  <script src="script.js"></script>
</body>

</html>

var i=1;
    $('#AddItemOption .btn-default').on('click', function(e) {
        i++;
        var el = $('.table-additems tbody tr:eq(0)').clone();
        $(el).find('.inputother').attr('count', i);
        $(el).find('.inputother').addClass('inputothercount' + i);
        $(el).find('.inputother').removeClass('firstinput');

        $(el).find('.sellitem').attr('count', i);
      //  $(el).find('.sellitem').class('count' + i);
        $(el).find('option:selected').removeAttr('selected');
        $(el).find(':input').each(function(){
            $(this).removeAttr('value');
        });

        $(this).closest('tr').before('<tr id="row'+i+'" >'+$(el).html()+'</tr>');
        listen();
    });

    $(document).on('click', '#AddItemOption .btn-danger', function(e) {
        if ($('.table-additems tbody tr').length == 2) {
            var el = $('.table-additems tbody tr:eq(0)');
            $(el).find('select:eq(0)').val($(el).find('select:eq(0) option:first').val());
            $(el).find('select:eq(1)').val($(el).find('select:eq(1) option:first').val());
            $(el).find('input:eq(0)').val('');
            e.preventDefault();
        }
        else {
            $(this).closest('tr').remove();
        }
    });


function listen() {
    $('.sellitem').change(function(){
        var count = $(this).attr('count') || 1;
        if (count == 1) {
           if ($(this).val() == 'other') {
            $('.firstinput').css({'display':'block'});
        }else{  
            $('.firstinput').css({'display':'none'});
        };
          return;
        } else {

        if ($(this).val() == 'other') {
            $('.inputothercount' + count).css({'display':'block'});
        }else{
            $('.inputothercount' + count).css({'display':'none'});
        }
        }
    });
}
listen();

You can play with it here https://repl.it/repls/DefiniteMintyScandisk#index.html and you would need to add firstinput class in <input type="text" class='form-control inputother' style="display: none;" name="other[]" > also

  1. When you add and remove display through class .inputother you are doing it for all elements placed on view. You should add class inputothercontent${count} to it so you can find specific element by count and hide display appropriate div.

  2. Do add firstinput class by default in html and remove it when appending other elements.

  3. You will need to awake listener again to listen for .sellitem click after adding element to dom. It don't auto refresh for dynamically added elements.

  4. You should save current count in attribute of sellItem element so on click you can know which element got changed and change display based on that.

Related