我有库存表格将库存提交到数据库。我在更新动态生成的行的单位成本和总成本方面遇到了问题。正如您在下面的快照中看到的那样。产品名称是通过自动完成jQuery获取的。
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>#</th>
<th>Product Name/Code</th>
<th>Quantity</th>
<th>Unit Cost</th>
<th>Total Cost</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="p_scents">
<tr>
<td>1</td>
<td><input id="product_id" type="text" name="product_id[]" hidden><input id="product_code" type="text" name="product_code[]" hidden><input class="product_name form-control" id="product_name" type="text" placeholder="Type product name/code here" name="products[]" required></td>
<td><input class="quantity form-control" id="quantity" type="text" placeholder="Quantity to Buy" name="quantity[]" required /></td>
<td><div class="input-group"><span class="input-group-addon">$</span><input class="cost form-control" id="cost" placeholder="Unit Cost" type="text" readonly /></div></td>
<td><div class="input-group"><span class="input-group-addon">$</span><input class="total form-control" id="total" placeholder="Total" type="text" readonly /></div></td>
<td><button class="btn btn-default" type="button" id="addScnt"><i class="fa fa-plus "></i> Item</button></td>
</tr>
</tbody>
</table>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type='text/javascript'>
jQuery(document).ready(function(){
var scntDiv = $('#p_scents');
var i = $('#p_scents tr').size() + 1;
$('#addScnt').click(function() {
scntDiv.append('<tr>'+
'<td>'+i+'</td>'+
'<td><input id="product_id" type="text" name="product_id[]" hidden><input id="product_code" type="text" name="product_code[]" hidden><input class="product_name form-control" id="product_name" type="text" placeholder="Type product name/code here" name="products[]" required></td>'+
'<td><input class="quantity form-control" id="quantity" type="text" placeholder="Quantity to Buy" name="quantity[]" required /></td>'+
'<td><div class="input-group"><span class="input-group-addon">$</span><input class="cost form-control" id="cost" placeholder="Unit Cost" type="text" readonly /></div></td>'+
'<td><div class="input-group"><span class="input-group-addon">$</span><input class="total form-control" id="total" placeholder="Total" type="text" readonly /></div></td>'+
'<td><a id="remScnt" class="btn btn-danger btn-xs"><span title="Delete" class="glyphicon glyphicon-remove"></span></a></td>'+
'</tr>');
i++;
//return false;
$('.product_name').autocomplete({
source:'http://localhost/Multi-Channel_Shipping/inc/auto_product.php',
minLength:2,
select:function(evt, ui)
{
// when a product is selected, populate related fields in this form
this.form.cost.value = ui.item.cost;
this.form.product_id.value = ui.item.product_id;
this.form.product_code.value = ui.item.product_code;
}
});
$('.quantity').keyup(function() {
updateTotal();
});
$('.cost').keyup(function() {
updateTotal();
});
var updateTotal = function () {
var input1 = parseFloat($('.quantity').val());
var input2 = parseFloat($('.cost').val());
if (isNaN(input1) || isNaN(input2)) {
if(!input2){
$('.total').val($('.quantity').val());
}
if(!input1){
$('.total').val($('.cost').val());
}
} else {
$('.total').val(input1 * input2);
}
};
var output_total = $('.total');
var total = input1 + input2;
output_total.val(total);
});
//Remove button
$(document).on('click', '#remScnt', function() {
if (i > 2) {
$(this).closest('tr').remove();
i--;
}
return false;
});
$('.product_name').autocomplete({
source:'http://localhost/Multi-Channel_Shipping/inc/auto_product.php',
minLength:2,
select:function(evt, ui)
{
// when a zipcode is selected, populate related fields in this form
this.form.cost.value = ui.item.cost;
this.form.product_id.value = ui.item.product_id;
this.form.product_code.value = ui.item.product_code;
}
});
$('.quantity').keyup(function() {
updateTotal();
});
$('.cost').keyup(function() {
updateTotal();
});
var updateTotal = function () {
var input1 = parseFloat($('.quantity').val());
var input2 = parseFloat($('.cost').val());
if (isNaN(input1) || isNaN(input2)) {
if(!input2){
$('.total').val($('.quantity').val());
}
if(!input1){
$('.total').val($('.cost').val());
}
} else {
$('.total').val(input1 * input2);
}
};
var output_total = $('.total');
var total = input1 + input2;
output_total.val(total);
});
</script>
<?php
class DB
{
const DATABASE = 'multi-channel_shipping';
const HOST = 'localhost';
const USERNAME = 'root';
const PASSWORD = '';
static private $pdo;
static public function singleton()
{
if (!is_object(self::$pdo))
{
self::$pdo = new PDO('mysql:dbname=' . self::DATABASE . ';host=' . self::HOST,
self::USERNAME,
self::PASSWORD);
}
return self::$pdo;
}
private function __construct()
{
}
public function __clone()
{
throw new Exception('You may not clone the DB instance');
}
}
if (!isset($_REQUEST['term']))
{
die('([])');
}
$st = DB::singleton()
->prepare(
'SELECT * ' .
'FROM products ' .
'WHERE (name LIKE :name) OR (code LIKE :name) ' .
'ORDER BY name ASC ' .
'LIMIT 0,10');
$searchProduct = '%'.$_REQUEST['term'].'%';
$st->bindParam(':name', $searchProduct, PDO::PARAM_STR);
$data = array();
if ($st->execute())
{
while ($row = $st->fetch(PDO::FETCH_OBJ))
{
$data[] = array(
'value' => $row->code." - ".$row->name,
'cost' => $row->cost,
'product_id' => $row->id,
'product_code' => $row->code
);
}
}
echo json_encode($data);
flush();
?>
--
-- Table structure for table `products`
--
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(100) NOT NULL,
`name` varchar(255) NOT NULL,
`unit` varchar(50) DEFAULT NULL,
`cost` decimal(25,2) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `products`
--
INSERT INTO `products` (`id`, `code`, `name`, `unit`, `cost`) VALUES
(1, '4815162342', 'BAZIC 12 Dil Dil Pak', 'Packet', '0.10'),
(2, '23', 'Razer', 'Piece', '0.03');
我还需要输入运费成本输入字段并在表格底部显示发票总额。
答案 0 :(得分:3)
页面和页面存在多个问题。代码,所以我会尝试覆盖我能做的。 @Barmar
还发现了其他问题,因此会尝试涵盖所有内容并提出一些改进建议。
JSFiddle: http://jsfiddle.net/TrueBlueAussie/vx15mr4n/29/
<强>模板:强>
不是在代码中使用文本字符串,而是将HTML维护为 HTML 更容易。我提供的示例使用了一个虚拟脚本块(类型=“text / template”,所有浏览器都会忽略它),但您可以使用$('#template').html()
访问HTML内容。
重复ID无效
您不能在页面中包含重复的ID。这是无效的HTML和jQuery只会看到第一场比赛。改为使用添加元素上的类并匹配它们。
所以使用:
<a class="remScnt"
和
$(document).on('click', '.remScnt', function()
注意:您还需要排除任何其他重复的ID(例如product_id
和quantity
以及cost
和total
)。您的代码已经使用了类,因此只需移动/删除id
属性。
e.g。使用所有类的类:
scntDiv.append('<tr>'+
'<td>'+i+'</td>'+
'<td><input class="product_id" type="text" name="product_id[]" hidden><input id="product_code" type="text" name="product_code[]" hidden><input class="product_name form-control" type="text" placeholder="Type product name/code here" name="products[]" required></td>'+
'<td><input class="quantity form-control" type="text" placeholder="Quantity to Buy" name="quantity[]" required /></td>'+
'<td><div class="input-group"><span class="input-group-addon">$</span><input class="cost form-control" placeholder="Unit Cost" type="text" readonly /></div></td>'+
'<td><div class="input-group"><span class="input-group-addon">$</span><input class="total form-control" placeholder="Total" type="text" readonly /></div></td>'+
'<td><a class="remScnt btn btn-danger btn-xs"><span title="Delete" class="glyphicon glyphicon-remove"></span></a></td>'+
'</tr>');
您正在为一个处理程序使用委托事件,而不是其他处理程序。您还需要为keyup添加它们(可以组合使用,因为代码是相同的):
$('#p_scents').on('keyup', '.quantity .cost', function() {
updateTotal();
});
重要提示:此处的代码与特定行不匹配。也可以使用@Barmar's
这样修复以传递当前行:
$('#p_scents').on('keyup', '.quantity .cost', function() {
updateTotal($(this).closest('tr'));
});
更新:如下所示Regent
,您不应使用document
,而是使用#p_scents
作为委派事件处理程序:
$('#p_scents').on('click', '.remScnt', function()
委托事件应附加到最近的不变的祖先(如果方便/可用)。这将使得速度非常小,因为它在DOM中停止下降。
我还清理了执行计算的事件处理程序,现在使用临时变量,相对于行的元素,看起来像:
// Update the row total of a specific row
var updateTotal = function ($row) {
// Get the specific inputs
var $quantity = $('.quantity', $row);
var $cost = $('.cost', $row);
var $total = $('.total', $row);
var input1 = parseFloat($quantity.val());
var input2 = parseFloat($cost.val());
if (isNaN(input1) || isNaN(input2)) {
if (!input2) {
$total.val($quantity.val());
}
if (!input1) {
$total.val($cost.val());
}
} else {
$total.val(input1 * input2);
}
var total = input1 * input2;
$total.val(total);
};
注意:如果没有丢失的数据,我无法轻松测试代码,但您应该明白这一点。
总计
要更新总计,您需要迭代所有.total
字段并将其添加到运费中:
var updateGrandTotal = function()
{
// Now update the grand total
var grandTotal = 0;
$('.total').each(function () {
grandTotal += parseFloat($(this).val());
});
var shipping = parseFloat($('.shippingcost').val());
$('.grandtotal').val(grandTotal + shipping);
}
由于您希望在发货更改时更新总计,我会对其进行重构,以便也可以从运输中的密钥调用:
$('.shippingcost').keyup(function(){
updateGrandTotal();
});
另一个问题是自动填充功能(如果没有真正的数据Feed,我就无法测试):
基本上让select事件引用当前字段的行并找到要更新的相应字段:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/vx15mr4n/23/
select: function (evt, ui) {
// when a product is selected, populate related fields in this form
var $tr = $(this).closest("tr");
$(".cost",$tr).val(ui.item.cost);
$(".product_id", $tr).val(ui.item.product_id);
$(".product_code", $tr).val(ui.item.product_code);
}
答案 1 :(得分:0)
当updateTotal()
使用$('.quantity').val()
时,它会获取该类的第一个字段的值,而不是用户输入的行中的值。您需要将该行传递给该函数。此外,由于元素是动态添加的,因此您需要使用委托来进行事件绑定。
$('#p_scents').on('keyup', '.quantity, .cost', function() {
updateTotal($(this).closest('tr'));
});
var updateTotal = function (row) {
var input1 = parseFloat($('.quantity', row).val());
var input2 = parseFloat($('.cost', row).val());
if (isNaN(input1) || isNaN(input2)) {
if(!input2){
$('.total', row).val(input1);
}
if(!input1){
$('.total', row).val($(input2);
}
} else {
$('.total', row).val(input1 * input2);
}
}
var output_total = $('.total', row);
var total = input1 + input2;
output_total.val(total);
};