How to add new lines after HTML elements - javascript

I have a simple method for adding input boxes after a button is clicked. The goal of this method is to generate a set of input boxes with a newline inserted after each div.
In the screenshot above you can see that the divs are spaced properly. However, when the add_more button is clicked the generated inputs do not come out properly.
Expected:
The code should generate new input boxes like so:
<div>
Key Term 2: <input id="el2" type="text" value=""> <br>
</div>
<br>
Actual:
function add_more() {
// we've added more inputs.
addMore = true;
// set html generated to false, because new inputs have been added.
htmlGenerated = false;
// increment the number of inputs.
numberOfInputs++;
//fetch the input boxes.
inputs = document.getElementById("inputBoxes");
// create newline
br_key = document.createElement("br");
// create newline
br_description = document.createElement("br");
//create a new row for a key term.
row = document.createElement("div");
// set the key term text.
row.innerHTML = "Key Term ";
row.innerHTML += numberOfInputs;
row.innerHTML += " :";
// create the input for the key.
key = document.createElement("input");
key.setAttribute("id", "el" + numberOfInputs);
//add the key to the row.
row.appendChild(key);
row.after(br_key);
//create a row for the new description.
row2 = document.createElement("div");
// set the description text.
row2.innerHTML = "Description "
row2.innerHTML += numberOfInputs;
row2.innerHTML += " :";
// create the description input
description = document.createElement("input");
description.setAttribute("id", "dl" + numberOfInputs);
// add the description to the row.
row2.appendChild(description);
row2.after(br_description);
// add the rows for the key and the description to the inputBoxes.
inputs.appendChild(row);
inputs.appendChild(row2);
}
<div>Key Term 5 :<input id="el5"></div>
Any help figuring out this issue would be greatly appreciated. Thanks.

Your issue here is essentially incorrect HTML, CSS. I'd implement your inputs, etc. like this:
.full-width-label {
display:block;
}
<label class="full-width-label" for="1">Label</label>
<input type="text" id="1"/>
There are multiple ways to achieve the above, this is just one of your options but now you no longer need to embed the look into the HTML and the format of your HTML (line breaks) is independent of your look.
You might want to look into an off the shelf solution for these kinds of things, like Bootstrap or Tailwind

You can use make it in a simple way
HTML
add this jquery cdn
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<button type="button">Click Here</button>
<div class="appendDiv">
</div>
Js
$(document).ready(function (){
var button = document.getElementsByTagName('button');
var appendDiv = document.getElementsByClassName('appendDiv');
var key = 1;
var descKey = 1;
$('button').click(function(event){
event.preventDefault();
$(appendDiv).append('<div class="child"><div class="grand-child"><label>Key Form :'+ ' '+(++key)+'</label><input type="text" value=""/></div><div class="grand-child"></div><label>Description :'+ ' '+(++descKey )+'</label><input type="text" value=""/></div>');
})
})

Related

getElementByID.onchange not working after i update html with = innerHTML

