Javascript Wrong tr info creating dynamic tables - javascript

I have a form that a user can fill out.
What i want to be able to do is allow to user to add more feilds if needed.
All works wells expect for one small part i cannot seem to get around. I have spent the last couple days trying to figure it out and its driving me crazy.
Javascript Code
<script>
var ed = 1;
function new_education()
{
ed++;
var div1 = document.createElement('div');
div1.id = ed;
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled('+ ed +')" > Delete Education ' + ed + ' </a>';
document.getElementById('educationtr').innerHTML = '<th colspan="4" style="background-color:#b0c4de;">Education ' + ed + '</th>';
div1.innerHTML = document.getElementById('educationtpl').innerHTML + delLink;
document.getElementById('education').appendChild(div1);
}
function deled(eleId)
{
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('education');
parentEle.removeChild(ele);
ed--;
}
</script>
HTML Code
<legend>Education</legend>
<div id="education">
<table border=3>
<tr><th colspan="4" style="background-color:#b0c4de;">Education 1</th></tr>
<tr><td><label>School Name</label><input type="text" name="schoolname[]" maxlength="30" size="30"><br></td>
<td><label>Degree Type</label><input type="text" name="degreetye[]" maxlength="30" size="30"><br></td>
<td><label>Degree Field</label><input type="text" name="degreefield[]" maxlength="30" size="30"><br></td>
</tr></table>
</div>
<a class="btn btn-info" href="javascript:new_education()" > Add New Education </a>
<div id="educationtpl" style="display:none">
<table border=3>
<tr id="educationtr"></tr>
<tr><td><label>School Name</label><input type="text" name="schoolname[]" maxlength="30" size="30"><br></td>
<td><label>Degree Type</label><input type="text" name="degreetype[]" maxlength="30" size="30"><br></td>
<td><label>Degree Field</label><input type="text" name="degreefield[]" maxlength="30" size="30"><br></td>
</tr></table>
</div>
jsfiddle example not working however http://jsfiddle.net/811yohpn/
Working Example: http://thenerdservice.com/addtest.php
What I would like to happen is each new table added will get a new heading "Education 2", "Education 3" etc but that does not happen.
What happens is when the button is hit to add new table the tr data will appear correct.
If you hit it once more it will increment the tr data however the delete buttons stay
correct.
If you hit the button more times the top tr data will continue to increment however the reat of the added tr data stays "Education 2"
Thank you

