How to retain a text in textfield - javascript

I have a link the purpose of the link is to add a textfield dynamically when i click it. But the problem is that if i have entered a text in the previous generated textfield and click on the link, textfield is generated but the page refresh and the input text resets.
html file
<script>
var countBox =3;
var boxName = 0;
function addInput()
{
var boxName="textBox"+countBox;
document.getElementById('responce').innerHTML+='<br /><input type="radio" name="choices" value="o'+countBox+'" id="o'+countBox+'"/><label>Option '+countBox+':</label> <input type="text" id="option'+countBox+'" name="option'+countBox+'"" placeholder="Enter here..." /><br/>';
countBox += 1;
}
</script>
<br />Add another(max.5)
How can i add the textfield and also retain the the text in the textfield. Hope you understood my problem
Thanks in advance.

The page is not refreshed, so that's not the problem. The problem is that you are using .innerHTML += to add the new elements. This is will destroy and recreate the existing elements: The elements are serialized to HTML, then you are concatenating the string to add new HTML and after the assignment the browser has to parse the HTML to create DOM Elements again. In this process all data will be lost.
Use DOM manipulation methods instead. I.e. create the elements with document.createElement and add them with Node.appendChild.
Using .innerHTML to override existing content or to initialize an element for the first time is OK. But using it to add elements to an existing element can lead to problems (as mentioned above) so it is better avoided in this case.
Example:
function addInput() {
var boxName="textBox"+countBox;
var input = document.createElement('input');
input.id = input.name = 'option'+countBox;
var parent = document.getElementById('responce');
parent.appendChild(document.createElement('br'));
parent.appendChild(input);
// create/add other elements...
countBox += 1;
}
Or a mix of both:
function addInput() {
var boxName="textBox"+countBox;
var container = document.createElement('div');
container.innerHTML = '<input type="radio" name="choices" value="o'+countBox+'" id="o'+countBox+'"/><label>Option '+countBox+':</label> <input type="text" id="option'+countBox+'" name="option'+countBox+'"" placeholder="Enter here..." />';
document.getElementById('responce').appendChild(container);
countBox += 1;
}

Related

Iterate DOM property x times with JS