My starting html looks like this:
<label> Names: </label><br>
<input type="text" class="form-control name" placeholder="name1" id="name1" name ="name1"><br>
and i have a variable that captures the html:
var html = "<label> Names: </label><br><input type=\"text\" class=\"form-control name\" placeholder=\"name1\" id=\"name1\" name =\"name1\"><br>"
Then I have an onchange operator that performs a couple functions when the first row has text in it. the .onchange is picked up fine the first time and the subsequent functions are run. I end up with an additional row:
for (n = 1; n < inputLength+1 ; ++n) {
var test2 = document.getElementById(dude+n);
test2.onchange = forFunction
}
function forFunction() {
for (m = 1; m < inputLength+1 ; ++m) {
var test = document.getElementById(dude+m)
if (test.value != "") {
var txt = "<input type=\"text\" class=\"form-control name\" placeholder="+dude+(m+1)+" id="+dude+(m+1)+" name="+dude+(m+1)+"><br>";
document.getElementById('group_names').innerHTML = updateHTML(txt);
//function updateHTML(txt)
}
}
}
var html = "<label> Names: </label><br><input type=\"text\" class=\"form-control name\" placeholder=\"name1\" id=\"name1\" name =\"name1\"><br>"
function updateHTML(txt) {
html = html + txt;
return html;
}
The issue is that after all that completes i end up with two input rows as desired: name1 and name2. However, when i enter text in those fields for a second time, the .onchange is not picked up. but the elements are there in the html when i inspect and view the html.
Also, when i
console.log(inputFormDiv.getElementsByTagName('input').length);
the length of the inputs increases from 1 to 2 after i first run functions (upon the first time i change the value in my input field) so that is getting recognized correctly, just not the .onchange.
thoughts?
The onchange will only work if added to the attribute on the html and the user clicks out of a textbox e.g:
<input onchange="forFunction()" type="text" class="form-control name" placeholder="name1" id="name1" name ="name1">
To add the onchange event in JavaScript code. Add the change event to the addEventListener e.g:
var test2 = document.getElementById(dude+n);
test2.addEventListener('change', forFunction, false)
However if you want the event to fire whilst the user is types a key then use the keypress event. e.g:
var test2 = document.getElementById(dude+n);
test2.addEventListener('keypress', forFunction, false
A basic example: https://jsfiddle.net/xrL6y012/1/
Instead of .innerHTML = html + text do .insertAdjacentHTML('beforeend', text), that way you keep the original html (and events binding).
Edit: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
I had the same problem, it seems like modifying the HTML will never work, regardless of how you do it (.innerHTML or .insertAdjacentHTML()).
The only way that worked for me is to append a child instead of editing the HTML, like so:
const span = document.createElement('span');
span.innerHTML = 'text and <b> html stuff </b>';
initialElement.appendChild(span);
And if you actually need to insert just pure text, then this works:
initialElement.append('just text');
Hope that helps.

Add element works but clears input value

I have a script below that adds an element to my form, another text input field. It adds the new text input field but if I type something into the first one then add a new field it removes the input text from the first one.
I cant see where im going wrong here, im fairly new to JavaScript so please go easy :)
function addAnother() {
var id = 1;
var elemebt = document.getElementById('quest');
var number = elemebt.getElementsByTagName('*').length;
var add = number + 1;
var element = '<input type="text" name="question[]" id="quest'+ add +
'" placeholder="Example: What previous experiance do you have?" class="form-control" id="cloan"><a id="name'+
add +'" onClick="removeEle('+ add +')">Remove</a>';
document.getElementById('quest').innerHTML += element;
}
In JavaScript, the following two statements are practically identical:
str = str + ' more text ';
str += ' more text ';
The key point here is that in the end, the value of str is COMPLETELY OVERWRITTEN.
In your case, that means the innerHTML of the "quest" element is overwritten and the browser completely recreates it's children nodes, thus reseting any state and input values.
To overcome this, you can use the appendChild method but you first need to create the element to append. The easiest way to do that given you have a string of your HTML is to inject that string into a dummy element using the innerHTML property:
var target = document.getElementById('target');
var tDiv = document.createElement('div');
var htmlString = '<input type="text"></input>';
tDiv.innerHTML = htmlString;
target.appendChild(tDiv.children[0]);
<div id="target">Keep my content safe!</div>

How to insert a line break with javascript?

The Submit Form I have has the name, email, and phone number fields. Of course, I want to insert line break between the three. I tried to insert a line break between all three, but only generated one at the end of the form, when my code should appended 3 line breaks, not one.
The generated view source shows this:
<label>Name: </label><input required="" name="fullName" type="text"><label>Email: </label> <input required="" name="email" type="text"><label>Phone Number: </label><input required="" name="phoneNumber" type="text"><br><input value="Submit Query" type="submit"></form>
My Javascript Code to produce this form:
function queryForm()
{
var queryBox = document.getElementById("queryBox").style.display = "block";
var queryForm = document.getElementById("queryForm");
var linebreak = document.createElement("br");
var lblName = document.createElement("label");
lblName.textContent = "Name: ";
queryForm.appendChild(lblName);
var fullName = document.createElement("input");
fullName.name = "fullName";
fullName.type = "text";
fullName.required = "required";
queryForm.appendChild(fullName);
queryForm.appendChild(linebreak);
var lblEmail = document.createElement("label");
lblEmail.textContent = "Email: ";
queryForm.appendChild(linebreak);
queryForm.appendChild(lblEmail);
var email = document.createElement("input");
email.name = "email";
email.type = "text";
email.required = "required";
queryForm.appendChild(email);
var lblPhoneNumber = document.createElement("label");
lblPhoneNumber.textContent = "Phone Number: ";
queryForm.appendChild(linebreak);
queryForm.appendChild(lblPhoneNumber);
var phoneNumber = document.createElement("input");
phoneNumber.name = "phoneNumber";
phoneNumber.type = "text";
phoneNumber.required = "required";
queryForm.appendChild(phoneNumber);
var submitQuery = document.createElement("input");
submitQuery.type = "submit";
submitQuery.value = "Submit Query";
queryForm.appendChild(linebreak);
queryForm.appendChild(submitQuery);
}
You should create new <br> tag each time when you will append it, something like
linebreak = document.createElement("br");
queryForm.appendChild(linebreak);
DEMO
You should try to append each time a new node, and not the same one that was previously created, i.e:
queryForm.appendChild(document.createElement("br"));
EDIT:
the explanation is here on the documentation
Node.appendChild
Adds a node to the end of the list of children of a specified parent node. If the node already exists it is removed from current parent node, then added to new parent node.
https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild
The problem with your code is you're inserting the same element over and over again.
Here's an analogy: Imagine you have several children lined up in a row. Yes you can attempt to move one of them after each of the other children, however, at the end of the day you still only have one of that child. He's going to end up at the end of the row.
Solution: Create the line break element each time you need to insert it.
Also, here's an obligatory plug for jQuery: http://www.jquery.com
Protip: Append your inputs to your labels. That way a user can click the label to get focus on the input.
This has the additional perk that you can simply apply the CSS display:block to your labels and have them on separate lines!
You can use the classic \n to get this to work. I used this solution for a multi-line textarea in my project, but I cut out some code to simplify the example:
explanation.value = 'Equation: ' + equation;
explanation.value += '\nAnswer: ' + answer;

