Maintaing Input Values in Dynamically Generated Fields - javascript

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/

Related

How to add new lines after HTML elements

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>');
})
})

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.

How to make automatic input line appender in js?

I'm having an HTML page with an input line and a submit button.
I'm wanting to automatically generate a new line under the line if we change the first line content.
Before searching for this, I just made a second button named "Add new line" (explicit).
HTML part
print '<input type="button" id="addLineButton" value="Ajouter ligne"/>';
print '<input type="submit" id="valider" value="Rechercher"/>';
JS part
$("#addLineButton").click(function(e){
e.preventDefault();
var newLine = "";
document.getElementById("nbLines").textContent = Number(document.getElementById("nbLines").textContent) + 1;
var nbLines = Number(document.getElementById("nbLines").textContent);
newLine += "<input type='text' id='line"+nbLines+"' placeholder='Ref article'/><input type='number' id='qty"+nbLines+"' placeholder='Qté étiquettes'/><br>"
$("#zoneOF").append(newLine);
});
$("#zoneOF") is a div, and nbLines is a label which is used to count how many lines we already have.
I'm then searching (but not founding because I don't know how to formulate it clearly) what can I do to remove my addLineButton and automate the line adding (surely with on change event).
I wouldn't be surprised if you didn't understood sthg, then don't hesitate to ask me to reformulate.
Thank you in advance.
Ok I resolved it, by simply making my code recursive.
$(document).ready(function(){
var newLine = "";
document.getElementById("nbLines").textContent = Number(document.getElementById("nbLines").textContent) + 1;
var nbLines = Number(document.getElementById("nbLines").textContent);
newLine += "<input type='text' id='line"+nbLines+"' placeholder='Ref article'/><input type='number' id='qty"+nbLines+"' placeholder='Qté étiquettes'/><br>"
$("#zoneOF").append(newLine);
$('#line'+nbLines).on('change', function() {
setNewLine();
});
function setNewLine() {
var newLine = "";
document.getElementById("nbLines").textContent = Number(document.getElementById("nbLines").textContent) + 1;
var nbLines = Number(document.getElementById("nbLines").textContent);
newLine += "<input type='text' id='line"+nbLines+"' placeholder='Ref article'/><input type='number' id='qty"+nbLines+"' placeholder='Qté étiquettes'/><br>"
$("#zoneOF").append(newLine);
$('#line'+nbLines).on('change', function() {
setNewLine();
});
}
I make a new line at the document creation, and I put the on change event on it. The on change calls a function which creates a new line, and the function calls herself when the on change event is triggered on the new line.

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>

Use jQuery insertAfter in existing function that appends table

Here is what I have so far: http://jsfiddle.net/JEAkX/1/
I am trying to get the appended cells to come after the last tr. Furthermore, I am attempting to change the appendTable(id) function so that the output cells have their content inside an <input> field like the original cells.
For the <input> addition I have tried:
Adding the input field code <input type='text' size='1' value='subset[i++]' /> at various point with no luck I also tried it in another location but changed the value to value='c'.
For append after last tr I have tried:
Using jQuery and .insertAfter('#alphabetTable tbody>tr:last') I added it to various parts of the cell.appendChild(document.createTextNode(subset[i++])); line but had no luck..probably the wrong placement?
I feel like I am sort of on the right track but lack the Javascript knowledge to know exactly where to insert the code and if surrounding code needs change.
It'll be easier with JQuery but here's a hint:
function appendTable(id)
{
var tbody = document.getElementById(id).getElementsByTagName("tbody")[0];
var i = 0;
var html = '<tr>';
for(i=0;i<4;i++){
html += '<td><input type="text" size="1"/></td>';
}
html += '</tr>';
tbody.innerHTML += html;
}
Jquery:
var $tbody = $('#mytableid tbody:eq(0)');
var $tdLen = $('#mytableid tbody:eq(0) tr:eq(0) td').length; // cell length in row
$("<tr>").appendTo($tbody);
//append cells to row with input text
for (var i=0;i<$tdLen;i++){
var inp = $("<input>").attr("type","text").attr("name","text"+i).val(i);
var tdTemo = $("<td>");
inp.appendTo(tdTemo);
tdTemo.appendTo("tr:last");
}
this script will append row to table and add 4cells contain input type text :)

Categories