Javascript added form elements not being added to array - javascript

I have a simple Javascript that adds text boxes to a form. It appears to work (i.e. a new box is added to the form) but when I submit the new form elements are not added to the array. So only the info in the first text box is submitted. Here is the code.
HTML
<div id="dynamicInput">
Part SKU 1: <input type="text" name="myInputs[]">
</div>
<input type="button" value="Add Another Part" onClick="addInput('dynamicInput');">
JS
var counter = 1;
var limit = 5;
function addInput(divName){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "Part " + (counter + 1) + " <br><input id='input"+(counter + 1)+"' type='text' name='myInputs[]'>";
document.getElementById(divName).appendChild(newdiv);
counter++;
}
}
Any help would be appreciated.

Your input name must be unique otherwise it will grab the first one and leave out the rest similar to how JS treats ID's

Related

Clicking the add button should add two textboxes and cancel button should remove the textboxes

Clicking the "Add" button should add two text boxes and "Cancel" button should remove those added text boxes.
I have tried adding and removing dynamic textboxes, but that didn't work for me.
I clicked the "Add" button and there is no response
var counter = 0;
$("#addtextbox").click(function() {
if (counter > 10) {
alert("Only 10 learning Tools allowed per page.");
return false;
}
var newTextBoxDiv = $(document.createElement('div')).attr("id", 'Tools' + counter);
newTextBoxDiv.after().html(
"<label></label>" +
"<textarea id='tbTools'" + counter + "' name='txtTools' rows='3' cols='50'></textarea>" +
' <input type="button" value="Remove" class="removeTools" onclick="removeTextArea(this);">');
newTextBoxDiv.appendTo("#ToolsGroup");
counter++;
});
function removeTextArea(textAreaElement) {
$(textAreaElement).parent().remove();
counter--;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="btn btn-info" type="button" id="addtextbox" value="Add">
</div>
When I click the add button it should add two text boxes in a row and when I click the cancel button it should remove those two boxes.
I don't have any clear idea of doing this. So someone can help me
So now it is a bit responsive - in case there is space, it they will be next to other, if not, they will stay one under another, also DIV is used now as parent element, so all is removed with that DIV, TAs are named ...A/B now. Btw you can accept answer under voting buttons or vote up if you like it ;-)
var counter = 0;
function addtextbox() {
if (counter > 10) {
alert("Only 10 learning Tools allowed per page.");
return false;
}
var newTextBoxDiv = document.createElement('div');
newTextBoxDiv.id = 'Tools' + counter;
document.getElementById("ToolsGroup").appendChild(newTextBoxDiv);
newTextBoxDiv.innerHTML = "<label></label>" +
"<textarea id='tbTools" + counter + "A' name='txtTools' rows='3' cols='50'></textarea>" +
"<textarea id='tbTools" + counter + "B' name='txtTools' rows='3' cols='50'></textarea>" +
' <input type="button" value="Remove" class="removeTools" onclick="removeTextArea(this);">'
counter++;
};
function removeTextArea(inputElement) {
var el = inputElement;
while (el.tagName != 'DIV') el = el.parentElement;
el.parentElement.removeChild(el);
counter--;
}
textarea {
display:inline
}
<div>
<input class="btn btn-info" onclick="addtextbox()" type="button" value="Add">
</div>
<div id="ToolsGroup">
</div>

Trying To Move Input Element to Another Div