I basically have an input of type number
<input type="number" id="no_pi" name="" onkeyup="des()">
<div id="extract"></div>
and function
function des() {
var ext = document.getElementById('extract');
var va = Number(document.getElementById('no_pi').value);
for (var i = 0; i = va; i++) {
ext.innerHTML = "<input type='number' name='' class='form-control'><div class='input-group-text'>cm</div>";
}
}
I just want to instantly generate x number of inputs in div based on user input.
When the user input any number, the page just crashes down. I think the page is going in infinite loop, but I think it is not the case.
Any idea how to achieve this
There's several errors :
In your loop : i = va (this is why it crashes)
You erase the content of the div ext each time you iterate, instead of adding content
By listening on keyup event, you add some content on each key hit. Finally if the user submit 12, it will generate 1 + 12 elements. You should pass the value using a form (by doing this you can also add easily the value control in the input element).
As perfectly mentionned by #Andy in the comments, innerHTML += is a very bad idea. You should generate your elements using document.createElement or insertAdjacentHTML.
Some advices :
Use an event listener instead of the onkeyup attribute
Avoid this kind of variable names, be more explicit
Use const and let instead of var
Here's a version which fixes all that issues :
document.getElementById('elementsNumberForm').addEventListener('submit', event => {
event.preventDefault();
const targetElement = document.getElementById('extract');
const inputValue = document.getElementById('no_pi').value;
for (let i = 0; i < inputValue; i++) {
targetElement.insertAdjacentHTML('beforeEnd', '<input type="number" name="" class="form-control" /><div class="input-group-text">cm</div>');
}
});
<form id="elementsNumberForm">
<input type="number" id="no_pi" min="1" />
<input type="submit" />
</form>
<div id="extract"></div>
Your key issue is how you're using your loop. i = va isn't going to accomplish what you want. It should be a check that the index in the iteration is less than the number represented by the value in your input. It should be i < va.
The other issue is that you're not adding to the HTML, just ensuring that the HTML is just one input.
I've adjusted the code in your question to remove the inline JS and use addEventListener instead, and also to use an array to store the HTML built from the loop which can then be applied to the extract element.
// Cache the elements outside of the loop
// and attach a change listener to the noPi element
const extract = document.getElementById('extract');
const noPi = document.getElementById('no_pi');
noPi.addEventListener('change', des, false);
function des() {
const limit = noPi.value;
// Check that we haven't gone into
// negative numbers
if (limit >= 0) {
// Create an array
const html = [];
// Loop, pushing HTML into the array, until
// we've reached the limit set by the value in noPi
for (let i = 0; i < limit; i++) {
html.push('<input type="number" class="form-control"><div class="input-group-text">cm</div>');
}
// `join` up the array, and add the HTML
// string to the extract element
extract.innerHTML = html.join('');
}
}
<input type="number" id="no_pi" />
<div id="extract"></div>
Additional information
join
I see that you want to use an input field to insert the number of inputs to create.
I see a better way to start learning insert the number of inputs with a prompt, and then scale the project.
You can start like this: (hope it make sense to you)
<div style="height: 300px; background-color: #ccc;" class="container"></div>
we have this div that is going to be filled with the inputs
Then we have the script:
const container = document.querySelector('.container');
const runTimes = prompt("How many inputs wnat to create?");
for(let i = 0; i < runTimes; i++){
let newInput = document.createElement('input');
newInput.innerHTML = "<input type='number' name='' class='form-control'>";
container.appendChild(newInput);
}
In the for loop, we create the element input, then with the .innerHTML we add the HTML we want. to end the loop, we need to append the created input element to the div we have.
hope it makes sense to you, :)
when you get the idea with the prompt , I´ve done this project more pro jaja.
<div style="height: 300px; background-color: #ccc;" class="container"></div>
<input type="text" class="numberTimes" onkeyup="getValue()">
we add an event listener to the input with the function getValuue, and the script like this:
const container = document.querySelector('.container');
function getValue(){
let runTimes = document.querySelector('.numberTimes').value;
document.querySelector('.numberTimes').value= "";
for(let i = 0; i < runTimes; i++){
let newInput = document.createElement('input');
newInput.innerHTML = "<input type='number' name='' class='form-control'>";
container.appendChild(newInput);
}
}
This line document.querySelector('.numberTimes').value= ""; is to reset the input field.
So whenever insert a value on the input it creates that number of inputs in the container and cleans the input field :)

Adding form post/submit button to javascript script

I found this code on here (thanks to Xavi López) and it is ideal for what I need to add to my project but I'm in need of some help adding a Form post and submit button in JavaScript. I have no knowledge on this subject and I've tried looking at some example but non of them seem to work. I would be grateful if someone could help me. After the user adds the relevant number of input boxes and adds there data, I would like to have a submit button which will POST the results to another web page (result page)
I have added the solution to the below coding (thank you MTCoster) but I'm now try to find a solution to having the submit button appear only when an entry has been added. I have tried different methods but non will work.
function addFields() {
// Number of inputs to create
var number = document.getElementById('member').value;
// Container <div> where dynamic content will be placed
var container = document.getElementById('container');
// Clear previous contents of the container
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'));
}
}
<input type="text" id="member" name="member" value="">Number of Pins: (max. 48)<br>
Add Pinout Entries
<form action="result.asp" method="POST">
<div id="container"></div>
<input type="submit" value="Add Data">
</form>
You’re almost there - all you need to do is wrap your inputs in a <form> element:
function addFields() {
// Number of inputs to create
var number = document.getElementById('member').value;
// Container <div> where dynamic content will be placed
var container = document.getElementById('container');
// Clear previous contents of the container
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'));
}
}
<input type="text" id="member" name="member" value="">Number of Pins: (max. 48)<br>
Add Pinout Entries
<form action="/url/to/post/to" method="POST">
<div id="container"></div>
<input type="submit">
</form>
If you’d like the submit button to only appear after at least one input is visible, you could add it at to div#container at the end of addFields(). I’ll leave this as an exercise to the OP, since it’s not much different to how you’re adding the input fields.

