Create fields with certain placeholders in a row

Viewed 69

With the help of the comunity (Thanks all of you !) I manage to create 3 fields at a time in a single row, anytime the user needs it. The thing is that everytime it create the fields, the placeholder is always "Another field". I would like that instead of that says Infrastracture, Time, Monthly Cost", but I have no clue how to do that.

Thank you Kindly !

Html Code:

<!doctype html>
<html>
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
    
    <!-- Awsome Fonts-->
    <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

    <!-- Styling -->
    <link rel="stylesheet" type="text/css" href="style.css">

    <!-- My Title-->
    <title>Hello, world!</title>
  </head>
  
  <body>
      
      <form class="Form" id="formulario">
          <h1>Factibilidad Técnica y Operativa</h1>
          <h2>Análisis de Infraestructura</h2>

          <!-- Campos en Columnas-->
        <div class="container" id="contenedor">
            <div class="row" id="campo">

              <div class="col-lg-4 mb-2">
                <input type="text" class="form-control" placeholder="Infraestructura">
              </div>

              <div class="col-lg-4 mb-2">
                <input type="text" class="form-control" placeholder="Tiempo">
              </div>

              <div class="col-lg-4 mb-2">
                  <input type="text" class="form-control" placeholder="Costo Mensual">
              </div>
                
            </div>
        </div>
        
          <!-- Iconos de Agregar / Eliminar Campos-->
          <div class="Controls">
            <a href="#" id="add_more_fields" onclick="createTwoInput()"><i class="fa fa-plus-square"></i>Añadir</a>
            <a href="#" id="removefields" onclick="Eliminar()"><i class="fa fa-minus-square"></i>Eliminar</a>
          </div>

      </form>
          <!-- JS Script-->    
          <script src="script.js"></script>
  </body>
</html>

JavaScript Code:

var survey_options = document.getElementById('campo');
var add_more_fields = document.getElementById('add_more_fields');
var remove_fields = document.getElementById('remove_fields');

function Añadir(){
    var newDiv = document.createElement('div');
    newDiv.setAttribute('class', 'col-lg-4 mb-2')

    var newField = document.createElement('input');
    newField.setAttribute('type','text');
    newField.setAttribute('class','form-control');
    newField.setAttribute('placeholder','Another Field');
    survey_options.appendChild(newDiv);
    newDiv.appendChild(newField);
 
}

function createTwoInput(){
  Añadir();
  Añadir(); 
  Añadir();  
}


function Eliminar(){
    var input_tags = survey_options.getElementsByTagName('input');
    if(input_tags.length > 2) {
        survey_options.removeChild(input_tags[(input_tags.length) - 1]);
    }
}
2 Answers

One options is to pass into your function the number of items you want to create, and pull the placeholder from an array, like this:

let survey_options = document.querySelector('.survey_options')

function Añadir(num_create) {
  let placeholders = ["Infrastracture", "Time", "Monthly Cost"];
  for (let x = 0; x < num_create; x++) {
    var newDiv = document.createElement('div');
    newDiv.setAttribute('class', 'col-lg-4 mb-2')

    var newField = document.createElement('input');
    newField.setAttribute('type', 'text');
    newField.setAttribute('class', 'form-control');
    newField.setAttribute('placeholder', placeholders[x]);
    survey_options.appendChild(newDiv);
    newDiv.appendChild(newField);
  }

}

Añadir(3);
<div class='survey_options'></div>

Make a function that can add or remove a .row depending on exactly whitch button was clicked.