I am creating a form that shows one question at a time. I would like to show all questions, though, on a different view when "View Complete Form" is clicked. The problem I am having is showing the questions in said form. There's no issue with the single view questions.
I am able to display the value, on said form but I cannot actually enter anything. That's not what I want.
Ex. in case any one is confused:
(In single view)
Question 1: (input box) Answer 1
(In full view)
Question 1: Answer 1 (All text, no input boxes)
I would like to do:
(In single view)
Question 1: (input box) Answer 1
(In full view)
Question 1: (input box) Answer 1
Like I said, I see how I can get the value (I used answer[i-1] = document.getElementById(i-1).value) then I print the answer BUT WITHOUT THE INPUT BOX.
I realized my mistake so I tried document.getElementById(x) which gives me [object HTMLInputElement]. Again, I just want the input box with the answer already filled in IF it's filled on the single view.
Did some searching on here and tried to use appendTo, descendants and appendChild (object does not support these) but nothing helped.
html
<div id="questionnaire-question">Click 'Start' to begin...</div>
<div id="input-questionnaire">
<input type='text' class='form-control' name='reqEng' id='1' style="display:none" placeholder="Requesting Engineer" required>
</div>
<button id="view-form" onclick="viewForm()">View Complete Form</button>
<form id="full-form" style="display:none">
<div id="full-form-question"></div>
<input type="reset" name="reset" value="Reset Fields">
<input type="submit" name="submit" id="submitQuestionnaire" value="Submit Questionnaire">
</form>
</div>
js
function viewForm() {
for (var x = 0; x < 44; x++) {
//form.appendChild(document.getElementById(x)); // Didn't work
//form.insert(document.getElementById(x).descendants()[x]); // Not supported
//document.getElementById(x).style.display = "block"; // Loop for questions and answers to populate
//document.getElementById(x+1).appendTo(form);
//fullForm.innerHTML += questions[x]+ ": " + answer[x+1] + " <br>";
fullForm.innerHTML += questions[x] + ": " + document.getElementById(x + 1) + " <br>";
}
}
This is what I want (from a previous form. I populated the inputs in an array but found it easier with some functionalities if I had just hard coded it)
https://imgur.com/cgarzSd
This is what I currently have :
https://imgur.com/Uj4FlvZ
Your question could possibly use some clarification, however I am taking a stab at it hoping that we can get you on the right track.
Below is an example of simply moving the input from one div to another:
function viewForm(){
//gets all of the inputs held in the "input-questionnaire" div
var inputs = document.getElementById('input-questionnaire').getElementsByTagName('input');
//loop through the collection of inputs
for(var i = 0;i < inputs.length; i++)
{
//if you want to ensure input is no longer hidden when moved
//inputs[i].style.display = "block";
//move the element to the new div
document.getElementById("full-form-question").appendChild(inputs[i]);
}
//probably want to show the hidden form at this point
document.getElementById("full-form").style.display = "block";
}
Here is another option if you actually want to "copy" the input to the new div:
function viewForm(){
//gets all of the inputs held in the "input-questionnaire" div
var inputs = document.getElementById('input-questionnaire').getElementsByTagName('input');
//loop through the collection of inputs
for(var i = 0;i < inputs.length; i++)
{
//clone the current input
var clone = inputs[i].cloneNode();
//make sure the question is visible?
clone.style.display = "block";
//append the clone to your "full-form-question" div
document.getElementById("full-form-question").appendChild(clone);
}
//probably want to show the hidden form at this point
document.getElementById("full-form").style.display = "block";
}
Hope this helps. Cheers!
Here's a basic example of how you can "move" input elements from one form to another. In reality you're making a copy of it and removing the old one from the previous form.
It looks like the main problem you're having is that you're not defining the form.
Take a look at how you could go about it:
function viewForm() {
const form1 = document.getElementById('form-1')
const form2 = document.getElementById('form-2')
for (var x = 1; x <= 1; x++) {
let input = document.getElementById(x)
form1.remove(input)
form2.append(input);
const span = document.createElement('span');
span.innerText = `${x} is now in form2`
form2.appendChild(span)
}
}
document.getElementById("btnMove").addEventListener('click', viewForm);
<div>
Form 1
<form id="form-1">
<input type='text' class='form-control' name='reqEng' id='1' placeholder="Requesting Engineer" required>
</form>
</div>
<div>
Form 2
<form id="form-2">
</form>
</div>
<input type="button" id="btnMove" value="move input">

validate form for dynamically created inputs count

I am dynamically creating the inputs in the form
I want user to enter at least 'n' elements.
<html lang="en-US">
<head>
<meta name="referrer" content="origin">
<script>
var counter = 0;
var limit = 50;
function addInput(divName, arrName){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var newdiv = document.createElement('div');
var af = "autofocus"
newdiv.innerHTML = "<input id='my-div-"+counter+"' type='text' name='" + arrName + "[]' required autofocus=" + af + ">";
document.getElementById(divName).appendChild(newdiv);
document.getElementById('my-div-'+counter).focus();
counter++;
}
}
function validateForm(){
var frm = document.forms['simples'];
a = parseInt(frm.elements['myInputs_1[]'].length)
var sum = parseInt(frm.elements['myInputs_1[]'].length)
if(parseInt(sum) < 4){
alert("You must write at least 4 sentences ");
return false;
}
}
</script>
</head>
<body>
<form name="simples" action="part.php" align="center" onsubmit="return validateForm()" method="POST">
<div id = "dynamicInputHolder_1">
<b>Emotion </b><input type="text" value="" name="emotion" id="emotion" class="generatedEmotion" readonly>
<input type="hidden" value="" name="uniqueID" id="uniqueID">
<div id="dynamicInput_1">
<textarea rows="5" cols="50" readonly class="floating-box">
John arrived at Sally's house to pick her up. John and Sally were going to a fancy restaurant that evening for a dinner. John was little nervous because he was going to ask Sally to marry him.</textarea>
</div>
<input type="button" value="Add connecting sentences" onClick="addInput('dynamicInput_1', 'myInputs_1');">
</div>
<br>
<input type="submit" value="show me what is next">
</form>
</body>
</html>
The method validateForm() works only if number text boxes are greater than equal to 2, for 0 and 1 it does not work.
Please not that this is minimal example, in real website, I have many such divs collecting input in multiple arrays, so I am summing them over something like:
var sum = parseInt(frm.elements['myInputs_1[]'].length) + parseInt(frm.elements['myInputs_2[]'].length) + parseInt(frm.elements['myInputs_3[]'].length)
but it may happen that few of the arrays are empty.
How do I check that collectively there are atleast n inputs?
frm.elements['myInputs_1[]'] has a different behavior for each of the cases.
for no elements entered, it will be undefined
for 1 element, it only contains that element, so it does not have a length
for two elements onwards it is an object of type RadioNodeList, which is inherited from NodeList and has a length attribute.
so the validate form method changes to:
function validateForm(){
var frm = document.forms['simples'];
ele = frm.elements['myInputs_1[]'];
if(typeof ele === 'undefined'){
alert('no element at all..');
return false;
}
else if(ele.value == ""){
if (ele.length < 4){
alert("You must write at least 4 sentences ");
return false;
}
}
else{
alert('contains one element');
return false;
}
return true;
}
and it works!