Maintaing Input Values in Dynamically Generated Fields

I have the following JavaScript which generates text-inputs dynamically and inserts them into a div. This code works fine, but if I type text into the field, then click the button to add another field I lose the text I typed in the first field.
I made a jFiddle - but for some reason it's not working. The same code works fine in my browser though.
Here's the function in question:
var optCount = 0;
function addOption(type){
var cont = document.getElementById('new'+type+'Opts');
cont.innerHTML = cont.innerHTML + "<span style='display:block;' id='opt" + optCount + "'><input type='text' style='width:80%;' />[x]<br /></span>";
optCount++;
return false;
}
How can I maintain the values of the existing fields when adding additional fields?
Don't replace the entire contents of the div every time. Instead, just create the new option and append it.
var cont = document.getElementById("new"+type+"Opts");
var span = document.createElement('span');
span.className = 'block';
span.id = "opt" + optCount;
span.innerHTML = "<input type='text' class='width80' />[x]<br />";
optCount++;
cont.appendChild(span);
http://jsfiddle.net/ExplosionPIlls/PBp4g/5/

Dynamically creating a specific number of input form elements

I've read many blogs and posts on dynamically adding fieldsets, but they all give a very complicated answer. What I require is not that complicated.
My HTML Code:
<input type="text" name="member" value="">Number of members: (max. 10)<br />
Fill Details
So, a user will enter an integer value (I'm checking the validation using javascript) in the input field. And on clicking the Fill Details link, corresponding number of input fields will appear for him to enter. I want to achieve this using javascript.
I'm not a pro in javascript. I was thinking how can I retrieve the integer filled in by the user in input field through the link and displaying corresponding number of input fields.
You could use an onclick event handler in order to get the input value for the text field. Make sure you give the field an unique id attribute so you can refer to it safely through document.getElementById():
If you want to dynamically add elements, you should have a container where to place them. For instance, a <div id="container">. Create new elements by means of document.createElement(), and use appendChild() to append each of them to the container. You might be interested in outputting a meaningful name attribute (e.g. name="member"+i for each of the dynamically generated <input>s if they are to be submitted in a form.
Notice you could also create <br/> elements with document.createElement('br'). If you want to just output some text, you can use document.createTextNode() instead.
Also, if you want to clear the container every time it is about to be populated, you could use hasChildNodes() and removeChild() together.
<html>
<head>
<script type='text/javascript'>
function addFields(){
// Generate a dynamic number of inputs
var number = document.getElementById("member").value;
// Get the element where the inputs will be added to
var container = document.getElementById("container");
// Remove every children it had before
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
// Append a node with a random text
container.appendChild(document.createTextNode("Member " + (i+1)));
// Create an <input> element, set its type and name attributes
var input = document.createElement("input");
input.type = "text";
input.name = "member" + i;
container.appendChild(input);
// Append a line break
container.appendChild(document.createElement("br"));
}
}
</script>
</head>
<body>
<input type="text" id="member" name="member" value="">Number of members: (max. 10)<br />
Fill Details
<div id="container"/>
</body>
</html>
See a working sample in this JSFiddle.
Try this JQuery code to dynamically include form, field, and delete/remove behavior:
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".container1");
var add_button = $(".add_form_field");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) {
x++;
$(wrapper).append('<div><input type="text" name="mytext[]"/>Delete</div>'); //add input box
} else {
alert('You Reached the limits')
}
});
$(wrapper).on("click", ".delete", function(e) {
e.preventDefault();
$(this).parent('div').remove();
x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container1">
<button class="add_form_field">Add New Field
<span style="font-size:16px; font-weight:bold;">+ </span>
</button>
<div><input type="text" name="mytext[]"></div>
</div>

Categories