Creating elements on DOM dynamically but form not sending anything - javascript

I have a form which has some of its fields dynamically added based on another field, I was able to make it create the elements, but when I send the form, none of those are sent with the non dynamically fields that are loaded on page load.
Here's how I'm adding
function foo(field) {
var selectionDiv = document.getElementById("div_" + field);
var divLength = selectionDiv.children.length;
for (var i = 0; i < divLength; i++) {
if (selectionDiv.children[i].id.indexOf(field) != -1) {
var element = document.createElement(selectionDiv.children[i].tagName);
element.setAttribute("type", selectionDiv.children[i].type);
element.setAttribute("value", selectionDiv.children[i].value);
element.setAttribute("id", selectionDiv.children[i].id);
if (selectionDiv.children[i].className != "") {
element.setAttribute("class", selectionDiv.children[i].className);
}
$(element).appendTo("#div_" + field);
}
}
}
The HTML after insertion:
<form action="/URL" id="form" method="post" name="form" onsubmit="Confirmation('Are you sure?');return false;"><div class="form-horizontal">
<...OtherFields...>
<div class="form-group" id="form_group_test">
<label class="col-xs-2 control-label" for="Identity">test:</label>
<div class="col-xs-4" id="div_test">
<input id="Fields_test__Identity" name="Fields[test].Identity" type="hidden" value="test">
<input class="form-control hasTooltip" data-placement="right" data-toggle="tooltip" id="Fields_test__Value" name="Fields[test].Value" title="" type="text" value="*">
<br>
<button type="button" onclick="foo('test'); return false;" class="btn btn-default hasTooltip form-control" data_toggle="tooltip" data_placement="right" title=""><span class="glyphicon glyphicon-plus blue"></span></button>
<input type="hidden" value="test" id="Fields_test1__Identity"><input type="text" value="*" id="Fields_test1__Value" class="form-control hasTooltip"></div>
<...MoreFields...>
</form>
Any thoughts?

When you are creating dynamically the element, the attribute "name" is missing, try the following code:
function foo(field) {
var selectionDiv = document.getElementById("div_" + field);
var divLength = selectionDiv.children.length;
for (var i = 0; i < divLength; i++) {
if (selectionDiv.children[i].id.indexOf(field) != -1) {
var element = document.createElement(selectionDiv.children[i].tagName);
element.setAttribute("type", selectionDiv.children[i].type);
element.setAttribute("value", selectionDiv.children[i].value);
element.setAttribute("id", selectionDiv.children[i].id);
element.setAttribute("name", selectionDiv.children[i].id);
if (selectionDiv.children[i].className != "") {
element.setAttribute("class", selectionDiv.children[i].className);
}
$(element).appendTo("#div_" + field);
}
}
}

Related

Fields Added Via Javascript not posting Data into $POST