How to count dynamically added inputs?

I have a simple form with two text boxes: One for peoples "name" and the other for their "surname". On the page you can click and it will add two more text boxes below, also for "name" and "surname".. so basically you could add as many pairs of name and surname as you want.
How do I count how many pairs/rows (of "names" and "surnames") of inputs?
You can see the demo here: http://poostudios.com/jstest2.html
Here's the code:
<html>
<head>
<script type="text/javascript" src="nutrition/jquery-3.1.1.js"></script>
<style type="text/css">
div{
padding:8px;
}
</style>enter code here
</head>
<body>
<form action="results.php" method="get">
<script type="text/javascript">
$(document).ready(function(){
var counter = 2;
$("#addButton").click(function () {
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<label>Name : </label>' +
'<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" ><label> Surname : </label>' +
'<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" >');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("#removeButton").click(function () {
counter--;
$("#TextBoxDiv" + counter).remove();
});
});
</script>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Name : </label><input type='textbox' id='textbox1' >
<label>Surname : </label> <input type='textbox' id='textbox2' >
</div>
</div>
<input type='button' value='Add' id='addButton'>
<input type='button' value='Remove' id='removeButton'>
<input type="submit" value="Go">
</form>
</body>
</html>
There are dozens of ways to do this. #Tibrogargan and I have littered the comments on your question with various snippets which will return the number of elements at any given time.
However, each time you want to check the count, you'd need to call those methods in full to get a 'live' count — so if you're just planning to check the number of inputs once, i.e. when the form is submitted, for example, all you need do is, in your submit handler, check the count or store the count in a variable:
$('form').on('submit',function(e){
e.preventDefault();
// store the current count in a variable (this will not change if the user adds another input)
var current_count = $('#TextBoxesGroup input').length / 2;
// do what you want with the current_count variable
console.log("The user has submitted the form with " + current_count + " input fields");
});
However, perhaps you're not only planning to count the number of input fields once. Perhaps you're monitoring the user's behaviour. In such a case, you could define a function to make things a bit less verbose.
Instead of using a counter which you increment/decrement, just define a counter function in the following way:
function counter(){
return $('#TextBoxesGroup input').length / 2;
/*
This could also be:
return document.getElementById('TextBoxesGroup').getElementsByTagName('input').length / 2;
*/
}
Now, whenever you need to check how many input pairs there are, just call counter() and the value will be returned. So, let's imagine you're checking the number of inputs when the user clicks something — your code might look like this:
$('body').on('click', 'input[type=button]', function(){
// conditionally pass the current count straight to a function which uses the data
if ( counter() > 0 ) processMyData( counter() );
// or, if you process the data here, then pass it on to another function
// store the current count
var current_count = counter();
// do nothing if there are no input fields
if ( current_count < 1 ) return;
// do what you want with the count now that you have it
myAnalytics.inputs.save( current_count );
// do something else with it
processMyData( current_count );
// etc.
});
Since you are using jquery already, this is how you are going to get the length. Divide by 2 since each you have a set of name and username.
<script>
var len = $('#TextBoxesGroup').find('input').length / 2;
// Do whatever you wanted to do with the len
</script>
Here is the plunker sample
Firstly in your code, the ids are not unique so I modified it a bit just see the demo below ( I used the append() function for your markup creation ).
Secondly since you used a counter variable just use it to count the number of pairs by dividing it with 2 (counter / 2).
var counter = 2;
$("#addButton").click(function() {
$('<div>', {
id : 'TextBoxDiv' + counter
}).append(
$('<label>', {
text: 'Name : '
}),
$('<input>', {
type: 'text',
name: 'textbox' + (++counter), // increment counter for name
id: 'textbox' + counter,
value: ''
}),
$('<label>', {
text: 'Surname : '
}),
$('<input>', {
type: 'text',
name: 'textbox' + (++counter), // increment counter for surname
id: 'textbox' + counter,
value: ''
})
).appendTo('#TextBoxesGroup');
// just divide the counter by 2 to get the pairs
console.log('input text pairs: ' + counter/2);
});
$("#removeButton").click(function() {
// if counter === 2 (initial) then remove nothing
if (counter === 2) {
return false;
}
// decrement counter by 2
// and remove the textbox container
counter-=2;
$("#TextBoxDiv" + counter).remove();
console.log('input text pairs: ' + counter/2);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="results.php" method="get">
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Name : </label>
<input type='textbox' id='textbox1'>
<label>Surname : </label>
<input type='textbox' id='textbox2'>
</div>
</div>
<input type='button' value='Add' id='addButton'>
<input type='button' value='Remove' id='removeButton'>
<input type="submit" value="Go">
</form>
$("#textbox1").length will give you the count of occurrences of name text field.

Deleting any element, the reassigning the count value

Sorry about the cryptic title, it's hard to describe!
I am using the following script to add a row to my form when a button is clicked:
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length;
var newNum = new Number(num + 1);
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
newElem.children(':first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
$('#input' + num).after(newElem);
$('#btnDel').attr('disabled','');
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length;
$('#input' + num).remove();
$('#btnAdd').attr('disabled','');
if (num-1 == 1)
$('#btnDel').attr('disabled','disabled');
});
$('#btnDel').attr('disabled','disabled');
});
This works absolutely fine, but it's not very user-friendly that you can only delete the last added row. Say I want to delete a row added earlier on, I would have to delete everything I'd done since then.
How can I delete any row, and at the same time reassign the count value to the other rows, so that the count is still sequential (i.e. Row1, Row2, Row3 etc, rather than Row1, Row5, Row8)?
I recommend that you don't explicitly set an id to the elements. Instead you can use jQuery powerful selectors to get the position of an element.
This is an example, based on a common html structure. Post your own html to give you a more details.
$('.btnDel').click(function() {
var num = $(this).parent().prevAll().size();
// this points to delete link.
// The previous element is the content element
$(this).prev().remove();
$('#btnAdd').attr('disabled','');
if (num-1 == 1)
$(this).attr('disabled','disabled');
});
<div class='elem'>
<span class='content'>....</span>
<a class='btnDel' href='#'>Delete</a>
</div>
Why are you even adding IDs to the rows? Remember that 83% of jQuery is "Query" - use the selectors to get to the elements you want.
I had to do a similar thing a while ago
Essentially I got the number of the deleted row ie. Row3 and then looped through the remaining rows updating their values. so Row4 becomes Row3 etc.
I used something like this
var last_val = //get the last value of the rows so you know when to stop
//knock off the Row part of the id and parses as an integer
var pos = parseFloat(row_id.slice(3))
var next_val = position+1;
var prev_val = position;
while(next_val<=last_val){
next_selector = "#Row"+next_val;
prev_id = "Row"+prev_val;
$(next_selector).attr("id",prev_id);
next_val++;
prev_val++;
}
There may be a better way to do this, but this worked for me for a cms allowing pages to be deleted from the middle of a list which then updated the row numbering.
I posted a demo here (it doesn't look good in IE because of the float, but I just wanted to post this as an example to help). I don't know how you handle gathering your form data, so I did include renumbering the cloned input IDs.
CSS
form { width: 400px; margin: 0 auto; line-height: 30px; }
input { float: right; }
HTML
<form>
<div class="main">
Name: <input type="text" /><br>
Title: <input type="text" /><br>
Company: <input type="text" /><br>
Location: <input type="text" /><br>
</div>
Additional information: <input id="btnAdd" type="button" value="Add More"/>
<div id="addFields"></div>
</form>
Script
$(document).ready(function(){
$('#btnAdd').click(function(){
// inputs reversed because of the float right
var newInput = '<div class="clonedInput">Additional Field <span></span>: ' +
'<input type="button" class="btnDel" title="Delete this field" value="X"><input type="text" /></div>';
$(newInput).appendTo('#addFields');
// disable add button if there are 5 additional fields
if ($('.clonedInput').length == 5) {
$('#btnAdd').attr('disabled','disabled');
}
renumber();
})
// Delete input field
$('.btnDel').live('click',function(){
$('#btnAdd').attr('disabled','');
$(this).parent().remove();
renumber();
})
})
// This function adds the additional field number and ID for each clonedInput field
function renumber(){
$('.clonedInput').each(function(i){
$(this).find('span').html('#' + (i+1));
// the code below will change the ID of the input, in case you collect your data based on the ID.
$(this).find('input[type=text]').attr('id', 'input' + (i+1));
})
}

Categories

Resources