Adding dom elements relative to input value

I have this function which add elements to the dom according to the value inserted into an input element, and if i insert new value in to the input the previous elements are erased and new elements are inserted.
what i want is to keep the old elements and add new ones to it
html:
<input type="text" placeholder="insert the number of div" class="number">
<button>submit</button>
<br>
<div id="wrapper"></div>
jquery:
$('button').click(function(){
var boxes = '';
var i;
var inputValue = $('.number').val();
for(i=0; i < inputValue; i++){
boxes += "<div class='box'></div>";
}
$('#wrapper').html(boxes);
});
Instead of $.html
$('#wrapper').html(boxes);
Use
$('#wrapper').append(boxes);
You can read more about both methods here:
append
html

How to save the values in existing input fields when adding a new one?

This is what my program's body looks like:
<form id = "input">
<input id = "0" >
</form>
<p onclick = "add()"> Add Another</p>
And on clicking the above The following function is executed:
var inputArea = document.getElementById("input");
next = 1;
function add(){
inputArea.innerHTML+= " <input id = " + next+ ">" ;
Where next is the id of new input field. In this case, since 0 already exists so value of next is 1.
One problem that I am encountering with this is that after adding a new input field, the values in all existing input fields are lost. How to save these values? My attempt is to place this code in function add():
for (i=0;i<next;i++)
{inputs[i] = document.getElementById(i);
inputV[i]= inputs[i].value;
inputs[i].value = inputV[i];}
But this does not works..
var inputArea = document.getElementById("input");
next = 1;
function add(){
inputArea.innerHTML+= " <input id = " + next+ ">" ;
var inputs = new Array();
var inputV = new Array();
for (i=0;i<next;i++)
{inputs[i] = document.getElementById(i);
inputV[i]= inputs[i].value;
inputs[i].value = inputV[i];}
next++;
}
<form id = "input">
<input id = "0" >
</form>
<p onclick = "add()"> Add Another</p>
You may want to dynamically add elements to your DOM tree like so
function add() {
var form = document.getElementById("input");
var input = document.createElement("input");
form.appendChild(input);
}
The problem with what you're doing is that when you write inside an input field, the changes are not represented in the HTML code, only in the memory of the browser. Thus if you add text through to code to form.innerHTML, the browser is going to reinterpret the text inside the form which will be
<input id="0"> <input id="1"> ...
and this will result in two empty input of type text being displayed.
Edit: you can then add your id tag via
function add() {
var form = document.getElementById("input");
var input = document.createElement("input");
input.id = someValue;
form.appendChild(input);
}
N.B. please indent your code in a somewhat logical manner.
The reason this is happening is that the dom, or more specifically inputArea's innerHtml doesnt get changed when you type into a form field. And what youre doing is resetting the innerHTML with a blank input BEFORE youre capturing the values.
so whats going on is you have HTML like this:
<input id='0' />
then type into the form so that it behaves like:
<input id='0' value='foo' />
but thats not what the innerHTML actual is. its still <input id='0' /> because the value is kept in memory not on the dom.
if you want to add new elements to the form, you need to use appendChild instead
so convert
inputArea.innerHTML+= " <input id = " + next+ ">"
to
inputArea.appendChild(document.createElement('input'))

How do I use window.find to change css style?

Through a combination of AJAX and PHP, I put some text data in a span at the bottom of the page. Now I want to search this text for a string. My page is full of checkboxes, and their values are the strings I will search for.
Goal: Using a loop, cycle through the values of all checkboxes on the page. Search the page for each checkbox's value (ideally, within the text in the AJAX-informed span). If the checkboxes value is found, change that checkboxes CSS style color.
My code so far: I have a form full of checkboxes all named "comment" each with unique IDs:
<input type="checkbox" name="comment" id="hjl1" value="the comment."
onclick="createOrder()"><label for="hjl1" onclick="createOrder()"
title="comment"> onscreen text for this checkbox </label>
When triggered , using Javascript, I go through every checkbox in that form.
var comment=document.forms[0].comment;
var txt="";
var ii;
for (ii=0;ii<comment.length;ii++)
{str=comment[ii].value;}
Now I want to insert window.find in that loop to check if that value is on my page.
if (window.find) {
var found = window.find (str);
if (!found) {
document.getElementById("?????").style["color"] = "red";
}
}
The idea is that when the checkbox is checked, the javascript would search for the value "the comment." on page. If found, the checkbox label will add the CSS style color red.
Somehow, I want to combine these ideas, but there are so many problems. How do I get the element by ID in this loop? Can window.find search the text created by php in my span?
Would it be better to not use window.find at all?
var source = document.getElementsByTagName('html')[0].innerHTML;
var found = source.search("searchString");
I'm so confused and new. Please be patient. Thank you for reading this far.
I misunderstood at first, and wrote code to highlight text within the page.
Yes, window.find is fine to use for this as you only need to know if the value exists or not. It might behave a bit odd (scroll to bottom) when used in frames though.
Also, I added a function for your onClick, but I'm not sure if this is wanted. It will change color of the label if text if found when clicked (also).
Below is a small example:
function checkThis(ele) {
var str = ele.value;
if (window.find) {
var found = window.find(str);
if (found) {
var id = ele.getAttribute('id');
var lbl = document.querySelectorAll('label[for="' + id + '"]');
if (lbl) lbl[0].style.color = "red";
}
}
}
window.onload = function() {
var comment = document.form1.getElementsByTagName('input');
for (var x = 0; x < comment.length; x++) {
if (comment[x].type == 'checkbox') {
var str = comment[x].value;
if (window.find) {
var found = window.find(str);
if (found) {
var id = comment[x].getAttribute('id');
var lbl = document.querySelectorAll('label[for="' + id + '"]');
if (lbl) lbl[0].style.color = "red";
}
}
}
}
}
<form name="form1">
<input type="checkbox" name="comment" id="hjl1" value="the comment." onclick="checkThis(this);" />
<label for="hjl1" onclick="createOrder()" title="comment">onscreen text for this checkbox</label>
<input type="checkbox" name="comment" id="hjl2" value="the comment2." onclick="checkThis(this);" />
<label for="hjl2" onclick="createOrder()" title="comment">onscreen text for this checkbox</label>
<br/>
<b>first comment.</b><br/>
<b>other comment.</b><br/>
<b>some comment.</b><br/>
<b>the comment.</b><br/>
<b>whatever comment.</b><br/>
<b>not this comment.</b><br/>
</form>
try this as your function code
function loopy() {
var comment=document.forms[0].comment;
var txt="";
var ii;
for (ii=0;ii<comment.length;ii++) {
if (comment[ii].checked) {
str=comment[ii].value;
id = comment[ii].id;
nextLabelId = comment[ii].nextSibling.id;
if (window.find) { // Firefox, Google Chrome, Safari
var found = window.find (str);
if (found == true) {
// found string
//comment[ii].style['outline']='1px solid red';
document.getElementById(nextLabelId).className = 'selected';
}
} else {
// this browser does not support find()
alert('not supported');
}
}
}
}
So, in order to get the checkbox id, you just add id = comment[ii].id in your loop.
To change the color, it's best to use class name and use styling in the css file. so if you want to change the label that is after the checkbox to red you will first find the label's id using nextSiblings and then add the .selected class name. Just remember that you need to remove the coloring if the user un-check the box
Regarding the usage of find(), not supported by all browser so this could be an issue and also not sure it will be able to find on the content you injected to the DOM by AJAX so this needs some testing.
I would suggest moving this code to jQuery as some features seems to be easier using their functionality.

Categories

Resources