0

In a form there is an add button which adds form inputs. At the new form inputs I tried to increment the attribute name e.g name="description-1", name="description-2" etc. However, all the new inputs have the same name="description-1". What I miss?

var dataList = $('.products');
var jsonOptions = [{
  "product": "11111",
  "description": "description 1"
}, {
  "product": "22222",
  "description": "description 2"
}, {
  "product": "33333",
  "description": "description 3"
}];

jsonOptions.forEach(function(item) {

  var option = '<option value="' + item.product + '">' + item.description + '</option>';

  dataList.append(option);
});

$(function() {
  $('body').on('input', '.product,.products', function() {

    var i = this.value;
    var description = "";
    var productsInBox = 0;

    jsonOptions.forEach(function(a) {
      if (a.product == i) {
        description = a.description;
      }
    });
    $(this).closest('.form-group').find('.description').val(description);


  });
});

counter = 0;

$('#form1').on('click', '.addButtonDED', function() {
    counter++;
    var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
      .find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
      .find('[name="description-0"]').attr('name', 'description-' + counter).end()
      .find('i').removeClass('fa-plus').addClass('fa-minus').end();
    $template.insertAfter('.form-group:last');
  })

  // Remove button click handler
  .on('click', '.removeButtonDED', function() {
    counter--;
    var $row = $(this).closest('.form-group');
    $row.remove();
  });
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" method="post" class="form-horizontal" role="form">
  <fieldset>


    <div class="form-group">
      <div class="col-xs-2">
        <input type="text" list="products" class="form-control product" name="product" />
        <datalist id="products" class="products"></datalist>
      </div>

      <div class="col-xs-4">
        <input id="" type="text" class="form-control description" name="description-0" />
      </div>



      <div class="col-xs-1">
        <button type="button" class="btn btn-default addButtonDED"><i class="fa fa-plus"></i></button>
      </div>
    </div>

    <div class="col-xs-10 ">
      <button type="submit" name="formAction" value="next" class="btn btn-primary">sUBMIT</button>

    </div>



  </fieldset>
</form>
yaylitzis
  • 5,354
  • 17
  • 62
  • 107

4 Answers4

1

You are accesing always to '[name="description-0"]' so when you change their name to description-1, that selector won't select them anymore.

You should select them with this selector '[name^="description-"]'.

The ^= operator means to select every element that starts with the stated value, so it will select all your description-0, description-1 and description-whatever.

You can read more here: https://www.w3schools.com/jquery/sel_attribute_beginning_value.asp

Jorge Fuentes González
  • 11,568
  • 4
  • 44
  • 64
1

You can fix it by simple change [name="description-0"] to [name="description-'+ (counter-1) +'"]

The problem is that you close the previous object, and then the decription-0 will not be 0 anymore after the first object.

var dataList = $('.products');
var jsonOptions = [{
  "product": "11111",
  "description": "description 1"
}, {
  "product": "22222",
  "description": "description 2"
}, {
  "product": "33333",
  "description": "description 3"
}];

jsonOptions.forEach(function(item) {

  var option = '<option value="' + item.product + '">' + item.description + '</option>';

  dataList.append(option);
});

$(function() {
  $('body').on('input', '.product,.products', function() {

    var i = this.value;
    var description = "";
    var productsInBox = 0;

    jsonOptions.forEach(function(a) {
      if (a.product == i) {
        description = a.description;
      }
    });
    $(this).closest('.form-group').find('.description').val(description);


  });
});

counter = 0;

$('#form1').on('click', '.addButtonDED', function() {
    counter++;
    var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
      .find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
      .find('[name="description-'+ (counter-1) +'"]').attr('name', 'description-' + counter).end()
      .find('i').removeClass('fa-plus').addClass('fa-minus').end();
    $template.insertAfter('.form-group:last');
  })

  // Remove button click handler
  .on('click', '.removeButtonDED', function() {
    counter--;
    var $row = $(this).closest('.form-group');
    $row.remove();
  });
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" method="post" class="form-horizontal" role="form">
  <fieldset>


    <div class="form-group">
      <div class="col-xs-2">
        <input type="text" list="products" class="form-control product" name="product" />
        <datalist id="products" class="products"></datalist>
      </div>

      <div class="col-xs-4">
        <input id="" type="text" class="form-control description" name="description-0" />
      </div>



      <div class="col-xs-1">
        <button type="button" class="btn btn-default addButtonDED"><i class="fa fa-plus"></i></button>
      </div>
    </div>

    <div class="col-xs-10 ">
      <button type="submit" name="formAction" value="next" class="btn btn-primary">sUBMIT</button>

    </div>



  </fieldset>
</form>
Carsten Løvbo Andersen
  • 26,637
  • 10
  • 47
  • 77
1

Your actual issue is var $template = $('.form-group:last').clone(true, true) , specifically the :last bit which means that its going to grab the one on the bottom of the group therefore .find('[name="description-0"]') only matches the first time. After that, the element would have name="description-1" and that call wont find it.

Instead, always grab the first element:

var $template = $('.form-group').eq(0).clone(true, true)

Working jsFiddle

However,

Why are you incrementing your name attributes at all?

Are you sending this data to some server side processing like php? if so, why not use the array syntax like:

    <input id="" type="text" class="form-control description" name="description[]" />

See HTML Element Array, name="something[]" or name="something"?

Community
  • 1
  • 1
Wesley Smith
  • 19,401
  • 22
  • 85
  • 133
  • I am actually read these values from a `servlet`. At first I had as you wrote `name="description[]"` but I couldn't read the values.. that's why I am incrementing the name attributes. – yaylitzis Feb 22 '17 at 09:46
  • Your solution works, but when I fill the 1st row and then I press the add button, then the new line is the already filled with the data of the 1st line. Anyway, thx for info and that's why +1 voted you! – yaylitzis Feb 22 '17 at 10:09
0

You can use .find('.description').attr('name', 'description-' + counter).end()

Fiddle link

$('#form1').on('click', '.addButtonDED', function() {
  counter++;

  var $template = $('.form-group:last').clone(true, true).find('input').val('').end()
    .find('.addButtonDED').removeClass('addButtonDED').addClass('removeButtonDED').end()
    .find('.description').attr('name', 'description-' + counter).end()
    .find('i').removeClass('fa-plus').addClass('fa-minus').end();
  $template.insertAfter('.form-group:last');
  alert(counter)
})
Deep 3015
  • 9,929
  • 5
  • 30
  • 54