I have created a form which can be dynamically changed using the buttons included. These buttons allow for more input fields to be added/removed. The issue is that the input fields created are not posting any data/ Values in those fields not being added to the $POST array on the submit of the form.
The main functions below resposible for adding and removing rows is RemoveRows() and addRows()
What should happen is that on submit all values in the form should be "posted" then I can access all of those fields via $_POST["nameOfField"].
The way I have currently approached this is to create an input fields with the relevant id's and names then append that field to where the "hard coded" fields exists.
From my initial debugging none of the fields that have been added via javascript are in $Post which I have checked via var_dump($_REQUEST);
I have also seen that the nodes that are added are not elements of the form tag even though the nodes are added between the opening and closing tag. This can be seen in the doBeforeSubmit() Function where we can see all elements that are children of the and this never changes as rows are added/removed.
function showPlatforms() {
let nacellesOptions = ["Option1", "option2", "Option3"];
let milOptions = ["Option1", "option2", "Option3"]
let highOptions = ["Option1", "option2", "Option3"]
let entry = document.getElementById("vs")
let platfom = document.getElementById("platform")
if (platform.hasChildNodes()) {
var lastChild = platfom.lastElementChild
while (lastChild) {
platfom.removeChild(lastChild)
lastChild = platform.lastElementChild
}
}
if (entry.value == "Nacelles") {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = nacellesOptions[i]
option.innerHTML = nacellesOptions[i]
platform.appendChild(option)
}
} else if (entry.value == "Military") {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = milOptions[i]
option.innerHTML = milOptions[i]
platform.appendChild(option)
}
} else {
for (var i = 0; i < 2; i++) {
var option = document.createElement("option");
option.value = highOptions[i]
option.innerHTML = highOptions[i]
platform.appendChild(option)
}
}
}
function formOptions() {
let entry = document.getElementById("type")
if (entry.value == "Engineering MAM") {
document.getElementById("WBS").disabled = false
document.getElementById("Desc").disabled = false
document.getElementById("ProName").disabled = false
} else {
document.getElementById("WBS").disabled = true
document.getElementById("Desc").disabled = true
document.getElementById("ProName").disabled = true
}
}
function formoptions2() {
let entry2 = document.getElementById("organisation")
if (entry2.value == "Aftermarket") {
document.getElementById("COT").disabled = false
document.getElementById("COC").disabled = false
} else {
document.getElementById("COT").disabled = true
document.getElementById("COC").disabled = true
}
}
count = document.getElementById("partNum").childElementCount
function addRows() {
rowNames = ["partNum", "partDesc", "leadTime", "quantity", "dateReq", "unitCost", "unitExtention", "unitSaleValue", "estSalesValue"]
rowNames.forEach(addRow, count)
count = document.getElementById("partNum").childElementCount
//doBeforeSubmit()
}
function doBeforeSubmit() {
var es = document.getElementById("form").elements;
var l = es.length;
var msgs = [];
for (var idx = 0; idx < l; idx++) {
var e = es[idx];
msgs.push('name=' + e.name + ', type=' + e.type + ', value=' + e.value);
}
alert(msgs.join('\n'));
return false;
}
function addRow(id) {
let col = document.getElementById(id)
var box = document.createElement("INPUT")
box.setAttribute("type", "text")
box.setAttribute("id", id + count)
box.setAttribute("name", id + count)
box.setAttribute("class", "form-control")
col.appendChild(box)
}
function RemoveRows() {
rowNames = ["partNum", "partDesc", "leadTime", "quantity", "dateReq", "unitCost", "unitExtention", "unitSaleValue", "estSalesValue"]
rowNames.forEach(removeBoxes)
count = document.getElementById("partNum").childElementCount
}
function removeBoxes(item) {
let box = document.getElementById(item)
let last = box.lastChild
box.removeChild(last)
}
function checkData() {
// if all stuff is correct do this:
document.getElementById("submit").disabled = false
// else dont activate the submit button.
}
<form method="post" id="form" action="SubmitMAM.php">
<div class="row" id="productRow" style="width:95%; margin:auto">
<div id="partNo" class="col-2">
<h3>Part Number:</h3>
</div>
<div class="col-2">
<h3>Part Description:</h3>
</div>
<div class="col-1">
<h3>Lead Time:</h3>
</div>
<div class="col-1">
<h3>Quantity:</h3>
</div>
<div class="col-1">
<h3>Date Required:</h3>
</div>
<div class="col-1">
<h3>Unit Cost:</h3>
</div>
<div class="col-2">
<h3>Unit Cost Extension:</h3>
</div>
<div class="col-1">
<h3>Unit Sale Value:</h3>
</div>
<div class="col-1">
<h3>Est Sales Value:</h3>
</div>
</div>
<div class="row" id="productRow" style="width:95%; margin:auto">
<div id="partNum" class="col-2">
<input type="text" id="partNum0" class="form-control" name="partNum0">
</div>
<div id="partDesc" class="col-2">
<input type="text" id="partDesc0" class="form-control" name="partDesc0">
</div>
<div id="leadTime" class="col-1">
<input type="text" id="leadTime0" class="form-control" name="leadTime0">
</div>
<div id="quantity" class="col-1">
<input type="text" id="quanitity0" class="form-control" name="quantity0">
</div>
<div id="dateReq" class="col-1">
<input type="text" id="dateReq0" class="form-control" name="dateReq0">
</div>
<div id="unitCost" class="col-1">
<input type="text" id="unitCost0" class="form-control" name="unitCost0">
</div>
<div id="unitExtention" class="col-2">
<input type="text" id="unitExtention0" class="form-control" name="unitExtention0">
</div>
<div id="unitSaleValue" class="col-1">
<input type="text" id="unitSaleValue0" class="form-control" name="unitSaleValue0">
</div>
<div id="estSalesValue" class="col-1">
<input type="text" id="estSalesValue0" class="form-control" name="estSalesValue0">
</div>
<button onclick="addRows()" class="btn btn-primary" type="button">Add a Product</button>
<button onclick="RemoveRows()" class="btn btn-primary" type="button">Remove Row</button>
<button onclick="checkData()" class="btn btn-primary" type="button">Check Data</button>
<br>
<button type="submit" name="submit" id="submit" class="btn btn-primary" disabled>Submit</button>
</form>
PHP:
<?php
var_dump($_REQUEST)
?>
UPDATE:
The code has been changed to use a php array by adding square brackets into the name which produces the following html:
<input type="text" id="partNum0" class="form-control" name="partNum[]">
<input type="text" id="partNum1" name="partNum[]" class="form-control">
<input type="text" id="partNum2" name="partNum[]" class="form-control">
You just need to use the name property of the input and add [] at the end, as GrumpyCrouton said. PHP parse it as an array, and you can access it as:
$partNum = $_POST["partNum"];
FIXED: It turns out the above code did not have any issues with the logic or the way it should work, in the source code in visual studio the indentation of some of the Divs was off causing the browser to have issues in rendering the form correctly hence why the added boxes were not included in the form and their values not POSTED.
As a heads up to anyone with maybe a similar issue, it pays to have your code neat.

