How to add remove input fields dynamically using javascript
Updated: 26-Oct-2022 / Tags: HTML, CSS and Javascript / Views: 13473 - Author: George
Introduction
Hello everyone, in this tutorial, we are going to add and remove dynamically input elements using plain JavaScript. We are going to see how to create elements using the createElement() method, and how to set attributes with the setAttribute() method.
I've also prepared a live demo that you can try out.
Live demo
Try out the demo below.
Write some text in the input field and press the plus (+) sign.
You will see that a new input field is created and in the previous one the plus (+) sign is changed to a minus (-) sign.
Create more than one input field and press the Display Notes button.
Please try out the example, it will give you a better understanding on what we are going to code.
Now that you have tried out the live demo, let's see how we code this.
Project's folder
/-- project-folder/ |-- index.html |-- script.js |-- styles.css
We need three files. An index.html, a script.js, and a styles.css file.
The CSS file
Let's start our application with the css file. Copy and paste the below css code in the styles.css file. I am not going to explain what is going on in the css file, it's basic styling applied to the html elements that we are going to write further down in the index.html file.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
font-family: sans-serif;
min-height: 100%;
color: #555;
width: 600px;
margin: 0 auto;
padding-top: 20px;
background-color: white;
}
h1{
text-align: center;
color: #888;
}
.notes{
padding: 20px;
}
.notes p{
border-bottom: thin dotted #d4d4d4;
padding: 20px 10px 0px 0px;
font-style: italic;
font-size: 18px;
}
.notes p span{
font-size: 16px;
float: right;
cursor: pointer;
display: inline-block;
}
.notes p span.mark{
color: green;
font-size: 30px;
transform: translateY(-10px);
}
form{
width: 100%;
}
.field{
margin-bottom: 10px;
display: flex;
transition: opacity 0.3s;
}
.field input{
padding: 5px 10px;
width: 100%;
border: none;
border: thin solid #d4d4d4;
font-size: 20px;
color: #888;
font-family: ubuntu, sans-serif;
background-color: #f9f9f9;
}
.field input:focus{
outline: none;
}
.field span{
display: inline-block;
margin-left: 10px;
cursor: pointer;
background-color: #f9f9f9;
padding: 10px;
font-size: 20px;
transition: all 0.3s;
font-weight: bold;
border: thin solid #d4d4d4;
}
.field span:last-child{
display: none;
padding: 12px;
}
.field span:hover{
background-color: green;
border: thin solid green;
color: #fff;
}
.field span:last-child:hover{
background-color: red;
border: thin solid red;
color: #fff;
}
button{
display: block;
padding: 10px 20px;
margin-top: 30px;
width: 150px;
float: left;
font-size: 16px;
background-color: #5b8ebf;
border: thin solid #d5e4d4;
cursor: pointer;
color: #fff;
}
button:active{
background-color: #aedea6;
color: #000;
}
.reset{
float: right;
background-color: green;
}
The index file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<!-- Link to the css file -->
<link rel="stylesheet" href="styles.css">
<title>Adding dynamically input fields</title>
</head>
<body>
<!-- Info text -->
<h2>Write a text note and press the plus button</h2>
<div class="notes">
<!--
The content will be created by javascript when
we click on the 'Display Notes' submit button.
-->
</div>
<form action="" method="post" autocomplete="off">
<div class="field">
<input type="text" name="notes[]">
<span onclick="addField(this)">+</span>
<span onclick="removeField(this)">-</span>
</div>
<button type="submit" >Display Notes</button>
</form>
<!-- Link to the javascript file -->
<script src="script.js"></script>
</body>
</html>
Let's explain the above form element.
Inside the form element we have a div element with a class of "field". And a submit button.
<form action="" method="post">
<div class="field">
<input type="text" name="notes[]">
<span onclick="addField(this)">+</span>
<span onclick="removeField(this)">-</span>
</div>
<button type="submit">Display Notes</button>
</form>
-
Inside the div with class of "field" element and in line 16 we have the input field.
<input type="text" name="notes[]">
Notice that the name attribute is set to an array named "notes[]". This is because we are going to create multiple input fields so we need an array to store the values when we submit the form.
Although we don't need to set an array for our example because we are going to use JavaScript to fetch the values, it is mandatory if we send the values to the server. Which we are not going to do in this tutorial.
-
Under the input field we have two span elements. In the first span we have the plus (+) sign, and in the second one we have the minus (-) sign.
<span onclick="addField(this)">+</span> <span onclick="removeField(this)">-</span>
On both span elements we have assigned an onclick event-listener. When we click on the first span which is the plus sign, a function named addField() will run and will create a new input field.
When we click on the second span a function named removeField() will run and will remove the whole "field" container.The keyword this refers to the span element. This way we are going to have a reference point in the javascript code to target the elements we want. You will see this when we get to the javascript file.
What i need to say is that the second span element is hidden by default by setting the display property to "none" in the css file. We are going to manipulate the span elements visibility in the javascript file.
Every time we are going to create a new input field in the javascript code, we will create the exact same "field" div element and all the elements inside, and in the same order.
-
And in line 21 we have the submit button.
<button type="submit">Display Notes</button>
And we are done with the index file, now let's go to the script.js javascript file and write the functions to make the application to work.
The javascript file
Before we start writing our functions in the script.js file, let's see them first.
- addField() ... The function will create a new input field.
- removeField() ... The function will remove an input field.
- fetchTextNotes() ... The function will fetch and display the created text-notes.
- markAsDone() ... The function will add a checkmark when a text-note is marked as done.
Now we are ready to start writing our functions, and we are going to begin with the addField() function.
The addField function
Let's start our javascript code with the addField() function. Remember that this function will run every time we click on the plus (+) sign.
function addField(plusElement){
let displayButton = document.querySelector("form button");
// Stopping the function if the input field has no value.
if(plusElement.previousElementSibling.value.trim() === ""){
return false;
}
// creating the div container.
let div = document.createElement("div");
div.setAttribute("class", "field");
// Creating the input element.
let field = document.createElement("input");
field.setAttribute("type", "text");
field.setAttribute("name", "notes[]");
// Creating the plus span element.
let plus = document.createElement("span");
plus.setAttribute("onclick", "addField(this)");
let plusText = document.createTextNode("+");
plus.appendChild(plusText);
// Creating the minus span element.
let minus = document.createElement("span");
minus.setAttribute("onclick", "removeField(this)");
let minusText = document.createTextNode("-");
minus.appendChild(minusText);
// Adding the elements to the DOM.
form.insertBefore(div, displayButton);
div.appendChild(field);
div.appendChild(plus);
div.appendChild(minus);
// Un hiding the minus sign.
plusElement.nextElementSibling.style.display = "block"; // the minus sign
// Hiding the plus sign.
plusElement.style.display = "none"; // the plus sign
}
Code breakdown
Let's break the addField() function down.
-
function addField(plusElement){
The function takes as an argument the plus span element.
-
let displayButton = document.querySelector("form button");
Inside the function we will target the submit button and we will store the element in the displayButton variable. We need the submit button to act as a reference point, so we can create the new input element above it.
-
if(plusElement.previousElementSibling.value.trim() === ""){ return false; }
Next we are going to check the input element, and if the field is empty, we will return false and stop the function here.
Let's explain how i target the input field by using this line of code: plusElement.previousElementSibling.value.
With the previousElementSibling property we are targeting the element that is above the span element and that is the input element. If you don't remember the html code, check out the form again in the index file, and you will see that this is the case.
And then we use the value attribute to get the input field's value.
-
let div = document.createElement("div"); div.setAttribute("class", "field");
Next we are going to create the new input element, by recreating the whole div with class of "field" container and all the elements inside, in the exact same order.
So lets start with the div container, and give it a class of "field".
In line 8 we creating the div element,
and in line 9 we set the class attribute to "field".
-
let field = document.createElement("input"); field.setAttribute("type", "text"); field.setAttribute("name", "notes[]");
Next we are going to create the input element.
In line 11 we are creating the input element.
In line 12 we set the type attribute to "text",
and in line 13 we set the name attribute to the "notes[]" array, as we did in the html form.
-
let plus = document.createElement("span"); plus.setAttribute("onclick", "addField(this)"); let plusText = document.createTextNode("+"); plus.appendChild(plusText);
Next we are creating the plus (+) span element.
In line 16 we set the "onclick" event-listener as an attribute, and as its value we set the addField() function. So when we click on the new created plus sign we will create another new element. It's like a circle, a loop. Hope it makes sense.
In line 17 we create a textNode which is the plus + character inside the span element.
And in line 18 we append the textNode to the span element.
-
let minus = document.createElement("span"); minus.setAttribute("onclick", "removeField(this)"); let minusText = document.createTextNode("-"); minus.appendChild(minusText);
We do the exact same thing as we did with the plus span element, to create the minus (-) span element.
-
form.insertBefore(div, displayButton); div.appendChild(field); div.appendChild(plus); div.appendChild(minus);
Next we are going to add the div container and it's children to the DOM.
In line 25 we are inserting the div container before the submit button. This way the new created element will always appear as the last element.
In line 26 we insert the input field in the div container.
In line 27 we inserting the plus span element in the div container.
And in line 28 we inserting the minus span element in the div container. With this last line of code we added in the div container all the new created elements.
-
plusElement.nextElementSibling.style.display = "block"; plusElement.style.display = "none"; } // end of addField function.
And last in line 30, we are targeting the minus span element and set the display property to "block". Remember that the minus span element is hidden by default.
And in line 31 we hiding the plus span element. If you checked out the live demo you saw that when we creating a new element we hide the plus sign and make visible the minus sign.
And in line 32 we are closing the addField() function.
And we are done with the addField() function now let's write the removeField() function.
Removing a field
The removeField function runs every time we click on the minus span element.
function removeField(minusElement){
minusElement.parentElement.remove();
}
The function takes as an argument the minus span element. So we use the minus element and we target it's parent which is the div "field" container and remove the whole element. And that's it, that is all the code we need to remove an input field.
Displaying the textNotes
Next in our javascript file we are going to catch the text-notes and we are going to display them in the "notes" element that we have above our form in the html file.
let form = document.forms[0];
form.addEventListener("submit", fetchTextNotes);
- In line 38 we are targeting the html form element, and store it in the form variable.
- And in line 39 we add an event-listener to the form element. The addEventListener method takes two arguments, the first argument is the event that we want to capture, in our case its the submit event, and as a second argument we pass in the name of the function that will run when we press the submit button. In our case this is the fetchTextNotes function.
Now let's write the fetchTextNotes function.
function fetchTextNotes(event){
event.preventDefault();
let data = new FormData(form);
let notes = [];
data.forEach( function(value){
if(value !== ""){
notes.push(value);
}
});
let out = "";
for(let note of notes){
out += `<p>${note} <span onclick="markAsDone(this)">Mark as done</span></p>`;
}
document.querySelector(".notes").innerHTML = out;
let inputFields = document.querySelectorAll(".field");
inputFields.forEach(function(element, index){
if(index == inputFields.length - 1){
element.children[0].value = "";
}else{
element.remove();
}
});
}
Code breakdown
Let's break the fetchTextNotes() function down.
-
function fetchTextNotes(event){ event.preventDefault();
We are gonna pass in the function the event object as an argument. We do this because i need access to the preventDefault() method, so i can stop the form submit the data to the server.
-
let data = new FormData(form); let notes = []; data.forEach( function(value){ if(value !== ""){ notes.push(value); } });
Next i am going to fetch the values from the created input fields, and i will create an array out of them.
- In line 44 we use the formData object, and we pass in the form element. We are storing the returned data in the data variable.
- Next in line 45 we create an empty array called notes.
- In line 46 we loop through the data array using the forEach method.
- In line 47 we check every value, and if it is NOT empty we store them in the notes array.
-
let out = ""; for(let note of notes){ out += `<p>${note} <span onclick="markAsDone(this)">Mark as done</span></p>`; } document.querySelector(".notes").innerHTML = out;
Next we are going to display the values in the notes html element.
- In line 52 we creating a variable named out, and set the value to an empty string.
- Next in line 53 we use a for of function to loop through the notes array.
-
In line 54 we adding in the out variable a paragraph element which holds the text-note and a span tag.
In the span tag we display the text "Mark as done", and also we assign an onclick event-listener which
fires the markAsDone() function.
The markAsDone() function will replace the text inside the clicked span element with a checkmark. You saw this in the live demo. - And in line 56 we target the "notes" element in the index file and we use the innerHTML property to display the created text-notes.
-
let inputFields = document.querySelectorAll(".field"); inputFields.forEach(function(element, index){ if(index == inputFields.length - 1){ element.children[0].value = ""; }else{ element.remove(); } }); } // end of function
Next as we saw in the live demo, we are going to delete all created input elements and leave only an empty one.
- In line 60 we use the querySelectoAll method to target all elements with a class of "field". The method returns a node-list, which we can handle as an array, and store it in the inputFields variable.
- In line 61 we loop through all the "field" elements using a forEach function.
-
In line 62 we are checking if the current "field" element is the last inside the array.
If the condition returns true we are setting the value to an empty string, else we remove the element.
This way we end up with only one empty input field.
And we are done with the fetchTextNotes() function, now let's write our last function which is the markAsDone() function.
Mark as done function
The markAsDone() function takes as an argument the clicked span element, and replaces the text with the checkmark.
function markAsDone(element){
element.classList.add("mark");
element.innerHTML = "✓";
}
-
In line 71 we add the "mark" css class to the span element, this changes the color, the font-size, and tweaks the position.
.mark{ color: green; font-size: 30px; transform: translateY(-10px); }
- And in line 72 we replace the text with the checkmark.
Summary
And that's it. In this tutorial we saw how to dynamically add and remove input fields in a form using the createElement() function in JavaScript.
Last Words
Thanks for reading, i hope you find the article helpful.
Please leave a comment if you find any errors, so i can update the page with the correct code.
Source code
You can download the source code and use it in any way you like.
Times downloaded: 1341