What I suggest is to rewrite new_education function using jQuery (I have tried to save most part of original code, but it wasn't so easy) fixing this problem with multiple same IDs.
Updated fiddle.
function new_education() {
ed++;
var newDiv = $('#education div:first').clone();
newDiv.attr('id', ed);
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled(' + ed + ')" > Delete Education ' + ed + ' </a>';
newDiv.find('tr:first th').text('Education ' + ed);
newDiv.append(delLink);
$('#education').append(newDiv);
}
Note: I also changed HTML, removing unnecessary extra table and wrapping first one with <div id="1"></div>:
<legend>Education</legend>
<div id="education">
<div id="1">
<table border=3>
<tr>
<th colspan="4" style="background-color:#b0c4de;">Education 1</th>
</tr>
<tr>
<td>
<label>School Name</label>
<input type="text" name="schoolname[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Type</label>
<input type="text" name="degreetye[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Field</label>
<input type="text" name="degreefield[]" maxlength="30" size="30"/>
</td>
</tr>
</table>
</div>
</div>
<br/>
<a class="js-addNew btn btn-info" href="javascript:new_education()"> Add New Education </a>

Related

How to get the average of all the dynamic inputs

I can't find the average of all the inputs. My code only reads the input that i stated in html, but doesn't read the other dynamic ones.
Heres my code:
$(document).ready(function(){
// adds a new row
$(".addCF").click(function(){
$("#customFields").append('<tr valign="top"><th scope="row"><label for="customFieldName">Custom Field</label></th><td><input type="text" class="code" id="customFieldName" name="customFieldName[]" value="" placeholder="Input Name" /> Add Remove</td></tr>');
});
// deletes the row
$("#customFields").on('click','.remCF',function(){
$(this).parent().parent().remove();
});
$("#customFields").on('click','.add',function(){
$("#customFields").append('<tr valign="top"><th scope="row"><label for="customFieldName">Custom Field</label></th><td><input type="text" class="code" id="customFieldName" name="customFieldName[]" value="" placeholder="Input Name" /> Add Remove</td></tr>');
});
$("#click").click(function(){
var isbn = document.getElementById('customFieldName').value;
alert(isbn / $("input").length)
$("#averageGrade").text("Average Grade: " + isbn)
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="form-table" id="customFields">
<tr valign="top">
<th scope="row"><label for="customFieldName">Custom Field</label></th>
<td>
<input type="text" class="code" id="customFieldName" name="customFieldName[]" placeholder="Input Name" />
Add
</td>
</tr>
</table>
<button id = "click" class = "btn btn-primary" >Hi</button>
<p id = "averageGrade">Average Grade:</p>
Please help!
Thanks!
Each element.id must be unique - please change customFieldName to a class, and then iterate over the inputs and calculate the average. Also, you can reuse the same class for all "add" buttons and save that string in a variable so you don't have to paste it multiple times.
let inputTemplate = '<tr valign="top"><th scope="row"><label>Custom Field</label></th><td><input type="text" class="customFieldName code" name="customFieldName[]" value="" placeholder="Input Name" /> Add Remove</td></tr>';
$(document).ready(function() {
// adds a new row
$("#customFields").on('click', '.addCF', function() {
$("#customFields").append(inputTemplate);
});
// deletes the row
$("#customFields").on('click', '.remCF', function() {
$(this).parent().parent().remove();
});
$("#click").click(function() {
let fields = $('.customFieldName'),
total = 0;
for (let field of fields)
total += Number(field.value);
let average = total / fields.length;
$("#averageGrade").text("Average Grade: " + average);
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="form-table" id="customFields">
<tr valign="top">
<th scope="row"><label>Custom Field</label></th>
<td>
<input type="text" class="customFieldName code" name="customFieldName[]" placeholder="Input Name" />
Add
</td>
</tr>
</table>
<button id="click" class="btn btn-primary">Hi</button>
<p id="averageGrade">Average Grade:</p>
First of all, you need a way to select all the fields. Since id must (should) be unique, you could use the name or the class .code and remove id="customFieldName".
Then, getElementById, as its name suggests, returns one element. You need to select them all! If you're using class names, you can use getElementsByClassName, or querySelectorAll, or, since you're already using jQuery, just $(".code"), along with a loop to read each input's value (it you use jQuery, you can also use each()).
var sum=0,count=0,average;
$(".code").each(function() {
var value=parseInt($(this).val());
//You may want to validate the field
if(!isNaN(value)) sum+=value;
count++;
});
average=sum/count;
...
As many has pointed out (including myself in the comment section), you are going about using the wrong selector. id is a unique selector, meaning that the script will look at the first instance of the id and then stop immediately after.
What you need to do is use a selector that goes through every occurance of its instance. This is why class selectors exist. That will be the first fix in your code.
How I would go about calculating the average, personally, would be to make an array and push(); the values of the grades into the array. We will also need to do a parseInt() to make sure that our values are in fact handled as numbers. Otherwise, they'll be interpreted as strings.
You will then need to loop through the array, sum the values and divide by the length of the array.
HTML Example:
<div class="row">
<div class="col-12">
<table class="table form-table" id="customFields">
<tr valign="top">
<th scope="row"><label>Custom Field</label></th>
<td>
<input type="number" class="customFieldName" placeholder="Input Number" />
Add
</td>
</tr>
</table>
</div>
</div>
<div class="row">
<div class="col-md-4">
<button id="calcAvrgBtn" class="btn-primary">Calculate average grade</button>
</div>
<div class="col-md-4">
<p id="averageCalc"></p>
</div>
</div>
jQuery Example:
$('.addCF').on("click", function() {
$("#customFields").append('<tr valign="top"><th scope="row"><label>Custom Field</label></th><td><input type="number" class="customFieldName" placeholder="Input Number" /> Remove</td></tr>');
});
$(document).on("click", "a.remCF" , function() {
$(this).parent().parent().remove();
});
$('#calcAvrgBtn').on("click", function() {
let gradeArr = [];
$('.customFieldName').each(function() {
gradeArr.push(parseInt($(this).val()));
});
let total = 0;
for(var i = 0; i < gradeArr.length; i++) {
total += gradeArr[i];
}
let avg = total / gradeArr.length;
$('#averageCalc').text("The average grade is: "+avg);
});
Codepen example can be found here.
Snippet Example:
$('.addCF').on("click", function() {
$("#customFields").append('<tr valign="top"><th scope="row"><label>Custom Field</label></th><td><input type="number" class="customFieldName" placeholder="Input Number" /> Remove</td></tr>');
});
$(document).on("click", "a.remCF" , function() {
$(this).parent().parent().remove();
});
$('#calcAvrgBtn').on("click", function() {
let gradeArr = [];
$('.customFieldName').each(function() {
gradeArr.push(parseInt($(this).val()));
});
let total = 0;
for(var i = 0; i < gradeArr.length; i++) {
total += gradeArr[i];
}
let avg = total / gradeArr.length;
$('#averageCalc').text("The average grade is: "+avg);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-12">
<table class="table form-table" id="customFields">
<tr valign="top">
<th scope="row"><label>Custom Field</label></th>
<td>
<input type="number" class="customFieldName" placeholder="Input Number" />
Add
</td>
</tr>
</table>
</div>
</div>
<div class="row">
<div class="col-md-4">
<button id="calcAvrgBtn" class="btn-primary">Calculate average grade</button>
</div>
<div class="col-md-4">
<p id="averageCalc"></p>
</div>
</div>

hide last element of an array

How to hide the last index of an array as I want to hide the label and show the input when user clicks on add button . Couldn't find help . Here is my code:-
<tr ng-repeat="personalDetail in personalDetails">
<td>
<label ng-show="lab[$index]=true" for="settings" > {{personalDetail.Sname}}</label>
<input ng-show="lab[$index]=false" type="text" ng-model="personalDetail.Sname" />
</td>
<input type="button" class="btn btn-primary addnew pull-right btn-space" ng-click="addNew($index)" value=" Add New">
And my angular code :
$scope.addNew = function(val) {
$scope.personalDetails.push({
'Sname': "",
'Settings': "",
});
var ind = $scope.personalDetails.length - 1;
$("label[data-val='" + ind + "']").hide();
$("input[data-val='" + ind + "']").show();
$scope.PD = {};
};
try this
<tr ng-repeat="personalDetail in personalDetails">
<td>
<label ng-hide="$last" for="settings" > {{personalDetail.Sname}}</label>
<input ng-show="$last" type="text" ng-model="personalDetail.Sname" />
</td>
<tr>
Reference: ngRepeat
Just check for $last,
<td>
<label ng-show="lab[$index]==true" for="settings"> {{personalDetail.Sname}}</label>
<input ng-show="lab[$index]==false" type="text" ng-model="personalDetail.Sname" />
</td>

Codeigniter array input filed not working

I have a scenario in my project module which allows user to enter as many values as he wants in a form. I have given an array name to the field but when i try to get these values in my controller then it only returns the first value of the array. I have used java-script to append new input fields dynamically.
I can't figure out what mistake i am making.
Here is My code.
My view
<h1> <small>Order Details</small></h1>
<table class="table " id="dynamic_field">
<tr>
<td>
<input type="text" name="product_name[]" id="name" class="form-control name_list" placeholder="Product Name">
</td>
<td>
<button type="button" name="submit" id="add" class="btn btn- success">Add More</button>
</td>
</tr>
</table>
JavaScript Code
<script type="text/javascript">
var i = 1;
$('#add').click(function(){
i++;
$('#dynamic_field').append('<tr id="row'+i+'"><td><input type="text" name="product_name[]" id="last_class" class="form-control name_list" placeholder="Product Name"></td><td><button type="button" name="remove" class="btn btn-danger btn_remove" name="remove" id="'+i+'"> X</button></td></tr>')
});
$(document).on('click','.btn_remove',function() {
var button_id = $(this).attr("id");
$("#row"+button_id+"").remove();
});
</script>
When i try to print out the input field array using print_r it only returns the first value of the array even though we might have added more than 1 input fields.
Change your script and check
<script type="text/javascript">
var j = 1;
var i = 1;
$('#add').click(function()
{
i++;
$('#dynamic_field').append('<tr id="row'+i+'"><td><input type="text" name="product_name['+ j +']" id="last_class" class="form-control name_list" placeholder="Product Name"></td><td><button type="button" name="remove" class="btn btn-danger btn_remove" name="remove" id="'+i+'"> X</button></td></tr>');
j++ ;
});
$(document).on('click','.btn_remove',function()
{
var button_id = $(this).attr("id");
$("#row"+button_id+"").remove();
});
</script>
Try this in your controller
$names=$this->input->post('product_name') ;
foreach($names as $pname) {
echo $pname;
}

printing out a list of orders from a form using JS

I've been searching all over and can't seem to find an answer to my simple question. Basically I have created this form and a textarea below, I want to have my orders(you can make multiple orders using the same form) show up in the textarea below with the order number beside it.
I can't figure out how to do it. My problem is that I just keep over riding the first post, and I cant get my number to increment. Any help would be great!
Here is my form...
<div id="wrapper">
<h2>EMARKS REQUEST FORM</h2>
<table border="1">
<form id="requestForm">
<tr>
<td>ID</td>
<td><input type="text" class="inputText" id="id"/></td>
</tr>
<tr>
<td>Course Number</td>
<td><input type="text" class="inputText" id="courseNum" /></td>
</tr>
<tr>
<td>Description</td>
<td><input type="text" class="inputText" id="des" /></td>
</tr>
<tr>
<td>Distance Education</td>
<td id="checkBox"><input type="checkbox" id="distance"/></td>
</tr>
<tr>
<td>Additional Marks</td>
<td><input type="text" class="inputText" id="marks" /></td>
</tr>
</table> <br/>
Number of Courses <input type="text" value="0" /> Total Cost <input type="text" value="0" id="totalCost" /> <br/> <br/>
<h2 style="display:inline">Reasons:</h2>
<input type="radio" value="Doctor Note" />Doctor Note <input type="radio" value="Lack of Work" />Lack of Work <input type="radio" value="Some Compassion" />Some Compassion <br/><br/>
<input type="button" value="Go for It" onclick="getPrice()" /> <input type="button" value="Clear and Reset" />
<select>
<option value="First Time User">First Time User</option>
<option value="Frequent Flier">Frequent Flier</option>
<option value="Buying a Degree">Buying a Degree</option>
</select>
<h2>Summary of Your Request(s)</h2>
<textarea rows="10" cols="63" id="summary">
test
</textarea> <br/>
<h2>Danger Range</h2>
<textarea rows="10" cols="63">
test
</textarea>
</form>
</div>
And my Javascript
var itemNum = 0;
itemNum++;
var textBoxes = itemNum + " " + document.getElementById("id").value + " " + document.getElementById("courseNum").value + " " + document.getElementById("des").value + " " + document.getElementById("marks").value +" " + totalCost.value;
var summaryInfo = textBoxes;
summary.text = summaryInfo;
Use += to APPEND a string to an existing string.
summary.value += summaryInfo
Also, you are initializing itemNum to 0, then incrementing it by 1, EVERY time you execute. You need to initialize it ONCE, then increment it EVERY time, to get the effect you want.
var itemNum = 0;
function MyButtonClickHandler()
{
itemNum++;
var textBoxes = itemNum + " " + document.getElementById("id").value + " " + document.getElementById("courseNum").value + " " + document.getElementById("des").value + " " + document.getElementById("marks").value +" " + totalCost.value;
var summaryInfo = textBoxes;
summary.value += summaryInfo;
}
The problem’s here:
summary.text = summaryInfo;
The property is value, not text.
Here three things, you have problem:-
form tag is not opened/closed on the correct place
summary variable is not declared.
As minitech said, there is no property called text. It is value.
Do this way
document.getElementById("summary").value = textBoxes;
If(itemnum==""){
Itemnum=1;
}
Else
{
Itemnum=Itemnum+1;
}
Check the syntax please

Cloning with javascript - renaming ID of form elements within a table

I have some code I am using that works well cloning the contents of a div as many times as needed.
The original code would rename the name/id of each form field. so the first clone the name would be "name1" second clone "name2" etc...
The problem is when I put the form fields within a div or a table for design purposes.
The code doesn't rename the form fields anymore as it seems to refer to the top elment which is the table or div (depending which I used)
Here is a cut down version of the code that contains everything needed for this example (can be copied into an editor and will work as is. You will see the field id's are not being renamed):
www.jsbin.com/oyavez/1/edit
<script type="text/javascript">
var formCounter = 0;
function init() {
document.getElementById('moreFields').onclick = moreFields;
moreFields();
}
function moreFields() {
formCounter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + formCounter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
window.onload = moreFields;
</script>
<title>Add Orders IO TOC</title>
</head>
<body>
<!-- Template -->
<div id="readroot" style="display: none">
<table>
<tr><td colspan="2"><h3>Order <script>document.write(formCounter);</script></h2></td></tr>
<tr><td>Order ID: </td><td><input type="text" id="OrderID name="OrderID[]" ></input></td>
<td>Order Name: </td><td><input type="text" id="OrderName" name="OrderName[]" ></input></td>
</table>
<br /><br /><input type="button" value="Remove Above Order" style="width:200px;" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /><br /><br />
<!-- ROW -->
</div>
<!-- END Template -->
<!-- Start of form -->
<form method="get" action="form.php">
<table>
<tr><td align="center" colspan="2"><h2>Contract</h2></td></tr>
<!-- Static part of the form not to be cloned -->
<tr><td>Contract: </td><td><input type="text" id="Contract" name="Contract" ></input></td>
<td>Signed Date: </td><td><input type="text" id="datepicker0" name="SignedDate" ></input></td>
<tr><td align="center" colspan="2"><h2>Orders</h2></td></tr>
</table>
<!-- ROW -->
<!-- Cloned parts of the form appear here -->
<span id="writeroot"></span>
<table>
<tr><td align="center" > <input type="button" style="width:200px;" value="Add another order below" onclick="moreFields()" /></td>
<td align="center" ><input type="submit" value="Submit IO and all Orders" style="width:200px;" ></td></tr>
</table>
</form>
Anyone know how to get to the child of the table it would seem?
Thanks!

Categories

Resources