sending multiple rows from HTML to PHP and store in JSON - javascript

I need to provide option to user to enter multiple rows of data in form and save. I have html something like this.
<form id="books">
<table>
<tbody>
<tr>
<td><input name="bookName" type="text" /></td>
<td><input name="author" type="text" /></td>
<td><input name="publisher" type="text" /></td>
<td><input name="year" type="text" /></td>
</tr>
<tr>
<td><input name="bookName" type="text" /></td>
<td><input name="author" type="text" /></td>
<td><input name="publisher" type="text" /></td>
<td><input name="year" type="text" /></td>
</tr>
<tr>
<td><input name="bookName" type="text" /></td>
<td><input name="author" type="text" /></td>
<td><input name="publisher" type="text" /></td>
<td><input name="year" type="text" /></td>
</tr>
<tr>
<td><input name="bookName" type="text" /></td>
<td><input name="author" type="text" /></td>
<td><input name="publisher" type="text" /></td>
<td><input name="year" type="text" /></td>
</tr>
</tbody>
</table>
<button id="AddRow">Add Row</button>
<button id="SubmitBook">Save</button>
</form>
I want to save data in JSON thru PHP. Can someone help how can I serialize my form to POST like below, let me know if I have to use HTML in different way to make this easier (I tried finding solution, couldn't find anyone fitting my requirement):
{
"books": [
{"bookName":"html", "author":"xxxxx", "publisher":"johnWiley", "year":"2010"},
{"bookName":"CSS", "author":"yyyyy", "publisher":"johnWiley", "year":"2011"},
{"bookName":"javaScript", "author":"aaaa", "publisher":"johnWiley", "year":"2012"},
{"bookName":"PHP", "author":"bbbbb", "publisher":"johnWiley", "year":"2013"}
]
}

var arr = [];
$('#SubmitBook').click(function() {
var tablerow = $('#table').find('tr');
tablerow.each(function() {
var bookname = $(this).find('td .bookName').val();
var author = $(this).find('td .author').val()
var publisher = $(this).find('td .publisher').val()
var year = $(this).find('td .year').val()
arr.push({
bookname: bookname,
author: author,
publisher: publisher,
year: year
})
})
console.log(JSON.stringify(arr))
})
Try like this
DEMO

Related

EDGE laggy in showing keyboard input

The code below, when executed by edge shows a lot of input lag.
Steps to reproduce:
copy paste the snippit in a local html file.
It will not be reproducable from the snippit editor in stackoverflow.
open it with edge
make sure auto fill form fields are ON in edge settings/advanced . there is no need to actually have these form fields
slam your keyboard with random keys (more than 10 keys/sec)
it's a bit rude but necessary to demonstrate. On a production page where there is css, normal typing is enough to see the issue.
Not sure if it matters, Version where this issue works
Microsoft Edge 42.17134.1.0
Microsoft EdgeHTML 17.17134
You will see the input still being filled in even if you already stopped slamming the keyboard.
Workaround found but not acceptible for our situation
Disable "save form entries" option in edge. (not acceptable as we cannot force all our users to do this)
remove form element (obviously not acceptable)
<html>
<head>
</head>
<body>
<form method="post">
<div>
<div>
<table>
<tr>
<td><input class="decimal" id="OrderLines_0__AmountExcl" name="OrderLines[0].AmountExcl" type="text" value="45,00" /></td>
<td><input class="decimal" id="OrderLines_0__VAT" name="OrderLines[0].VAT" type="text" value="21,00" /></td>
<td><input class="decimal" id="OrderLines_0__Quantity" name="OrderLines[0].Quantity" type="text" value="1,00" /></td>
<td><input id="OrderLines_0__Unit" name="OrderLines[0].Unit" type="text" value="" /></td>
<td><input id="OrderLines_0__ReductionPercentage" name="OrderLines[0].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_1__AmountExcl" name="OrderLines[1].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_1__VAT" name="OrderLines[1].VAT" type="text" value="" /></td>
<td><input id="OrderLines_1__Quantity" name="OrderLines[1].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_1__Unit" name="OrderLines[1].Unit" type="text" value="" /></td>
<td><input id="OrderLines_1__ReductionPercentage" name="OrderLines[1].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_2__AmountExcl" name="OrderLines[2].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_2__VAT" name="OrderLines[2].VAT" type="text" value="" /></td>
<td><input id="OrderLines_2__Quantity" name="OrderLines[2].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_2__Unit" name="OrderLines[2].Unit" type="text" value="" /></td>
<td><input id="OrderLines_2__ReductionPercentage" name="OrderLines[2].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_3__AmountExcl" name="OrderLines[3].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_3__VAT" name="OrderLines[3].VAT" type="text" value="" /></td>
<td><input id="OrderLines_3__Quantity" name="OrderLines[3].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_3__Unit" name="OrderLines[3].Unit" type="text" value="" /></td>
<td><input id="OrderLines_3__ReductionPercentage" name="OrderLines[3].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_4__AmountExcl" name="OrderLines[4].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_4__VAT" name="OrderLines[4].VAT" type="text" value="" /></td>
<td><input id="OrderLines_4__Quantity" name="OrderLines[4].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_4__Unit" name="OrderLines[4].Unit" type="text" value="" /></td>
<td><input id="OrderLines_4__ReductionPercentage" name="OrderLines[4].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_5__AmountExcl" name="OrderLines[5].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_5__VAT" name="OrderLines[5].VAT" type="text" value="" /></td>
<td><input id="OrderLines_5__Quantity" name="OrderLines[5].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_5__Unit" name="OrderLines[5].Unit" type="text" value="" /></td>
<td><input id="OrderLines_5__ReductionPercentage" name="OrderLines[5].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_6__AmountExcl" name="OrderLines[6].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_6__VAT" name="OrderLines[6].VAT" type="text" value="" /></td>
<td><input id="OrderLines_6__Quantity" name="OrderLines[6].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_6__Unit" name="OrderLines[6].Unit" type="text" value="" /></td>
<td><input id="OrderLines_6__ReductionPercentage" name="OrderLines[6].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_7__AmountExcl" name="OrderLines[7].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_7__VAT" name="OrderLines[7].VAT" type="text" value="" /></td>
<td><input id="OrderLines_7__Quantity" name="OrderLines[7].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_7__Unit" name="OrderLines[7].Unit" type="text" value="" /></td>
<td><input id="OrderLines_7__ReductionPercentage" name="OrderLines[7].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_8__AmountExcl" name="OrderLines[8].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_8__VAT" name="OrderLines[8].VAT" type="text" value="" /></td>
<td><input id="OrderLines_8__Quantity" name="OrderLines[8].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_8__Unit" name="OrderLines[8].Unit" type="text" value="" /></td>
<td><input id="OrderLines_8__ReductionPercentage" name="OrderLines[8].ReductionPercentage" type="text" value="" /></td>
</tr>
<tr>
<td><input id="OrderLines_9__AmountExcl" name="OrderLines[9].AmountExcl" type="text" value="" /></td>
<td><input id="OrderLines_9__VAT" name="OrderLines[9].VAT" type="text" value="" /></td>
<td><input id="OrderLines_9__Quantity" name="OrderLines[9].Quantity" type="text" value="" /></td>
<td><input id="OrderLines_9__Unit" name="OrderLines[9].Unit" type="text" value="" /></td>
<td><input id="OrderLines_9__ReductionPercentage" name="OrderLines[9].ReductionPercentage" type="text" value="" /></td>
</tr>
</table>
</div>
</div>
</form>
</body>
</html>
Edge performance profiler shows big delays on the input event
And pins it to the AutoFormFill extension which is by default enabled in Edge
Detailed overview getFormIdentifier
Detailed overview Isimple iloop

How To get Multidimensional Input Fields Array Index with JavaScript?

This my sample HTML form with multidimensional input fields
<tr>
<td><input name="diameter[0][top]" type="text" id="diameter_top0" size="5" class="diameter" /></td>
<td><input name="diameter[0][bottom]" type="text" id="diameter_bottom0" size="5" class="diameter" /></td>
</tr>
<tr>
<td><input name="diameter[1][top]" type="text" id="diameter_top1" size="5" class="diameter" /></td>
<td><input name="diameter[1][bottom]" type="text" id="diameter_bottom1" size="5" class="diameter" /></td>
</tr>
<tr>
<td><input name="diameter[5][top]" type="text" id="diameter_top5" size="5" class="diameter" /></td>
<td><input name="diameter[5][bottom]" type="text" id="diameter_bottom5" size="5" class="diameter" /></td>
</tr>
Lets say I'm writing on ID diameter_bottom5 input. And onkeyup I need index of diameter of input field. In this example it would be 5.
I don't want to use regex or slice in name or id attribute.
I don't want to create custom attribute to store index.
How can get multidimensional input fields array index in which I'm currently typing using JavaScript?
If you are O.K. with the 'order index' of your table data, you can do it like that (obviously, this wouldn't work if your 'numbering' won't match given order and/or amount of inputs):
const tableData = [...document.getElementById('myTable').getElementsByTagName('td')]
tableData.forEach((item, i) => item.addEventListener('keyup', () => {
console.log(i)
}), false);
<table id='myTable'>
<tr>
<td><input name="diameter[0][top]" type="text" id="diameter_top0" size="5" class="diameter" /></td>
<td><input name="diameter[0][bottom]" type="text" id="diameter_bottom0" size="5" class="diameter" /></td>
</tr>
<tr>
<td><input name="diameter[1][top]" type="text" id="diameter_top1" size="5" class="diameter" /></td>
<td><input name="diameter[1][bottom]" type="text" id="diameter_bottom1" size="5" class="diameter" /></td>
</tr>
<tr>
<td><input name="diameter[5][top]" type="text" id="diameter_top5" size="5" class="diameter" /></td>
<td><input name="diameter[5][bottom]" type="text" id="diameter_bottom5" size="5" class="diameter" /></td>
</tr>
</table>

Re-Using JavaScript Function

Creating a cake ordering form, and the # of cakes available can vary from month to month. I am attempting to tweak a JS function created from #Anderson Contreira but in my fiddle it does not work. Here is what I have thus far - Why does nothing change when I enter a quantity?
https://jsfiddle.net/2uack1w6/
Syntax
JS
function calculate(el){
var quantity = el.val();
var id = el.attr("id").replace("item_","").replace("_qty","");
var data = {quantity: quantity,id:id};
var targetTax = $("#item_"+id+"_tax");
var targetTotalPrice = $("#item_"+id+"_totalprice");
$.post($.post(window.alert("It's been one or two or three entered");
});
}
var qty = $("#item_1_qty");
var qty1 = $("#item_2_qty");
var qty2 = $("#item_3_qty");
qty.on("keyup",function(){
window.alert("It's been one or two or three entered");
});
HTML/PHP
<body>
<form id="Form1" runat="server">
<div id="Form1" runat="server">
<table id="table1" border="1">
<tr>
<th>Item</th>
<th>Price</th>
<th>Quantity</th>
<th>Tax</th>
<th>Total</th>
</tr>
<tr>
<td><label for="lblChoccake">Choc Cake</label></td>
<td><label for="lblitem1price">$25.00</label></td>
<td><input type="text" id="item_1_qty" name="txtitem1qty" value="0" maxlength="10" size="3"></td>
<td><input type ="text" id="item_1_tax" name="txtitem1tax" maxlength="10" size="3" readonly></td>
<td><input type="text" id="item_1_totalprice" name="txtitem1totalprice" maxlength="10" size="3" readonly></td>
</tr>
<tr>
<td><label for="lblLemonFudgecake">Lemon Fudge Cake</label></td>
<td><label for="lblitem2price">$15.00</label></td>
<td><input type="text" id="item_2_qty" name="txtitem1qty" value="0" maxlength="10" size="3"></td>
<td><input type ="text" id="item_2_tax" name="txtitem1tax" maxlength="10" size="3" readonly></td>
<td><input type="text" id="item_2_totalprice" name="txtitem1totalprice" maxlength="10" size="3" readonly></td>
</tr>
<tr>
<td><label for="lblCoconut">Coconut Cake</label></td>
<td><label for="lblitem3price">$35.00</label></td>
<td><input type="text" id="item_3_qty" name="txtitem1qty" value="0" maxlength="10" size="3"></td>
<td><input type ="text" id="item_3_tax" name="txtitem1tax" maxlength="10" size="3" readonly></td>
<td><input type="text" id="item_3_totalprice" name="txtitem1totalprice" maxlength="10" size="3" readonly></td>
</tr>
</table>
</div>
</form>
</body>
jQuery(function($) {
var qty = $("#item_1_qty");
var qty1 = $("#item_2_qty");
var qty2 = $("#item_3_qty");
qty.on("keyup",function(){
alert("It's been one or two or three entered");
});
});
Try this, you are assigning variables before the document has actually loaded.
Take a look here: https://jsfiddle.net/andersoncontreira/mtu6syby/1/
You can make some changes and will work well:
Add a class in each input of item_?_qty e.g.: <input type="text" id="item_1_qty" class="item_qty" />
In your javascript, you can leave the call generic:
jQuery(document).ready(function(){
//you can use a class for help you
$(".item_qty").on("keyup",function(){
//window.alert("It's been one or two or three entered");
calculate($(this));
});
});

Update total in table row with jquery

I have a table
<table>
<tbody>
<tr>
<td><input type="text" name="quantity" /></td>
<td><input type="text" name="price" /></td>
<td><input type="text" name="total" disabled />
</tr>
<tr>
<td><input type="text" name="quantity" /></td>
<td><input type="text" name="price" /></td>
<td><input type="text" name="total" disabled />
</tr>
<tr>
<td><input type="text" name="quantity" /></td>
<td><input type="text" name="price" /></td>
<td><input type="text" name="total" disabled />
</tr>
<tr>
<td><input type="text" name="quantity" /></td>
<td><input type="text" name="price" /></td>
<td><input type="text" name="total" disabled />
</tr>
</tbody>
</table>
How can I update the total input field when a change in quantity or price happens?
I have thought of something like
$('table tbody tr td').filter(':nth-child(1), :nth-child(2)').children('input').change(function() {
$(this).parent('td').siblings('td').filter(':nth-child(3)').val(?);
});
but it seems a bit unhandy.
You can use:
$('table tbody tr td').find('input').keyup(function() {
var total=0;
total=(parseInt($(this).parent('td').siblings('td').not(':nth-child(3)').find('input').val())||0)+(parseInt($(this).val())||0);
$(this).closest('tr').find('input:last').val(total)
});
Working Demo
Much easy to read and control if you can assign some dummy class to quantity, price and total input.
Something like this:
HTML
<table>
<tbody>
<tr>
<td><input type="text" class="qty" name="quantity" /></td>
<td><input type="text" class="prc" name="price" /></td>
<td><input type="text" class="total" name="total" disabled />
</tr>
<tr>
<td><input type="text" class="qty" name="quantity" /></td>
<td><input type="text" class="prc" name="price" /></td>
<td><input type="text" class="total" name="total" disabled />
</tr>
<tr>
<td><input type="text" class="qty" name="quantity" /></td>
<td><input type="text" class="prc" name="price" /></td>
<td><input type="text" class="total" name="total" disabled />
</tr>
<tr>
<td><input type="text" class="qty" name="quantity" /></td>
<td><input type="text" class="prc" name="price" /></td>
<td><input type="text" class="total" name="total" disabled />
</tr>
</tbody>
</table>
Script
$('table tbody tr').find('.qty, .prc').on('keyup',function() {
var parent = $(this).parents('tr');
var quantity = parseInt(parent.find('.qty').val())||0;
var price = parseInt(parent.find('.prc').val())||0;
parent.find('.total').val(quantity*price);
});
Check working example here
Personally, i prefer not to select elements by their position. If you wind up changing them later, or adding another your code is broken.
I would do something like:
$(this).closest('tr').find('input[name=total]').val(?);

Get values from table of text fields javascript

I have a form which actually is a table of text fields. The html looks like this:
<form>
<table id="table">
<tr>
<th>Player</th>
<th>Number</th>
<th>Con.per.day</th>
<th>P.100.kg</th>
<th>P.day</th>
<th>I.month</th>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td>Result</td>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td>Result</td>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td>Result</td>
</tr>
</table>
<input type="button" name="rank" value="Rank" onClick="rankPlayers(this.form)"/>
</form>
I would like to iterate all fields and get the values at the press of the button, but I get undefined returned in the console log. I don't want to use IDs for each field as I want to do some column operations (add, multiply). My script for the first column looks like this:
function rankPlayers(){
var table=document.getElementById("table");
for(var i=1; i<table.rows.length;i++){
console.log(table.rows[i].cells[0].value);
}
}
Any tips? Thanks
You need to select the input from the cell:
// ------------------------------------v
console.log(table.rows[i].cells[0].firstChild.value);
If you could have siblings (even whitespace) around the inputs, then you can use the .children collection to target the correct element.
// ------------------------------------v
console.log(table.rows[i].cells[0].children[0].value);
You can change your loop to:
var table=document.getElementsByTagName("td");
for(var i=1; i<table.length;i++){
console.log(table[i].firstChild.value);
}
This gets all td elements, loops them, and checks the firstChild value

Categories

Resources