Dynamic Rows for Table in a Form - javascript

I'm trying to create a form that can dynamically add more rows to a table as needed. In the example that I will post you will see a table for chaperones. Since, we do not know off hand how many chaperones each school will bring it needs to be dynamic. I'm trying to use Javascript to create an onclick button that will add a new row to the table and storing the names as an array so that it can be sent POST and analyzed using PHP and then stored into the database. I found a solution online, however when I try to implement it on my site nothing is working once I click the button. Maybe I just need another set of eyes to look it over and see if I need anything.
<table id="chp" class="table table-striped">
<tr>
<th class="text-center">First Name</th>
<th class="text-center">Last Name</th>
<th class="text-center">Phone</th>
<th class="text-center">Email</th>
<th class="text-center"> + </th>
</tr>
<tr>
<td><input id="chpFirst" name="chpFirst" type="text" placeholder="John" class="form-control input-md" required=""></td>
<td><input id="chpLast" name="chpLast" type="text" placeholder="Doe" class="form-control input-md" required=""></td>
<td><input id="chpPhone" name="chpPhone" type="text" placeholder="5555555555" class="form-control input-md" required=""></td>
<td><input id="chpEmail" name="chpEmail" type="text" placeholder="john.doe#email.com" class="form-control input-md" required=""></td>
<td><input type="button" id="more_fields" onclick="add_chp();" value="Add" class="btn btn-info" /></td>
</tr>
</table>
<script>
function add_chp() {
document.getElementByID("chp").insertRow(-1).innerHTML = '<tr>' +
'<td><input id="chpFirst" name="chpFirst[]" type="text" placeholder="John" class="form-control input-md" required=""></td>' +
'<td><input id="chpLast" name="chpLast[]" type="text" placeholder="Doe" class="form-control input-md" required=""></td>' +
'<td><input id="chpPhone" name="chpPhone[]" type="text" placeholder="5555555555" class="form-control input-md" required=""></td>' +
'<td><input id="chpEmail" name="chpEmail[]" type="text" placeholder="john.doe#email.com" class="form-control input-md" required=""></td>' +
'<td><input type="button" id="more_fields" onclick="add_fields();" value="Add More" class="btn btn-info" /></td>' +
'</tr>';
}
</script>
https://jsfiddle.net/owk9ct13/

JavaScript is case sensitive:document.getElementByID wont work. Replace that with document.getElementById and it should fix your issue.
Also as a tip, be sure to check the any error or warning messages in the browser console...it makes debugging the front end way easier.

Related

Adding rows in the table with javascript

