Best way to dynamically add and remove fields?

I made a way to add and remove fields using input[type"number"]. I use jquery for this, but the way I did it is not perfect. If there is a value in the field, the value will be erased if the value of the number changes due to use .remove(). Is there a better way to do this?

<body>
    <input type="number" id="num" min="0" max="20" required/>
    <div class="dynamicInput"></div>
</body>

<script>
    $('#num').bind('keyup mouseup', function () {
        $('.dynamicInput .row').remove();
        $('.dynamicInput h4').remove();
        if ($(this).val() > 0) {
            $('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
            var num = $(this).val();
            for (var i = 0; i < num; i++) {
                $('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
            }
        }
    });
</script>

My script

+4
source share
6 answers

Try something like this. Instead of deleting all inputs each time, it simply removes those that are on the end, or adds more to the end.

, var totNum = 0;, . , , /.

var totNum = 0;
$(document).on('keyup mouseup', '#num', function(){
  var num = $(this).val();
  if (num != "")
  {
    if (totNum == 0)
       $('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
    for (var i = num; i < totNum; i++)
    {
       $('.dynamicInput .row:last-child').remove();
    }
    for (var i = totNum; i < num; i++)
    {
       $('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
    }
    totNum = num;

    if (totNum == 0)
    {
       $('.dynamicInput h4').remove();
       $('.dynamicInput .row').remove();
    }
  }
});
input[type="number"] {
  width: 200px;
  height: 30px;
  font-family: Arial, sans-serif;
  font-size: 20px;
}
.row {
  display: block;
  margin-bottom: 15px;
}
body {
  width: 100%;
  padding: 40px;
}
input[type="text"] {
  width: 100%;
}
.col1,
.col2 {
  width: 45%;
  display: inline-block;
  margin-right: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

<body>
  <input type="number" id="num" min="0" max="20" required/>
  <div class="dynamicInput"></div>
</body>
Hide result
+2

, , , . : , "change".

. - , , , .

, , "" , . , "change" , .

, "" , "" , . , .

$(function () {

  var data = []; // data source
  var $num = $('#num'); // input for number of rows
  var $left = $('#left'); // left panel
  var $right = $('#right'); // right panel
  
  // render the right panel at starting

  renderRightPanel();

  // when the number of rows changes:
  //  - rebuild the left panel entirely
  //  - keep the data list up to date
  //  - print the array to the right panel

  $num.on('keyup mouseup', function () {
    renderLeftPanel($(this).val());
    updateList();
    renderRightPanel();
  });

  // when a value changes:
  //  - keep the data item up to date
  //  - print the array to the right panel

  $left.on('change', 'input', function () {
    var i = $left.find('input').index(this);
    updateItem(i, $(this).val());
    renderRightPanel();
  });

  // updates the data list

  function updateList () {
    data = $left.find('input').map(function () {
      return $(this).val();
    }).get();
  }

  // updates a single data item

  function updateItem (index, value) {
    data[index] = value;
  }

  // refreshes the DOM of the right panel

  function renderRightPanel () {
    $right.html('<pre>data = ' + (
      JSON.stringify(data, 0, 4)
    ) + '</pre>');
  }

  // refreshes the DOM of the left panel

  function renderLeftPanel (nLines) {
    var i;
    var html = '';
    if (nLines > 0) {
      html = '<h4>Heading</h4>';
      for (i = 0; i < nLines; i++) {
        html += '<div><input value="' + (data[i] || '') + '" /></div>';
      }
    }
    $left.html(html);
  }
});
body * {
  padding: 0;
  margin: 0;
}

h4, input {
  margin-bottom: .5em;
}

#panels {
  border: 1px solid black;
}

#panels > div {
  display: table-cell;
  padding: 1em;
}

#right {
  border-left: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Number of inputs: <input id="num" type="number" value="0" /></div>
<div id="panels">
  <div id="left"></div
  ><div id="right"></div>
</div>
Hide result
+2

. , . . fiddle

In the latter case, if you do not want to save the values ​​of hidden elements, change .hide()to.hide().val("")

<body>
    <input type="number" id="num" min="0" max="20" required/>
    <div class="dynamicInput">
        <h4>Please fill in the name and email of each extra attendees</h4>
    </div>
</body>

<style>
    .col1, .col2 { display: inline; width: 48%; margin-right: 2%; }
    .row { padding: 5px; }
</style>

<script>
    for (var i = 0; i < 20; i++) {
        $('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
    }
    $('#num').bind('keyup mouseup', function () {
        var num = parseInt($(this).val());
        $('.dynamicInput .row')
            .slice(num)
            .hide()
            .attr('disabled','disabled');
        if ( num > 0) {
            $('.dynamicInput .row')
                 .slice(0,num).show()
                 .removeAttr('disabled');
            $('.dynamicInput h4').show();
        } else {
            $('.dynamicInput h4').hide();
        }
    }).trigger('keyup');
</script>
+1
source

You can cache values ​​in javascript so as not to lose them between changes #num. eg.

(function($){
  var $num = $('#num'),
      $dynamic = $('.dynamicInput');
      cache = {};
  
  $dynamic.on('change', 'input', function(e){
    cache[$(this).prop('name')] = $(this).val();
  });
  
  $num.on('change keyup mouseup', function(e){
    $dynamic.empty();
    
    var val = parseInt($(this).val(), 10);
    if (!isNaN(val) && val > 0){
      $('<h4>')
        .text('Please fill in the name and email of each extra attendees')
        .appendTo($dynamic);
      for (var i = 0; i < val; i++){
        
        var nameName = 'attendeesName' + i,
            emailName = 'attendeesEmail' + i;
        
        var $row = $('<div>',{'class':'row'}),
            $col1 = $('<div>',{'class':'col1'}).appendTo($row),
            $col2 = $('<div>',{'class':'col2'}).appendTo($row);
        
        $('<input>',{
          'type': 'text',
          'name': nameName,
          'placeholder': 'Name',
          'required': 'true'
        }).val(cache[nameName] || '').appendTo($col1);
        $('<input>',{
          'type': 'email',
          'name': emailName,
          'placeholder': 'Email',
          'required': 'true'
        }).val(cache[emailName] || '').appendTo($col2);
        
        $row.appendTo($dynamic);
      }
    }
  });
  
})(jQuery);
input[type="number"] {
    width:200px;
    height:30px;
    font-family:Arial, sans-serif;
    font-size:20px;
}
.row {
    display:block;
    margin-bottom:15px;
}
body{
    width:100%;
    padding:40px;
}
input[type="text"]{
    width:100%;
}
.col1, .col2{
    width:45%;
    display:inline-block;
    margin-right:10px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<input type="number" id="num" min="0" max="20" required/>
<div class="dynamicInput"></div>
Run codeHide result
0
source

Here is an attempt to improve the accepted answer:

$(function () {

  var $num = $('#num');
  var $panel = $('#panel');
  var h4 = '<h4>Heading</h4>';
  var row = '<div><input /></div>';

  $num.on('mouseup keyup', function () {
    var n, $inputs;
    var value = $(this).val();
    if (value <= 0) {
      $panel.empty();
    }
    else {
      $inputs = $panel.find('input');
      // get the number of inputs already added
      n = $inputs.size();
      // add your heading if there is no input
      if (n === 0) {
        $panel.append(h4);
      }
      // the user wants less inputs
      if (value < n) {
        $inputs.slice(value).remove();
      }
      // the user wants more inputs
      else if (value > n) {
        $panel.append( 
          // a little trick, see below
          new Array(value - n + 1).join(row)
        );
      }
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Number of inputs: <input id="num" type="number" value="0" /></div>
<div id="panel"></div>
Run codeHide result

Word in array combining trick:

var a = [1, 2, 3, 4];
console.log(a.join('+'));
// prints "1+2+3+4"

var b = new Array(4); // an array of 4 undefined items
console.log(b.join('+'));
// prints "+++"

var c = new Array(3);
console.log('<ul>' + c.join('<li>item</li>') + '</ul>');
// prints "<ul><li>item</li><li>item</li></ul>"
0
source

This is what you are looking for

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
 $(document).ready(function(){
    $("#num").keyup(function(){
    $('.dynamicInput .row').remove();
    $('.dynamicInput h4').remove();
    if ($(this).val() > 0) {
        $('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
        var num = $(this).val();
        for (var i = 0; i < num; i++) {
            $('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
        }
    }
    });
});
</script>
</head>
<body>
    <input type="number" id="num" min="0" max="20" required/>
    <div class="dynamicInput"></div>
</body> 
</html>
-2
source

Source: https://habr.com/ru/post/1605779/


All Articles