Event Delegation

  1. Register the 'click' event to an element that contains all of the elements you need to listen for events on. This element (ex. <form id='infra'>) is called the listener and once the event (ex. 'click') triggers, the event handler (ex. addRem()) will run.
    const ui = document.forms.infra;
    ui.onclick = addRem;
    
  2. The event handler addRem(event) passes the Event Object (ex. (event)) which has a property that helps determine what the user clicked called .target.
    const clicked = event.target;
    if (clicked.matches('#add')) {...}
    else if (clicked.matches('#rem')) {...}
    else {...}
    
  3. When 'button#add' is clicked, instead of writing a line of code for each and every attribute, element, etc. create a htmlString that represents everything that needs to be rendered. In addRem() it's row variable which is rendered into real HTML by .insertAdjacentHTML() method.
    const row = `<section class='row'>`Everything within`</section>`;
    main.insertAdjacentHTML('beforeEnd', row);
    
  4. When 'button#rem' is clicked, it removes the last .row unless there's only one left.
    let rows = main.querySelectorAll('.row');
    ...&& rows.length > 1) {
    rows[rows.length-1].remove();
    

Example 1

const ui = document.forms.infra;
const io = ui.elements;

ui.onclick = addRem;

function addRem(event) {
  const clicked = event.target;
  const main = document.querySelector('.container');
  let rows = main.querySelectorAll('.row');
  
  if (clicked.matches('#add')) {
    const row = ` <section class="row"> <hr> <div class="col-lg-4 mb-2"> <input name='infs' class="form-control" type="text" placeholder="Infraestructura"> </div> <div class="col-lg-4 mb-2"> <input name='time' class="form-control" type="text" placeholder="Tiempo"> </div> <div class="col-lg-4 mb-2"> <input name='cost' class="form-control" type="text" placeholder="Costo Mensual"> </div> <hr> </section>`;
    main.insertAdjacentHTML('beforeEnd', row);
  } else if (clicked.matches('#rem') && rows.length > 1) {
    rows[rows.length-1].remove();
  } else {
    return false;
  }
};
.btn-group {
  float: right;
}
<!DOCTYPE html>
<html lang='es'>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet">
  <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <title>Hello, world!</title>
</head>

<body>

  <form class="form" id="infra">
    <h1>Factibilidad Técnica y Operativa</h1>
    <h2>Análisis de Infraestructura</h2>

    <main class="container">
      <section class="row">
        <hr>
        <div class="col-lg-4 mb-2">
          <input name='infs' class="form-control" type="text" placeholder="Infraestructura">
        </div>

        <div class="col-lg-4 mb-2">
          <input name='time' class="form-control" type="text" placeholder="Tiempo">
        </div>

        <div class="col-lg-4 mb-2">
          <input name='cost' class="form-control" type="text" placeholder="Costo Mensual">
        </div>
        <hr>
      </section>
    </main>

    <nav class="btn-group">
      <button id='add' class='btn btn-success' type='button'>
        <i class="fa fa-plus-square"></i> Añadir
      </button>
      <button id='rem' class='btn btn-danger' type='button'>
        <i class="fa fa-minus-square"></i> Eliminar
      </button>
    </nav>

  </form>

</body>

</html>

Example 2

Variation of adding .row using .cloneNode()

const ui = document.forms.infra;
const io = ui.elements;

ui.onclick = addRem;

function addRem(event) {
  const clicked = event.target;
  const main = document.querySelector('.container');
  let rows = main.querySelectorAll('.row');
  
  if (clicked.matches('#add')) {
    let row = rows[0].cloneNode(true);
    let inputs = row.querySelectorAll('input');
    inputs.forEach(input => input.value = '');
    main.appendChild(row);
  } else if (clicked.matches('#rem') && rows.length > 1) {
    rows[rows.length-1].remove();
  } else {
    return false;
  }
};
.btn-group {
  float: right;
}
<!DOCTYPE html>
<html lang='es'>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet">
  <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <title>Hello, world!</title>
</head>

<body>

  <form class="form" id="infra">
    <h1>Factibilidad Técnica y Operativa</h1>
    <h2>Análisis de Infraestructura</h2>

    <main class="container">
      <section class="row">
        <hr>
        <div class="col-lg-4 mb-2">
          <input name='infs' class="form-control" type="text" placeholder="Infraestructura">
        </div>

        <div class="col-lg-4 mb-2">
          <input name='time' class="form-control" type="text" placeholder="Tiempo">
        </div>

        <div class="col-lg-4 mb-2">
          <input name='cost' class="form-control" type="text" placeholder="Costo Mensual">
        </div>
        <hr>
      </section>
    </main>

    <nav class="btn-group">
      <button id='add' class='btn btn-success' type='button'>
        <i class="fa fa-plus-square"></i> Añadir
      </button>
      <button id='rem' class='btn btn-danger' type='button'>
        <i class="fa fa-minus-square"></i> Eliminar
      </button>
    </nav>

  </form>

</body>

</html>

Related