I have one form which has master detail data. i have created one table for details and creating rows on button click using JavaScript, but as soon as i am clicking add row button it is adding row and immediately my page gets reloaded so the added row disappears. i have another buttons to perform other PHP tasks so i can not remove form tag. please help me to get this done.
following is the HTML and JavaScript code.
<div class="row pt-3">
<div class="table-responsive">
<table id="vattable" class="table table-sm table-striped">
<thead class="thead-light">
<tr>
<th><?php echo GetBilingualLabels($_SESSION['$language'],"VATSETUP","VSDID"); ?></th>
<th><?php echo GetBilingualLabels($_SESSION['$language'],"VATSETUP","VSDSCATEGORY"); ?></th>
<th><?php echo GetBilingualLabels($_SESSION['$language'],"VATSETUP","VSDRATE"); ?></th>
<th><?php echo GetBilingualLabels($_SESSION['$language'],"VATSETUP","VSDAUTOFLAG"); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" class="text-control input-sm" readonly name="vsdid[]" id="vsdid" value=1 style="text-align:right" maxlength="13" /></td>
<td><input type="text" class="text-control" name="vsdscategory[]" id="vsdscategory1" style="text-align:right" maxlength="13" /></td>
<td><input type="text" class="text-control" name="vsdrate[]" id="vsdrate1" style="text-align:right" maxlength="13" /></td>
<td><input type="text" name="vsdautoflag[]" id="vsdautoflag1" style="text-align:right" maxlength="13" autofocus /></td>
</tr>
</tbody>
</table>
</div>
</div>
<script>
$(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
var count=1;
$(document).on('click','#addrow', function(){
//alert('a');
count=count+1;
$('#vsdid').val(count);
//alert(count);
var html_code='';
html_code +='<tr id="row_id_'+count+'">';
html_code += '<td><input type="text" class="text-control input-sm" name="vsdid[]" id="vsdid'+count+'" style="text-align:right"/></td>';
html_code +='<td><input type="text" class="text-control" name="vsdscategory[]" id="vsdscategory'+count+'" /></td>';
html_code +='<td><input type="text" class="text-control" name="vsdrate[]" id="vsdrate'+count+'" style="text-align:right" maxlength="13" /></td>';
html_code +='<td><input type="text" name="vsdautoflag[]" id="vsdautoflag'+count+'" style="text-align:right" /></td>';
html_code +='<td><button type="submit" name="removerow" id="removerow" class="btn btn-danger fa fa-minus"></button></td></tr>';
$('#vattable').append(html_code);
//alert(html_code);
});
});
</script>
It's possible that your #addrow button is the submit button and the form is being submitted. Add a return false just after //alert(html_code)
You haven't added a button to add the rows, so you're likely observing a side effect.
If I understand correctly, you want to have a button that on click will execute the function you've created. Therefore, you can add a button with id addrow below the table div like this:
<button id="addrow">
Add Row
</button>
And then you can attach your function via jQuery as you've started (I have slightly amended your script) - see JsFiddle - https://jsfiddle.net/9Ljc237k/9/
in your add row button click you should return false at the end,
or set type attribute of your button tag to button instead of submit
also is better to append row to tbody tag not table
If you have the problem only with reload you should put event.preventDefault()
$(document).on('click','#addrow', function(event){
event.preventDefault();
//alert('a');
count=count+1;
$('#vsdid').val(count);
//alert(count);
var html_code='';
html_code +='<tr id="row_id_'+count+'">';
html_code += '<td><input type="text" class="text-control input-sm" name="vsdid[]" id="vsdid'+count+'" style="text-align:right"/></td>';
html_code +='<td><input type="text" class="text-control" name="vsdscategory[]" id="vsdscategory'+count+'" /></td>';
html_code +='<td><input type="text" class="text-control" name="vsdrate[]" id="vsdrate'+count+'" style="text-align:right" maxlength="13" /></td>';
html_code +='<td><input type="text" name="vsdautoflag[]" id="vsdautoflag'+count+'" style="text-align:right" /></td>';
html_code +='<td><button type="submit" name="removerow" id="removerow" class="btn btn-danger fa fa-minus"></button></td></tr>';
$('#vattable').append(html_code);
//alert(html_code);
});

Passing multiple parameters with serialize jQuery in PHP

I have a problem with a serialized form. I need to pass multiple rows for creating an invoice, but it passes just the first row.
This is a form:
<form action="" id="generate_invoice" method="POST">
<td><input type="number" class="form-control n_invoice" name="n_invoice[]"></td>
<td><input type="date" class="form-control data" name="data[]"></td>
<td><input type="text" class="form-control description" name="description[]"></td>
<td><input type="number" class="form-control price" name="price[]" step=any></td>
<td><input type="number" class="form-control vat" name="vat[]">
</form>
This is a function which adds new rows:
function addrow_invoice() {
var i = $('#invoiceTable tr').length;
var tr = '<tr>'+
'<td><input type="checkbox" class="case"/></td>'+
'<td></td>'+
'<td></td>'+
'<td><input type="text" class="form-control description" name="description[]"></td>'+
'<td><input type="number" class="form-control price" name="price[]"></td>'+
'<td><input type="number" class="form-control vat" name="vat[]"></td>'+
'</tr>';
$('table#invoiceTable').append(tr);
i++;
};
And this is a test:
for($i = 0; $i<count($_POST['description']); $i++)
{
echo "{$_POST['description'][$i]}";
echo "<br>";
}
The issue is because your HTML is invalid. The form needs to wrap the table element, not be inside it. Because the HTML is invalid, the location of the form is moved so that it's not wrapping your input elements, hence nothing gets serialised.
Your HTML needs to be changed to this:
<form action="" id="generate_invoice" method="POST">
<table id="invoiceTable">
<tr>
<td><input type="number" class="form-control n_invoice" name="n_invoice[]"></td>
<td><input type="date" class="form-control data" name="data[]"></td>
<td><input type="text" class="form-control description" name="description[]"></td>
<td><input type="number" class="form-control price" name="price[]" step=any></td>
<td><input type="number" class="form-control vat" name="vat[]">
</tr>
<!-- additional rows appended here... -->
</table>
</form>

how to apply the same javascript/jquery to other input rows

