Reputation: 49
So I have the following code:
$('input.qty').change(function() {
var $tr = $(this).closest('tr');
var price = $(this).closest('tr').find('input.price').val();
// var price = parseFloat($tr.find('td').eq(1).text());
var qty = parseInt($(this).val());
$(this).closest('tr').find('input.amt').val(qty * price);
});
.tis {
border: none;
background-color: Transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Font Awesome CDN -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<!-- Bootstrap CSS/CDN -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<main role="main">
<script type="text/javascript">
function addRow() {
var table = document.getElementById("invoiceTableBody")
table.innerHTML+=
'<tr>' +
'<td>'+
'<div>'+
'<select class="try" name="this">'+
'<option value="Option1">Option 1</option>'+
'<option value="Option2">Option 2</option>'+
'<option value="Option3">Option 3</option>'+
'</select>'+
'</div>'+
'</td>'+
'<td><input type="text" name="l108Price[]" size= "3" class="price tis"></td>' +
'<td><input type="text" name="l108Qty[]" size= "1" class="qty tis"></td>' +
'<td><input type= "text" name="l108Amt[]" size= "3" class="amt tis" disabled></td>' +
'<td><div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div></td>'; +
'</tr>';
};
</script>
<div class="row">
<div class="col-md-8 offset-2">
<table class="table thead-dark table-hover border-bottom" id="invoiceTable">
<thead>
<tr>
<th style="width: 60%">Item - Description</th>
<th style="width: 10%">Price</th>
<th style="width: 5%">Qty</th>
<th style="width: 10%">Amount</th>
<th style=>Action</th>
</tr>
</thead>
<tbody id="invoiceTableBody">
<tr id="invoiceTableRow">
<td>
<div>
<select class="try" name="this">
<option value="<Option1">Option 1</option>
<option value="<Option2">Option 2</option>
<option value="<Option3">Option 3</option>
</select>
</div>
</td>
<td><input type="text" name="l108Price[]" size="3" class="price tis"></td>
<td><input type="text" name="l108Qty[]" size="1" class="qty tis"></td>
<td><input type='text' name='l108Amt[]' size='3' class="amt tis" disabled></td>
<td>
<div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main><!-- /role main -->
</body>
</html>
The goal here is to create an invoicing system. Everything is working fine 'til I attempt to add a row by clicking the button at the end of the row. Once I do, everything gets reset and I have no idea why.
Upvotes: 2
Views: 428
Reputation: 513
The issue is caused by the table.innerHTML += '<tr>...</tr>';
. statement.
innerHTML
changes the HTML of an object which certainly can affect size and position and will trigger at least a partial reflow. That's why the content of your table row will be reset.
Instead use the HTMLElement.prototype.insertAdjacentHTML
method to insert HTMLElements into the DOM the right way. So I've rewritten your code a little:
$('#invoiceTableBody').on('change', 'input.qty', function() {
var $tr = $(this).closest('tr');
var price = $(this).closest('tr').find('input.price').val();
// var price = parseFloat($tr.find('td').eq(1).text());
var qty = parseInt($(this).val());
$(this).closest('tr').find('input.amt').val(qty * price);
});
.tis {
border: none;
background-color: Transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Font Awesome CDN -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<!-- Bootstrap CSS/CDN -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<main role="main">
<script type="text/javascript">
function addRow() {
var table = document.getElementById("invoiceTableBody")
// Composing your HTMLElement as a string
var element =
'<tr>' +
'<td>' +
'<div>' +
'<select class="try" name="this">' +
'<option value="Option1">Option 1</option>' +
'<option value="Option2">Option 2</option>' +
'<option value="Option3">Option 3</option>' +
'</select>' +
'</div>' +
'</td>' +
'<td><input type="text" name="l108Price[]" size= "3" class="price tis"></td>' +
'<td><input type="text" name="l108Qty[]" size= "1" class="qty tis"></td>' +
'<td><input type= "text" name="l108Amt[]" size= "3" class="amt tis" disabled></td>' +
'<td><div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div></td>' +
'</tr>';
// Inserting the string as a HTMLElement at the end of the table element
table.insertAdjacentHTML('beforeend', element);
};
</script>
<div class="row">
<div class="col-md-8 offset-2">
<table class="table thead-dark table-hover border-bottom" id="invoiceTable">
<thead>
<tr>
<th style="width: 60%">Item - Description</th>
<th style="width: 10%">Price</th>
<th style="width: 5%">Qty</th>
<th style="width: 10%">Amount</th>
<th style=>Action</th>
</tr>
</thead>
<tbody id="invoiceTableBody">
<tr id="invoiceTableRow">
<td>
<div>
<select class="try" name="this">
<option value="<Option1">Option 1</option>
<option value="<Option2">Option 2</option>
<option value="<Option3">Option 3</option>
</select>
</div>
</td>
<td><input type="text" name="l108Price[]" size="3" class="price tis"></td>
<td><input type="text" name="l108Qty[]" size="1" class="qty tis"></td>
<td><input type='text' name='l108Amt[]' size='3' class="amt tis" disabled></td>
<td>
<div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<!-- /role main -->
</body>
</html>
If you want to have the new row added right below the one you clicked on, you could do it by using the code below. I removed your script from HTML:
$('#invoiceTableBody').on('click', 'button.action', function() {
var row = event.target.closest(".invoiceTableRow");
// Composing your HTMLElement as a string
var element =
'<tr class="invoiceTableRow">' +
'<td>' +
'<div>' +
'<select class="try" name="this">' +
'<option value="Option1">Option 1</option>' +
'<option value="Option2">Option 2</option>' +
'<option value="Option3">Option 3</option>' +
'</select>' +
'</div>' +
'</td>' +
'<td><input type="text" name="l108Price[]" size= "3" class="price tis"></td>' +
'<td><input type="text" name="l108Qty[]" size= "1" class="qty tis"></td>' +
'<td><input type= "text" name="l108Amt[]" size= "3" class="amt tis" disabled></td>' +
'<td><div><button type="button" name="button" style="background-color:Transparent; border:none; color:green;" class="action"><i class="fas fa-plus-circle"></i></button></div></td>' +
'</tr>';
// Inserting the string as a HTMLElement after the current row
row.insertAdjacentHTML('afterend', element);
});
$('#invoiceTableBody').on('change', 'input.qty', function() {
var $tr = $(this).closest('tr');
var price = $(this).closest('tr').find('input.price').val();
// var price = parseFloat($tr.find('td').eq(1).text());
var qty = parseInt($(this).val());
$(this).closest('tr').find('input.amt').val(qty * price);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Font Awesome CDN -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<!-- Bootstrap CSS/CDN -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<main role="main">
<script type="text/javascript">
</script>
<div class="row">
<div class="col-md-8 offset-2">
<table class="table thead-dark table-hover border-bottom" id="invoiceTable">
<thead>
<tr>
<th style="width: 60%">Item - Description</th>
<th style="width: 10%">Price</th>
<th style="width: 5%">Qty</th>
<th style="width: 10%">Amount</th>
<th style=>Action</th>
</tr>
</thead>
<tbody id="invoiceTableBody">
<tr id="invoiceTableRow" class="invoiceTableRow">
<td>
<div>
<select class="try" name="this">
<option value="<Option1">Option 1</option>
<option value="<Option2">Option 2</option>
<option value="<Option3">Option 3</option>
</select>
</div>
</td>
<td><input type="text" name="l108Price[]" size="3" class="price tis"></td>
<td><input type="text" name="l108Qty[]" size="1" class="qty tis"></td>
<td><input type='text' name='l108Amt[]' size='3' class="amt tis" disabled></td>
<td>
<div><button type="button" name="button" class="action" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<!-- /role main -->
</body>
</html>
Upvotes: 1
Reputation:
You made a very simple error, check your code here :
var table = document.getElementById("invoiceTableBody")
table.innerHTML+=
'<tr>' +
'<td>'+
'<div>'+
'<select class="try" name="this">'+
'<option value="Option1">Option 1</option>'+
'<option value="Option2">Option 2</option>'+
'<option value="Option3">Option 3</option>'+
'</select>'+
'</div>'+
'</td>'+
'<td><input type="text" name="l108Price[]" size= "3" class="price tis"></td>' +
'<td><input type="text" name="l108Qty[]" size= "1" class="qty tis"></td>' +
'<td><input type= "text" name="l108Amt[]" size= "3" class="amt tis" disabled></td>' +
'<td><div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div></td>'; +
'</tr>';
There is a semicolon that should not be there on this line :
'<td><div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div></td>'; +
You should change that line to this :
'<td><div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div></td>'+
So your bloc should be like :
var table = document.getElementById("invoiceTableBody")
table.innerHTML+=
'<tr>' +
'<td>'+
'<div>'+
'<select class="try" name="this">'+
'<option value="Option1">Option 1</option>'+
'<option value="Option2">Option 2</option>'+
'<option value="Option3">Option 3</option>'+
'</select>'+
'</div>'+
'</td>'+
'<td><input type="text" name="l108Price[]" size= "3" class="price tis"></td>' +
'<td><input type="text" name="l108Qty[]" size= "1" class="qty tis"></td>' +
'<td><input type= "text" name="l108Amt[]" size= "3" class="amt tis" disabled></td>' +
'<td><div><button type="button" name="button" onclick="addRow()" style="background-color:Transparent; border:none; color:green;"><i class="fas fa-plus-circle"></i></button></div></td>' +
'</tr>';
Upvotes: 1