so I have this HTML code:
<form method="get" action="#" id="startForm">
<input type="text" name="period" id="period" placeholder="The number of days"/>
<input type="submit" name="submit" value="submit" id="startSubmit"/>
</form>
and this is the JavaScript code:
var btnSubmit = document.getElementById('startSubmit');
btnSubmit.addEventListener('click', function (e) {
e.preventDefault();
var myForm = document.createElement('form');
var period = document.getElementById('period').value;
for(var i = 0; i < period ; i++){
var input0 = document.createElement('input');
input0.setAttribute('type', 'text');
input0.setAttribute('placeholder', 'The count of tasks');
input0.setAttribute('style', 'margin: 10px');
input0.setAttribute('id', 'taskDone'+i);
input0.setAttribute('onchange', 'myFunction()');
document.body.appendChild(input0);
myForm.appendChild(input0);
document.body.appendChild(myForm);
function myFunction(){
var taskDone = document.getElementById('taskDone').value;
var newForm = document.createElement('form');
for(var j = 0; j < taskDone ; j++){
var input1 = document.createElement('input');
input1.setAttribute('type', 'text');
input1.setAttribute('id', 'time'+i);
document.body.appendChild(input1);
newForm.appendChild(input1);
document.body.appendChild(newForm);
};
};
};
console.log(myForm);
});
so my problem is that in the function when I try to take the value from the generated DOM element it will reset the page what I want to do is to take the number that is going to be placed into the input and make as many new inputs textboxes as it's the number is typed (it takes the number from the generated dom element and creates new dom element)
You are just doing the wastage of memory you must not place the definition of function inside a loop. You must place it outside the block or a separate definition. You should only call the function inside loop. However, inside your
myFunction()
you are trying to get the id of an element that doesn't exist as you have created the element with id = 'taskdone'+i. So you must also append 'i' inside the myFunction() to get element ids.
But I will suggest you there is a clean way to this task is just pass the element inside myFunction on changing the element value.
Use something like that :
`input0.setAttribute('onchange', 'myFunction(this)');`
Then you would no longer require the element id to get its value.
And create your myFunction like this:
function myFunction(element) {
var id = element.id;
var taskDone = element.value;
var i = id.split('taskDone')[1];
var newForm = document.createElement('form');
for (var j = 0; j < taskDone; j++) {
var input1 = document.createElement('input');
input1.setAttribute('type', 'text');
input1.setAttribute('id', 'time' + i);
document.body.appendChild(input1);
newForm.appendChild(input1);
document.body.appendChild(newForm);
};
};
See the snippet for more details and help:
var btnSubmit = document.getElementById('startSubmit');
console.log(btnSubmit);
btnSubmit.addEventListener('click', function (e) {
e.preventDefault();
var myForm = document.createElement('form');
var period = document.getElementById('period').value;
for(var i = 0; i < period ; i++){
var input0 = document.createElement('input');
input0.setAttribute('type', 'text');
input0.setAttribute('placeholder', 'The count of tasks');
input0.setAttribute('style', 'margin: 10px');
input0.setAttribute('id', 'taskDone'+i);
input0.setAttribute('onchange', 'myFunction(this)');
document.body.appendChild(input0);
myForm.appendChild(input0);
document.body.appendChild(myForm);
};
console.log(myForm);
});
function myFunction(element){
var id = element.id;
var taskDone = element.value;
var i = id.split('taskDone')[1];
var newForm = document.createElement('form');
for(var j = 0; j < taskDone ; j++){
var input1 = document.createElement('input');
input1.setAttribute('type', 'text');
input1.setAttribute('id', 'time'+i);
document.body.appendChild(input1);
newForm.appendChild(input1);
document.body.appendChild(newForm);
};
};
<form method="get" action="#" id="startForm">
<input type="text" name="period" id="period" placeholder="The number of days"/>
<input type="submit" name="submit" value="submit" id="startSubmit"/>
</form>
You need to define the function myFunction() as myFunction = function(){..}
Secondly the id attribute needs to be unique. Hence use
input0.setAttribute('id', 'taskDone'+i); to set the id and
input0.setAttribute('onchange', 'myFunction("'+i+'")');
to call the function.
Similarly access the id as
var taskDone = document.getElementById('taskDone'+i).value;
Try the fiddle - https://jsfiddle.net/djbb79d8/
Related
I am trying to build a basic mad lib style code using Regex and I am unable to create new input elements and have them behave like the initial one.
I've tried swapping out (doc.replace(regex[i]... for (doc.replace(inputArray[i]... - this works partially, but in the end I am stuck with brackets around the input value.
<!-- HTML
<div id = "doc" contentEditable="true">{input1} {input2}</div>
<div id = "inputs">
<input type = "text" id = "input1"> {input1}
</div>
<br>
<button onclick="generate()">Generate</button>
<button onclick="addInput()">Add Input</button>
</div>
-->
//Global Variables
var inputNumber = 1;
var regex = [/{input1}/g];
var inputArray = ["input1"];
//Generate
function generate(){
for (var i = 0; i < inputArray.length; i++) {
var doc = document.getElementById("doc").innerHTML;
var outputArray = document.getElementById(inputArray[i]).value;
document.getElementById("doc").innerHTML = (doc.replace(regex[i], outputArray))
};
};
//Add Input
function addInput(){
inputNumber++;
var inputs = document.getElementById("inputs");
var newInput = document.createElement("div");
newInput.innerHTML = "<p><input type='text' id='input"+inputNumber+"'> {input"+inputNumber+"}</p>";
inputs.appendChild(newInput);
inputArray.push("input"+inputNumber);
regex.push("/{input"+inputNumber+"}/g")
};
I want {input2} to become the value of the input with the id of 'input2' when the function generate() is called. It just straight up doesn't work.
Here my code snippet for test.
//Global Variables
// RegEx save input
var regexInputs = /\{(input\d+)\}/g;
//Generate
function generate(){
var doc = document.getElementById("doc");
var inputs = doc.innerHTML.matchAll(regexInputs);
var input = inputs.next();
while(input.value){
doc.innerHTML = doc.innerHTML.replace(
input.value[0], document.getElementById(input.value[1]).value);
input = inputs.next();
};
}
function addInput(){
var inputs = document.getElementById("inputs");
var idxInput = inputs.children.length + 1;
var newInput = document.createElement("div");
newInput.innerHTML = "<p><input type='text' id='input"+ idxInput +"'> {input"+ idxInput +"}</p>";
inputs.appendChild(newInput);
}
<div id = "doc" contentEditable="true">{input1} {input2}</div>
<div id = "inputs">
<input type = "text" id = "input1"> {input1}
</div>
<br>
<button onclick="generate()">Generate</button>
<button onclick="addInput()">Add Input</button>
</div>
<script src="script.js" type="text/javascript"></script>
Notes:
The regexInputs is the pattern that match all inputs and store (input\d+), so using matchAll we go througth all matches.
Every match has two index 0 has "{input#}" and 1 has "input#". With this strings we just do replaces.
So what i am trying to do is to have
1.add function to add an input box
2.remove function to remove the last input box in the list
3.sort function to sort the list of input texts by alphabetic order
I think my add function is working, but i am running into problem when i am trying to remove the last input box or trying to sort it.
Any idea or suggestion would be very much appreciated. thanks
<form id="mainform" >
<button onclick="add()">add</button>
<button onclick="remove()">remove</button>
<button onclick="sort()">sort</button>
</form>
<script>
var i = 0;
var count =0;
function add() {
var x= document.createElement("INPUT");
x.setAttribute("type", "text");
x.setAttribute("placeholder", "Name");
i += 1;
count=count+1;
document.body.appendChild(x);
}
function remove(){
i -= 1;
count=count-1;
}
function sort(){
var x;
x=count;
var strings=[]
var t;
var i=0;
t=x;
while(t!=0){
strings.push(document.forms["mainform"].elements[i].value);
t=t-1;
i=i+1}
strings=strings.sort()
var j=0;
var msg='';
while(x!=0){
var msg=msg+strings[j]+'\n';
document.forms["mainform"].elements[j].value=strings[j];
j=j+1;
x=x-1;}
}
</script>
Looks like your add function adds the inputs directly to the body, while your sort function is looking for elements in the form['mainform'] element.
Your remove function is just decrementing your iterator without actually affecting the form at all.
That would do the job:
<form id="mainform" >
<input type="button" value="add" onclick="add()"></input>
<input type="button" value="remove" onclick="remove()"></input>
<input type="button" value="sort" onclick="sort()"></input>
</form>
<script>
function add() {
var x= document.createElement("INPUT");
x.setAttribute("type", "text");
x.setAttribute("placeholder", "Name");
x.setAttribute("class", "someInput");
document.body.appendChild(x);
}
function remove() {
var childs = document.body.getElementsByClassName("someInput");
if(childs.length > 0) {
document.body.removeChild(childs[childs.length - 1]);
}
}
function sort(){
var hash = {};
var childs = document.body.getElementsByClassName("someInput");
// Map each element to its value
for(var i = 0; i < childs.length; i++) {
var currentElement = childs[i];
hash[currentElement.value] = currentElement;
}
// Remove all added elements
for(var i = 0; i < childs.length; i++) {
var currentElement = childs[i];
document.body.removeChild(currentElement);
}
// Sort by map keys, and add all elements back sorted
Object.keys(hash).sort().forEach(function(v, i) {
document.body.appendChild(hash[v]);
});
}
</script>
Please note that I replaced the button elements with input elements in order to prevent the form from being submitted.
Also pay attention that I marked each inserted textbox with class named "someInput". That will make our life easier when we want to query and get all the inserted textboxes.
I am trying to write a web app that takes user input as numbers in 15 text or number inputs on a html form, it should then add these values together and display the total in a label elsewhere on the page.
I have 15 inputs with the class name "takings" and a label with the ID "TotalLabel" on the page.
function getsum () {
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i = 0; i < rows.length; i++) {
var val = parseFloat(rows[i].value);
total += val;
}
var label = document.getElementById("TotalLabel");
label.value = total;
alert(parseFloat(total));
}
window.onload = getsum;
The alert is only in place for debugging purposes and it appears that the variable total is still set to zero at the end of the script. I also need to make the getsum() function fire every time a user enters data in any of the fields with class "takings".
Can anyone help?
So you need to add change events to all of the elements and call getsum
function getsum () {
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i = 0; i < rows.length; i++) {
var val = parseFloat(rows[i].value);
total += val;
}
var label = document.getElementById("TotalLabel");
label.value = total;
}
window.onload = getsum;
//Example showing how to add one event listener to the page and listen for change events
//The following works in modern browsers, not all browsers support addEventListener, target, and classList.
document.body.addEventListener("change", function(evt) {
var targ = evt.target;
if(targ.classList.contains("takings")) {
getsum();
}
});
label { display: block; }
<label>1</label><input type="text" class="takings" value="0"/>
<label>2</label><input type="text" class="takings" value="0"/>
<label>3</label><input type="text" class="takings" value="0"/>
<label>4</label><input type="text" class="takings" value="0"/>
<label>5</label><input type="text" class="takings" value="0"/>
<label>Total:</label><input type="text" id="TotalLabel" value="0" readonly/>
To have your getSum() function fire for all of those elements, you can use Javascript to add an onchange event to all elements with the required class name
var input = document.getElementsByClassName("takings");
for (var i = 0; i < cells.length; i++) {
input[i].onchange = getSum;
}
Other than that, I don't see any visible errors in your getSum() function.
You need to add an EventListener to your input fields and call getsum, for example
var a = document.getElementsByClassName("takings");
for (var i = 0;i<a.length;i++){
addEventListener('keyup',getsum);
}
Please note that a label has innerHTML, not a value:
label.innerHTML = total;
With your actual function, you will get NaN as a result as long as not all the inputs have a value, so you will need to add
if (val) {
total += val;
}
to your for loop.
Full working code:
function getsum(){
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i =0; i < rows.length; i++){
var val = parseFloat(rows[i].value);
if (val) {
console.log(val);
total += val;
}}
var label = document.getElementById("TotalLabel");
label.innerHTML = total;
}
var a = document.getElementsByClassName("takings");
for (var i = 0;i<a.length;i++){
this.addEventListener('keyup',getsum);
}
DEMO
I have created a simple application in javascript. The application is that a value is selected from a dropdown list and if the button next to it is clicked then the specified number of texboxes selected in the dropdown are added to the DOM with a a to their right sides.
Here's the HTML:
<form>
<select style="width: 250px;" id="numMembers" <!--onchange="addMembers();" -->>
<option value="0">Add More Members...</option>
<script>
for (var i = 1; i <= 10; i++) {
document.write('<option value=' + i + '>' + i + '</option>');
};
</script>
</select>
<button onclick="addMembers();" type="button">Add</button>
<div style="margin-top: 10px; border: 1px solid #eee; padding: 10px;">
<input type="text" />
<br/>
<input type="text" />
<br/>
<input type="text" />
<br/>
</div>
<div id="extras"></div>
</form>
And here's the script:
function addMembers() {
var num = document.getElementById("numMembers").options["selectedIndex"];
for (var i = 0; i < num; i++) {
var lineBreak = document.createElement("br")
var txtInput = document.createElement("input");
txtInput.type = "text";
txtInput.style.display = "inline";
var removeHref = document.createElement("a");
removeHref.href = "#";
removeHref.innerHTML = "Remove(x)";
removeHref.style.marginLeft = "5px";
removeHref.style.display = "inline";
removeHref.onclick = function () {
document.removeChild(this);
};
document.getElementById("extras").appendChild(lineBreak);
document.getElementById("extras").appendChild(txtInput);
document.getElementById("extras").appendChild(removeHref);
}
}
How can I remove the textbox on the left of the anchor tag which is when clicked. For example:
[XXXXXXX] Remove(x)
[XXXXXXX] Remove(x)
If the last "Remove(x)" is clicked then the last textbox should be removed hence the one to the left of it.
How can I do it?
Note: No JQuery solutions please! I could do that even myself :P.
You can pass the id on anchorTag and can pass same id with some addition for input text, like
If you pass the id input1 for a then use the id input1Text for relative text box,
So you when you click on particular link, you will get a with input1 and get relative input text with 'input1Text'.
This would be apply for input2, input3, ... Something like this.
DEMO
function addMembers() {
var num = document.getElementById("numMembers").options["selectedIndex"];
for (var i = 0; i < num; i++) {
var lineBreak = document.createElement("br")
var txtInput = document.createElement("input");
txtInput.type = "text";
txtInput.id = "input"+i+"Text"; //give the id with Text
txtInput.style.display = "inline";
var removeHref = document.createElement("a");
removeHref.href = "#";
removeHref.innerHTML = "Remove(x)";
removeHref.style.marginLeft = "5px";
removeHref.style.display = "inline";
//when you click on this link you will get relative textbox by "input"+i+"Text";
removeHref.id = "input"+i;
removeHref.onclick = function () {
var removeNodeText = document.getElementById(this.id+"Text");
removeNodeText.parentNode.removeChild(removeNodeText);
var removeNodeLink = document.getElementById(this.id);
removeNodeLink.parentNode.removeChild(removeNodeLink);
};
document.getElementById("extras").appendChild(lineBreak);
document.getElementById("extras").appendChild(txtInput);
document.getElementById("extras").appendChild(removeHref);
}
}
Try This
function addMembers() {
var num = document.getElementById("numMembers").options["selectedIndex"];
for (var i = 0; i < num; i++) {
var lineBreak = document.createElement("br")
var txtInput = document.createElement("input");
txtInput.id = "text_"+i;
txtInput.type = "text";
txtInput.style.display = "inline";
var removeHref = document.createElement("a");
removeHref.href = "#";
removeHref.id = "href_"+i;
removeHref.innerHTML = "Remove(x)";
removeHref.style.marginLeft = "5px";
removeHref.style.display = "inline";
removeHref.onclick = function(){
var id= this.id.split('_')[1];
console.log(id)
document.getElementById("extras").removeChild(document.getElementById('text_'+id));
document.getElementById("extras").removeChild(this);
}
document.getElementById("extras").appendChild(lineBreak);
document.getElementById("extras").appendChild(txtInput);
document.getElementById("extras").appendChild(removeHref);
}
}
Below code adds text-content to the list dynamically,
window.onload = function()
{
//alert("Window is loaded");
var numberList = document.getElementById("numberList");
//for every number between 100 and 200
for(var i = 0; i > 100 && i < 200; i++)
{
if ( i % 17 == 0 && i % 2 == 0) //if number evenly divisible by 17 and 2
{
//create new li element
var newNumberListItem = document.createElement("li");
//create new text node
var numberListValue = document.createTextNode(i);
//add text node to li element
newNumberListItem.appendChild(numberListValue);
//add new list element built in previous steps to unordered list
//called numberList
numberList.appendChild(newNumberListItem);
}
}
}
Now, instead of adding the text content like "i" to list, I want to add a form with one textfield and one submit-button.
Thanks in advance.
Just an example, you can change as per your requirement
Inside script tag
var f = document.createElement("form");
f.setAttribute('method',"post");
f.setAttribute('action',"submit.php");
var i = document.createElement("input");
i.setAttribute('type',"text");
i.setAttribute('name',"username");
var s = document.createElement("input");
s.setAttribute('type',"submit");
s.setAttribute('value',"Submit");
f.appendChild(i);
f.appendChild(s);
document.getElementsByTagName('body')[0].appendChild(f);
try something like this in javascript ...
/*Form creation*/
var form = document.createElement("form");
var input = document.createElement("input");
form.action = "FileNameHere";
form.method = "post";
input.name = "name";
input.value = "testname";
form.appendChild(input);
form.submit();