How should I put limit inside for loop using if condition using javascript

My goal is that only 15 quantities of input elements can be accepted, once the user enters 16 it should say that only 15 input elements is allowed. However I don't know how will I do this. I tried putting condition inside for but it is not not working. I am a little bit confused on this
Here is my HTML code
<div class="form-group">
<label> Quantity: </label>
<input class="form-control" name="quantity" type="number" id="get_Elem"
required>
<br>
<input type="button" id="sb_add_ctrl" name="is_Sub" class="btn btn-
primary" value="Add Control Number">
</div>
<div class="form-group" name="parent" id="parent"></div>
Here is my JS code
$(document).on('click', '#sb_add_ctrl', function() {
var element = $('#get_Elem').val();
var input;
var parent = $(document.getElementById("parent"));
var value = $('#sel_control_num').val();
functionPopulate(parent);
if (isNaN(element)) {
return;
}
for (var i = 0; i < element; i++) {
if(should I do it here??){
}
value = value.replace(/(\d+)$/, function(match, element) {
const nextValue = ++match;
return ('0' + nextValue).slice(1);
});
document.getElementById("parent").style.padding = "5px 0px 0px 0px";
document.getElementById("parent").innerHTML += '<br><input type="text"
value="' + value +
'" class="form-control" name="get_Input_show[]" required>'
}
});
You can check if the element value is < 16 if yes then only add html else show error message.
Demo Code :
$(document).on('click', '#sb_add_ctrl', function() {
var element = $('#get_Elem').val();
var input;
//var value = $('#sel_control_num').val();
var value = 12;
//functionPopulate(parent);
if (isNaN(element)) {
return;
}
//check if elemnt value if < 16
if (element < 16) {
$("#parent").empty() //empty div
for (var i = 0; i < element; i++) {
/* value = value.replace(/(\d+)$/, function(match, element) {
const nextValue = ++match;
return ('0' + nextValue).slice(1);
});*/
document.getElementById("parent").style.padding = "5px 0px 0px 0px";
document.getElementById("parent").innerHTML += '<br><input type="text" value = "' + value + '" class="form-control" name="get_Input_show[]" required>';
}
} else {
alert("only 15") //show error
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
<label> Quantity: </label>
<input class="form-control" name="quantity" type="number" id="get_Elem" required>
<br>
<input type="button" id="sb_add_ctrl" name="is_Sub" class="btn btn-
primary" value="Add Control Number">
</div>
<div class="form-group" name="parent" id="parent"></div>
There are two ways in which you can restrict it
You can use maxLength property of an input tag, which will restrict the user to input the 16th character.
You can keep checking the value in the input field and show error if the length is more than 15 character. To do this you can use onkeypress event on input, like
HTML
<input type="text" id="test" onkeypress="test()" />
JS:
<script>
function test() {
alert('Hi')
}
</script>

Can not create multiple text area after deleting using Javascript/Jquery

I need some help. I am creating multiple texareas using + button and deleting using - button but I am running into some issues.
This is my code:
<div class="col-md-3">
<div class="form-group">
<label for="ques">No of questions</label>
<input name="no_of_question" id="ques" class="form-control" placeholder="no of question" value="" type="text">
<div id="err_msg_name" style="font-size:12px; color:#FF0000; text-align: center;"></div>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Questions</label>
<input type="button" style="line-height:13px; margin-right:2px;" class="btn btn-success btn-sm" name="plus" id="plus" value="+" onClick="addQuestionField();">
<input type="button" style="line-height:13px; margin-right:2px;" class="btn btn-danger btn-sm" name="minus" id="minus" value="-" onClick="deleteQuestionField();">
</div>
</div>
</div>
<div id="container">
<div class="col-md-4">
<div class="form-group">
<textarea class="form-control" name="questions0" id="questions0" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea>
</div>
</div>
</div>
<script>
function addQuestionField() {
var get = $("#ques").val();
console.log('ques', get);
for (var i = 1; i < get; i++) {
$('#container').append('<div class="col-md-4 dyn"><div class="form-group"><textarea class="form-control" name="questions' + i + '" id="questions' + i + '" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea></div></div>')
}
}
function deleteQuestionField() {
var textareas = $('#container .dyn');
if (textareas.length !== 0) {
textareas.last().remove();
$('#ques').val(textareas.length - 1);
}
}
</script>
Basically what I need to do is to add new textareas with a unique id, and ordered by this id, to the page according to the number entered in the first textbox. One Default textarea should always be in the page.
So for example if I entered 3 in the textbox, 2 textareas should be added, if I enter 5- 4 textareas should be added etc.
But the above code is not working properly: For example I entered 2 in the first textbox and clicked on the + button- 1 textarea is being created and added to the page (what is good), the same thing in the second time, but on the third time it's not working anymore, an extra textbox is being created.
(For example: I entered the 3 digit, and 3 new textareas are being added + the default one = 4 ,but I only need 3- as entered in the textbox)
My full plunker code here.
As the OP claimed he also needs to keep the id and the name of the textareas serially.
Before adding the new textarea, we remove all the textareas that were added before.
function addQuestionField() {
var get = $("#ques").val();
var count=$('textarea').length -1 ;
for (var i = 0; i < count; i++) {
$('#container').find('.col-md-4').last().remove();
}
for (var i = 1; i < get; i++) {
$('#container').append('<div class="col-md-4 dyn"><div class="form-group"><textarea class="form-control" name="questions' + i + '" id="questions' + i + '" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea></div></div>')
}
}
I also noticed that it messed up the deleteQuestionField function, you should correct it as bellow:
function deleteQuestionField() {
var textareas = $('textarea');
if (textareas.length !== 0) {
textareas.last().remove();
$('#ques').val(textareas.length - 1);
}
}
A working plunker code here.
Make a small change, It will add same text area mention in the input field (including the existing one) .
function addQuestionField() {
var get = $("#ques").val();
var noOfTextArea = $('textarea').length;
if(get > noOfTextArea){
get = get - noOfTextArea;
for (var i = 1; i <= get; i++) {
$('#container').append('<div class="col-md-4 dyn"><div class="form-group"><textarea class="form-control" name="questions' + i + '" id="questions' + i + '" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea></div></div>')
}
}else{
get = noOfTextArea - get;
for (var i = 1; i <= get; i++) {
$('#container').find('.col-md-4').last().remove();
}
}
}
you are using for loop by starting index at 1 so you should use "<="
for (var i = 1; i <=get; i++) {
$('#container').append('<div class="col-md-4 dyn"><div class="form-group"><textarea class="form-control" name="questions' + i + '" id="questions' + i + '" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea></div></div>')
}
Your Code is perfect.The reason that that more boxes are getting created is because in your code there is already a form-area present,in addition to that one text area the number of text areas you have specified gets created.
So for example there is already one text area present on load of the screen,when you enter 5 into the text box for creation.5+1 text areas are seen on the screen.
If you remove the existing text area you will be able to see the exact number of text areas you specified on the screen.
Furthermore if your change the limit to <=limit then <=5 will be created else else less than 5 that is 4 will be created
Try with below code....
function addQuestionField() {
var get = $("#ques").val();
var textlen = $('textarea').length;
get = get - textlen;
//console.log('ques', get);
for (var i = 0; i < get; i++) {
$('#container').append('<div class=col-md-4 dyn><div class=form-group><textarea class=form-control name=questions"+i+" id=questions"+i+" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea></div></div>')
}
}
function deleteQuestionField() {
var textareas = $('textarea');
if (textareas.length !== 0) {
textareas.last().remove();
$('#ques').val(textareas.length - 1);
}
}
make some way to get new id always,
var idGernator = (function (){
var id = 10;
return function(){
return id++;
}
})();
function addQuestionField() {
var get = $("#ques").val();
// console.log('ques', get);
// var textareas = $('#container .dyn');
// console.log('text',textareas);
// var get = $("#ques").val() - 1;
for (var i = 1; i <= get; i++) {
var id = idGernator();
$('#container').append('<div class="col-md-4 dyn"><div class="form-group"><textarea class="form-control" name="questions' + id + '" id="questions' + id + '" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea></div></div>');
console.log("new id: "+ id);
}
}
function deleteQuestionField() {
var textareas = $('#container .dyn');
if (textareas.length !== 0) {
textareas.last().remove();
$('#ques').val(textareas.length - 1);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Hello</h1>
<div class="col-md-3">
<div class="form-group">
<label for="ques">No of questions</label>
<input name="no_of_question" id="ques" class="form-control" placeholder="no of question" value="" type="text">
<div id="err_msg_name" style="font-size:12px; color:#FF0000; text-align: center;"></div>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Questions</label>
<input type="button" style="line-height:13px; margin-right:2px;" class="btn btn-success btn-sm" name="plus" id="plus" value="+" onClick="addQuestionField();">
<input type="button" style="line-height:13px; margin-right:2px;" class="btn btn-danger btn-sm" name="minus" id="minus" value="-" onClick="deleteQuestionField();">
</div>
</div>
</div>
<div id="container">
<div class="col-md-4">
<div class="form-group">
<textarea class="form-control" name="questions0" id="questions0" placeholder="Questions" style="background:#FFFFFF;" rows="2"></textarea>
</div>
</div>
</div>

get required form elements via DOM in javascript

To do checking on required fields and a custom method of alerting users that required fields are missing, I'm trying to get an array of elements in a form, and have been hunting but not finding a good method.
Is there some variation of
document.getElementById(form).elements;
that would return all the required elements of an array, or a way to test if a given element is required... something akin to either
var my_elements = document.getElementById(form).required_elements;
or
var my_elements = document.getElementById(form).elements;
for (var this_element in my_elements){
if (this_element.attributes["required"] == "false"){
my_elements.splice(this_element, 1);
}
}
Try querySelectorAll with an attribute selector:
document.getElementById(form).querySelectorAll("[required]")
var requiredElements = document.getElementById("form").querySelectorAll("[required]"),
c = document.getElementById("check"),
o = document.getElementById("output");
c.addEventListener("click", function() {
var s = "";
for (var i = 0; i < requiredElements.length; i++) {
var e = requiredElements[i];
s += e.id + ": " + (e.value.length ? "Filled" : "Not Filled") + "<br>";
}
o.innerHTML = s;
});
[required] {
outline: 1px solid red;
}
<form id="form">
<input required type="text" id="text1" />
<input required type="text" id="text2" />
<input type="text" id="text3" />
<input type="text" id="text4" />
<input required type="text" id="text5" />
</form>
<br>
<button id="check">Check</button>
<br>
<div id="output">
Required inputs
</div>

jQuery Dynamic Add Form Field, Remove Form Field

Hello I am trying to add new form field and delete form field after getting inspired from this tutorial - http://bootsnipp.com/snipps/dynamic-form-fields
My Current Problem is to delete and reset the value of all in chronological order.
<input type="hidden" name="count" value="1" />
<div class="control-group" id="fields">
<label class="control-label" for="field1">Nice Multiple Form Fields</label>
<div class="controls" id="profs">
<div class="input-append">
<input autocomplete="off" class="span3" id="field1" name="prof1" type="text" placeholder="Type something (it has typeahead too)" data-provide="typeahead" data-items="8"
data-source='["Aardvark","Beatlejuice","Capricorn","Deathmaul","Epic"]'/><button id="b1" onClick="addFormField()" class="btn btn-info" type="button">+</button>
</div>
<br /><small>Press + to add another form field :)</small>
</div>
</div>
Javascript :-
var next = 1;
function addFormField(){
var addto = "#field" + next;
next = next + 1;
var newIn = '<br /><br /><input autocomplete="off" class="span3" id="field' + next + '" name="field' + next + '" type="text" data-provide="typeahead" data-items="8"><button id="b1" onClick="$(this).parent().remove();" class="btn btn-info" type="button">+</button>';
var newInput = $(newIn);
$(addto).after(newInput);
$("#field" + next).attr('data-source',$(addto).attr('data-source'));
$("#count").val(next);
}
Parent Element is getting removed, but next counter is not reset properly. in hidden and all new created form :-
Only Add Demo :- http://bootsnipp.com/snipps/dynamic-form-fields
Add an Delete Demo with Bug :- http://jsfiddle.net/6dCrT/2/
Can someone help me please.
Thanks
Try:
function addFormField(){
var addto = "#field" + next;
next = next + 1;
var newIn = '<br /><br /><input autocomplete="off" class="span3" id="field' + next + '" name="field' + next + '" type="text" data-provide="typeahead" data-items="8"><button id="b'+next+'" onClick="$(this).prev().remove();$(this).remove();" class="btn btn-info" type="button">-</button>';
var newInput = $(newIn);
console.log(addto);
$(addto).after(newInput);
if(next>1)
$("button#b"+next).after(newInput);
$("#field" + next).attr('data-source',$(addto).attr('data-source'));
$("#count").val(next);
}
DEMO FIDDLE
In my example, I was building a form that would allow users to add multiple input names if they had more than one dog.
var counter = 0
jQuery(function () {
$(".newDog").click(function(){
counter ++;
if (counter < 4) {
var elem = $("<input/>",{
type: "text",
name: `dogname${counter}`
});
} else {
alert("You can only add 4 Dog Names")
}
var removeLink = $("<span/>").html("X").click(function(){
$(elem).remove();
$(this).remove();
counter --;
});
$(".dogname-inputs").append(elem).append(removeLink);
});
})
Full credit as mentioned to https://stackoverflow.com/users/714969/kevin-bowersox

Categories