I am new to Javascript and jQuery. I was trying to apply the same code to every input row in the table.
The HTML for the input row in that table is:
<tr>
<td>Seller1</td>
<td><input type="text" placeholder="" class="form-control" name="text1"></td>
<td><input type="text" placeholder="" class="form-control text2" id="text2">
</td>
</tr>
The Javascript/JQuery code to enable/disable 2nd column(text2) of the row is:
/*text field enable*/
$('#text2').attr('disabled',true);
$('input[name="text1"]').keyup(function(){
$('#text2').prop('disabled', this.value == "" ? true : false);
});
Thanks
Here a snippet able to handle multiple rows. Relies on class name instead of 'name' or 'id' attr
$(function(){
$('.text2').prop('disabled', true);
$('table input.text1').keyup(function(e) {
var show = $(this).val() == "" ? true : false;
$(this).parent().parent().find('input.text2').prop('disabled', show);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Seller1</td>
<td><input type="text" placeholder="" class="form-control text1"></td>
<td><input type="text" placeholder="" class="form-control text2"></td>
</tr>
<tr>
<td>Seller2</td>
<td><input type="text" placeholder="" class="form-control text1"></td>
<td><input type="text" placeholder="" class="form-control text2"></td>
</tr>
<tr>
<td>Seller3</td>
<td><input type="text" placeholder="" class="form-control text1"></td>
<td><input type="text" placeholder="" class="form-control text2"></td>
</tr>
</table>
you could select inputs by class:
$('.form-control').attr('disabled',true);
this will disable all elements with form-control class
The problem you're encountering may be one of scope. inside the keyup function, you refer to this.value, which is saying "if the value of #text2 is null..." -- that may not be what you want. Instead, look at the following:
/*text field enable*/
$('.sellerLast').attr('disabled', true);
//
$(".sellerFirst").each(function() {
$(this).on("keyup", function() {
console.log($(this).val());
if ($(this).val() !== "") {
$(this).parents("tr").find(".sellerLast").attr("disabled", false);
} else {
$(this).parents("tr").find(".sellerLast").attr("disabled", true);
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Seller1</td>
<td>
<input type="text" placeholder="" class="form-control sellerFirst" name="sellerFirst-1">
</td>
<td>
<input type="text" placeholder="" class="form-control sellerLast" name="sellerLast-1">
</td>
</tr>
<tr>
<td>Seller2</td>
<td>
<input type="text" placeholder="" class="form-control sellerFirst" name="sellerFirst-2">
</td>
<td>
<input type="text" placeholder="" class="form-control sellerLast" name="sellerLast-2">
</td>
</tr>
</table>
Well, I was an idiot. There were two thing going on -- first, the code within the template block may not have been doing what you expected, and second, you wanted to know how to extend that to ALL similarly structured elements on the page. This should do.
Edited with an "else" condition on the length of the first field -- the else sets the field back to disabled if the first field is blank.

Need help for array field

This script works fine for me:
<script>
calculate = function(){
var resources = document.getElementById('a1').value;
var minutes = document.getElementById('a2').value;
document.getElementById('a3').value = parseInt(resources)* parseInt(minutes);
}
</script>
<form action="ProvideMedicinProcess.php" class="register" method="POST">
<table id="dataTable" border="1">
<tbody>
<tr>
<td><input type="checkbox" required="required" name="chk[]" checked="checked" /></td>
<td><input type="datetime-local" required="required" name="VisitDate[]"></td>
<td>
<input class="form-control"type="text" required="required" placeholder="Symptoms" name="Symptoms[]">
</td>
<td>
<input class="form-control" type="text" required="required" placeholder="GivenMedicin" name="GivenMedicin[]">
</td>
<td>
<input id="a1" class="form-control" type="text" required="required" placeholder="UnitePrice" name="UnitePrice[]" onblur="calculate()" >
</td>
<td>
<input id="a2" class="form-control" type="text" required="required" placeholder="Quentity" name="Quentity[]" onblur="calculate()" >
</td>
<td>
<input id="a3" class="form-control" type="text" required="required" placeholder="SubTotal" name="SubTotal[]" >
</td>
</tr>
</tbody>
</table>
<input type="button" value="Add" onClick="addRow('dataTable')" />
<input type="button" value="Remove" onClick="deleteRow('dataTable')" />
<input class="submit" type="submit" value="Confirm" />
<input type="hidden" value="<?php echo $PatientIDSearch ?>" name="PatientIDSearch" />
</form>
But I need to calculate All Subtotal
Some issues:
If you add rows, you'll have to avoid that you get duplicate id property values in your HTML. It is probably easiest to just remove them and identify the input elements via their names, which does not have to be unique
It is bad practice to assign to a non-declared variable. Use var, and in the case of functions, you can just use the function calculate() { syntax.
Make the subtotal input elements read-only by adding the readonly attribute, otherwise the user can change the calculated total.
Instead of responding on blur events, you'll get a more responsive effect if you respond to the input event. And I would advise to bind the event handler via JavaScript, not via an HTML attribute.
I would fix some spelling errors in your elements (but maybe they make sense in your native language): Quantity with an 'a', UnitPrice without the 'e'.
You can use querySelectorAll to select elements by a CSS selector, and then Array.from to iterate over them.
See below snippet with 2 rows:
function calculate(){
var unitPrices = document.querySelectorAll('[name=UnitPrice\\[\\]]');
var quantities = document.querySelectorAll('[name=Quantity\\[\\]]');
var subTotals = document.querySelectorAll('[name=SubTotal\\[\\]]');
var grandTotal = 0;
Array.from(subTotals, function (subTotal, i) {
var price = +unitPrices[i].value * +quantities[i].value;
subTotal.value = price;
grandTotal += price;
});
// Maybe you can also display the grandTotal somehwere.
}
document.querySelector('form').addEventListener('input', calculate);
input { max-width: 7em }
<form action="ProvideMedicinProcess.php" class="register" method="POST">
<table id="dataTable" border="1">
<tbody>
<tr>
<td><input type="checkbox" required="required" name="chk[]" checked="checked" /></td>
<td><input type="datetime-local" required="required" name="VisitDate[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Symptoms" name="Symptoms[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Given Medicin" name="GivenMedicin[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Unit Price" name="UnitPrice[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Quantity" name="Quantity[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="SubTotal" readonly name="SubTotal[]" ></td>
</tr>
<tr>
<td><input type="checkbox" required="required" name="chk[]" checked="checked" /></td>
<td><input type="datetime-local" required="required" name="VisitDate[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Symptoms" name="Symptoms[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Given Medicin" name="GivenMedicin[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Unit Price" name="UnitPrice[]"></td>
<td><input class="form-control" type="text" required="required" placeholder="Quantity" name="Quantity[]"" ></td>
<td><input class="form-control" type="text" required="required" placeholder="SubTotal" readonly name="SubTotal[]" ></td>
</tr>
</tbody>
</table>
</form>

Update record into current json array angularjs

I want to update new row data in my current Address Array but its not updating,
See below images, I am new in Angular, add other object of array see last image
<tbody class="gradeX">
<tr ng-repeat="x in Profile.addresses">
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.site_name ' name='site_name'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.street_address ' name='street_address'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.city ' name='city'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.state ' name='state'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.country ' name='country'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.zip_code ' name='zip_code'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.phone_number ' name='phone_number'></td>
<tr ng-repeat="lines in array">
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.site_name ' name='site_name'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.street_address ' name='street_address'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.city ' name='city'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.state ' name='state'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.country ' name='country'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.zip_code ' name='zip_code'></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='x.phone_number ' name='phone_number'></td>
</tr>
</tr>
</tbody>
<i class="fa fa-plus fa-2x cust_primary" aria-hidden="true"></i>
Code Snippet for Adding new row in Address Array:
$scope.i = 0;
$scope.array = [];
$scope.addRow = function() {
$scope.i++;
$scope.array = [];
for(var i = 0; i < $scope.i; i++) {
$scope.array.push(i);
}
}
Code Snippet for Updating Textbox values into database:
$scope.updateProfile = function () {
$scope.tempObject={full_name:$scope.Profile.full_name,
mobile_number:$scope.Profile.mobile_number,
company_name:$scope.Profile.company_name,
designation: $scope.Profile.designation,
addresses: $scope.Profile.addresses,
payment_info: $scope.Profile.payment_info
};
addresses: $scope.Profile.addresses,
In Below Picture I click button (+) to generate new row with empty textfields:
After row appears, I enter some data:
When i Click Update button yellow highlighted new row data does not save, it shows old records after i refresh my page
My question in Simple. How to update the Address array with new row ?
If I am understanding you correctly, you just need to push the new data into your existing array like below:
$scope.updateProfile = function(){
$scope.addresses.push($scope.form)
$scope.form = {};
$scope.i = 0;
}
add $scope.form = {} to your controller to collect the new row, and change your model on the new row to "form." + the column name like below:
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.site_name ' ></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.street_address ' ></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.city '></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.state ' ></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.country ' ></td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.zip_code ' td>
<td><input type="text" class="form-control" id="inputDefault" ng-model='form.phone_number '></td>
Mind you, you will have to do much more to actually permanently add it to your database.
Here is a Plunker

Categories

Resources