mirror of
https://github.com/grocy/grocy.git
synced 2025-10-15 01:37:13 +00:00
Form validation and barcode input handling improvements
This commit is contained in:
@@ -10,14 +10,26 @@
|
||||
spoiled = 1;
|
||||
}
|
||||
|
||||
Grocy.FetchJson('/api/stock/consume-product/' + jsonForm.product_id + '/' + jsonForm.amount + '?spoiled=' + spoiled,
|
||||
function(result)
|
||||
Grocy.FetchJson('/api/stock/get-product-details/' + jsonForm.product_id,
|
||||
function (productDetails)
|
||||
{
|
||||
$('#product_id_text_input').focus();
|
||||
$('#product_id_text_input').val('');
|
||||
$('#product_id_text_input').trigger('change');
|
||||
$('#amount').val(1);
|
||||
$('#consumption-form').validator('validate');
|
||||
Grocy.FetchJson('/api/stock/consume-product/' + jsonForm.product_id + '/' + jsonForm.amount + '?spoiled=' + spoiled,
|
||||
function(result)
|
||||
{
|
||||
toastr.success('Removed ' + jsonForm.amount + ' ' + productDetails.quantity_unit_stock.name + ' of ' + productDetails.product.name + ' from stock');
|
||||
|
||||
$('#amount').val(1);
|
||||
$('#product_id').val('');
|
||||
$('#product_id_text_input').focus();
|
||||
$('#product_id_text_input').val('');
|
||||
$('#product_id_text_input').trigger('change');
|
||||
$('#consumption-form').validator('validate');
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@@ -47,6 +59,24 @@ $('#product_id').on('change', function(e)
|
||||
|
||||
Grocy.EmptyElementWhenMatches('#selected-product-last-purchased-timeago', 'NaN years ago');
|
||||
Grocy.EmptyElementWhenMatches('#selected-product-last-used-timeago', 'NaN years ago');
|
||||
|
||||
if ((productStatistics.stock_amount || 0) === 0)
|
||||
{
|
||||
$('#product_id').val('');
|
||||
$('#product_id_text_input').val('');
|
||||
$('#product_id_text_input').addClass('has-error');
|
||||
$('#product_id_text_input').parent('.input-group').addClass('has-error');
|
||||
$('#product_id_text_input').closest('.form-group').addClass('has-error');
|
||||
$('#product-error').text('This product is not in stock.');
|
||||
$('#product-error').show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#product_id_text_input').removeClass('has-error');
|
||||
$('#product_id_text_input').parent('.input-group').removeClass('has-error');
|
||||
$('#product_id_text_input').closest('.form-group').removeClass('has-error');
|
||||
$('#product-error').hide();
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@@ -58,23 +88,26 @@ $('#product_id').on('change', function(e)
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('.datepicker').datepicker(
|
||||
{
|
||||
format: 'yyyy-mm-dd',
|
||||
startDate: '-3d',
|
||||
todayHighlight: true,
|
||||
autoclose: true,
|
||||
calendarWeeks: true,
|
||||
orientation: 'bottom auto'
|
||||
});
|
||||
$('.datepicker').val(moment().format('YYYY-MM-DD'));
|
||||
$('.datepicker').trigger('change');
|
||||
|
||||
$('.combobox').combobox({ appendId: '_text_input' });
|
||||
|
||||
$('#amount').val(1);
|
||||
$('#product_id').val('');
|
||||
$('#product_id_text_input').focus();
|
||||
$('#product_id_text_input').val('');
|
||||
$('#product_id_text_input').trigger('change');
|
||||
|
||||
$('#consumption-form').validator();
|
||||
$('#consumption-form').validator('validate');
|
||||
|
||||
$('#consumption-form input').keydown(function(event)
|
||||
{
|
||||
if (event.keyCode === 13) //Enter
|
||||
{
|
||||
if ($('#consumption-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error
|
||||
{
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@@ -1,22 +1,16 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-3 col-md-offset-2 main">
|
||||
<h1 class="page-header">Record consumption</h1>
|
||||
<h1 class="page-header">Consumption</h1>
|
||||
|
||||
<form id="consumption-form">
|
||||
<div class="form-group">
|
||||
<label for="product_id">Product</label>
|
||||
<select class="form-control combobox" id="product_id" name="product_id" required>
|
||||
<label for="product_id">Product <i class="fa fa-barcode"></i></label>
|
||||
<select data-instockproduct="instockproduct" class="form-control combobox" id="product_id" name="product_id" required>
|
||||
<option value=""></option>
|
||||
<?php foreach ($products as $product) : ?>
|
||||
<option value="<?php echo $product->id; ?>"><?php echo $product->name; ?></option>
|
||||
<option value="<?php echo $product->id; ?>"><?php echo $product->name; ?><?php if (!empty($product->barcode)) echo ' [' . $product->barcode . ']'; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control" id="barcode" name="barcode" />
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-barcode"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
<div id="product-error" class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="amount">Amount</label>
|
||||
@@ -32,7 +26,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 col-md-3 main well">
|
||||
<div class="col-sm-4 col-md-4 main well">
|
||||
<h3>Product overview <strong><span id="selected-product-name"></span></strong></h3>
|
||||
<h4><strong>Stock quantity unit:</strong> <span id="selected-product-stock-qu-name"></span></h4>
|
||||
|
||||
|
@@ -1,4 +1,7 @@
|
||||
$(function()
|
||||
{
|
||||
$('#current-stock-table').DataTable({ 'paging': false });
|
||||
$('#current-stock-table').DataTable({
|
||||
'paging': false,
|
||||
'order': [[2, 'asc']]
|
||||
});
|
||||
});
|
||||
|
@@ -11,16 +11,17 @@
|
||||
|
||||
<title><?php echo $title; ?> | grocy</title>
|
||||
|
||||
<link href="/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap-combobox/css/bootstrap-combobox.css" rel="stylesheet" />
|
||||
<link href="/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/datatables.net-responsive-bs/css/responsive.bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/style.css" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap/dist/css/bootstrap.min.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/bower_components/font-awesome/css/font-awesome.min.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap-combobox/css/bootstrap-combobox.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/bower_components/datatables.net-responsive-bs/css/responsive.bootstrap.min.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/bower_components/toastr/toastr.min.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
<link href="/style.css?v=<?php echo Grocy::GetInstalledVersion(); ?>" rel="stylesheet" />
|
||||
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src="/grocy.js"></script>
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/grocy.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -93,7 +94,7 @@
|
||||
<br />
|
||||
Created with passion since 2017
|
||||
<br />
|
||||
Version <?php echo file_get_contents('version.txt'); ?>
|
||||
Version <?php echo Grocy::GetInstalledVersion(); ?>
|
||||
<br />
|
||||
Life runs on code
|
||||
<br />
|
||||
@@ -108,21 +109,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
<script src="/bower_components/bootbox/bootbox.js"></script>
|
||||
<script src="/bower_components/jquery.serializeJSON/jquery.serializejson.min.js"></script>
|
||||
<script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
|
||||
<script src="/bower_components/moment/min/moment.min.js"></script>
|
||||
<script src="/bower_components/bootstrap-validator/dist/validator.min.js"></script>
|
||||
<script src="/bower_components/bootstrap-combobox/js/bootstrap-combobox.js"></script>
|
||||
<script src="/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||
<script src="/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||
<script src="/bower_components/datatables.net-responsive/js/dataTables.responsive.min.js"></script>
|
||||
<script src="/bower_components/datatables.net-responsive-bs/js/responsive.bootstrap.min.js"></script>
|
||||
<script src="/bower_components/jquery-timeago/jquery.timeago.js"></script>
|
||||
<script src="/bower_components/bootstrap/dist/js/bootstrap.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/bootbox/bootbox.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/jquery.serializeJSON/jquery.serializejson.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/moment/min/moment.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/bootstrap-validator/dist/validator.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/bootstrap-combobox/js/bootstrap-combobox.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/datatables.net/js/jquery.dataTables.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/datatables.net-responsive/js/dataTables.responsive.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/datatables.net-responsive-bs/js/responsive.bootstrap.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/jquery-timeago/jquery.timeago.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<script src="/bower_components/toastr/toastr.min.js?v=<?php echo Grocy::GetInstalledVersion(); ?>"></script>
|
||||
|
||||
<?php if (file_exists(__DIR__ . '/' . str_replace('.php', '.js', $contentPage))) : ?>
|
||||
<script src="/views/<?php echo str_replace('.php', '.js', $contentPage); ?>"></script>
|
||||
<script src="/views/<?php echo str_replace('.php', '.js', $contentPage) . '?v=' . Grocy::GetInstalledVersion(); ?>"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (file_exists(__DIR__ . '/../data/add_before_end_body.html')) include __DIR__ . '/../data/add_before_end_body.html' ?>
|
||||
|
@@ -36,3 +36,12 @@ $(function()
|
||||
$('#product-form').validator();
|
||||
$('#product-form').validator('validate');
|
||||
});
|
||||
|
||||
$('#barcode').keydown(function(event)
|
||||
{
|
||||
if (event.keyCode === 13) //Enter
|
||||
{
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
@@ -3,26 +3,28 @@
|
||||
e.preventDefault();
|
||||
|
||||
var jsonForm = $('#purchase-form').serializeJSON();
|
||||
delete jsonForm.barcode;
|
||||
|
||||
Grocy.FetchJson('/api/get-object/products/' + jsonForm.product_id,
|
||||
function(product)
|
||||
Grocy.FetchJson('/api/stock/get-product-details/' + jsonForm.product_id,
|
||||
function (productDetails)
|
||||
{
|
||||
jsonForm.amount = jsonForm.amount * product.qu_factor_purchase_to_stock;
|
||||
jsonForm.amount = jsonForm.amount * productDetails.product.qu_factor_purchase_to_stock;
|
||||
|
||||
Grocy.FetchJson('/api/helper/uniqid',
|
||||
function (uniqidResponse)
|
||||
function(uniqidResponse)
|
||||
{
|
||||
jsonForm.amount = jsonForm.amount * product.qu_factor_purchase_to_stock;
|
||||
jsonForm.stock_id = uniqidResponse.uniqid;
|
||||
|
||||
Grocy.PostJson('/api/add-object/stock', jsonForm,
|
||||
function(result)
|
||||
{
|
||||
toastr.success('Added ' + jsonForm.amount + ' ' + productDetails.quantity_unit_stock.name + ' of ' + productDetails.product.name + ' to stock');
|
||||
|
||||
$('#amount').val(1);
|
||||
$('#best_before_date').val('');
|
||||
$('#product_id').val('');
|
||||
$('#product_id_text_input').focus();
|
||||
$('#product_id_text_input').val('');
|
||||
$('#product_id_text_input').trigger('change');
|
||||
$('#amount').val(1);
|
||||
$('#purchase-form').validator('validate');
|
||||
},
|
||||
function(xhr)
|
||||
@@ -51,16 +53,16 @@ $('#product_id').on('change', function(e)
|
||||
if (productId)
|
||||
{
|
||||
Grocy.FetchJson('/api/stock/get-product-details/' + productId,
|
||||
function(productStatistics)
|
||||
function(productDetails)
|
||||
{
|
||||
$('#selected-product-name').text(productStatistics.product.name);
|
||||
$('#selected-product-stock-amount').text(productStatistics.stock_amount || '0');
|
||||
$('#selected-product-stock-qu-name').text(productStatistics.quantity_unit_stock.name);
|
||||
$('#selected-product-purchase-qu-name').text(productStatistics.quantity_unit_purchase.name);
|
||||
$('#selected-product-last-purchased').text((productStatistics.last_purchased || 'never').substring(0, 10));
|
||||
$('#selected-product-last-purchased-timeago').text($.timeago(productStatistics.last_purchased || ''));
|
||||
$('#selected-product-last-used').text((productStatistics.last_used || 'never').substring(0, 10));
|
||||
$('#selected-product-last-used-timeago').text($.timeago(productStatistics.last_used || ''));
|
||||
$('#selected-product-name').text(productDetails.product.name);
|
||||
$('#selected-product-stock-amount').text(productDetails.stock_amount || '0');
|
||||
$('#selected-product-stock-qu-name').text(productDetails.quantity_unit_stock.name);
|
||||
$('#selected-product-purchase-qu-name').text(productDetails.quantity_unit_purchase.name);
|
||||
$('#selected-product-last-purchased').text((productDetails.last_purchased || 'never').substring(0, 10));
|
||||
$('#selected-product-last-purchased-timeago').text($.timeago(productDetails.last_purchased || ''));
|
||||
$('#selected-product-last-used').text((productDetails.last_used || 'never').substring(0, 10));
|
||||
$('#selected-product-last-used-timeago').text($.timeago(productDetails.last_used || ''));
|
||||
|
||||
Grocy.EmptyElementWhenMatches('#selected-product-last-purchased-timeago', 'NaN years ago');
|
||||
Grocy.EmptyElementWhenMatches('#selected-product-last-used-timeago', 'NaN years ago');
|
||||
@@ -78,20 +80,98 @@ $(function()
|
||||
$('.datepicker').datepicker(
|
||||
{
|
||||
format: 'yyyy-mm-dd',
|
||||
startDate: '+7d',
|
||||
startDate: '+0d',
|
||||
todayHighlight: true,
|
||||
autoclose: true,
|
||||
calendarWeeks: true,
|
||||
orientation: 'bottom auto'
|
||||
orientation: 'bottom auto',
|
||||
weekStart: 1,
|
||||
showOnFocus: false
|
||||
});
|
||||
$('.datepicker').val(moment().format('YYYY-MM-DD'));
|
||||
$('.datepicker').trigger('change');
|
||||
|
||||
$('.combobox').combobox({ appendId: '_text_input' });
|
||||
|
||||
$('#amount').val(1);
|
||||
$('#best_before_date').val('');
|
||||
$('#product_id').val('');
|
||||
$('#product_id_text_input').focus();
|
||||
$('#product_id_text_input').val('');
|
||||
$('#product_id_text_input').trigger('change');
|
||||
|
||||
$('#purchase-form').validator();
|
||||
$('#purchase-form').validator({
|
||||
custom: {
|
||||
'isodate': function($el)
|
||||
{
|
||||
if ($el.val().length !== 0 && !moment($el.val(), 'YYYY-MM-DD', true).isValid())
|
||||
{
|
||||
return 'Wrong date format, needs to be YYYY-MM-DD';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#purchase-form').validator('validate');
|
||||
|
||||
$('#purchase-form input').keydown(function(event)
|
||||
{
|
||||
if (event.keyCode === 13) //Enter
|
||||
{
|
||||
if ($('#purchase-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error
|
||||
{
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#best_before_date-datepicker-button').on('click', function(e)
|
||||
{
|
||||
$('.datepicker').datepicker('show');
|
||||
});
|
||||
|
||||
$('#best_before_date').on('change', function(e)
|
||||
{
|
||||
var value = $('#best_before_date').val();
|
||||
if (value.length === 8 && $.isNumeric(value))
|
||||
{
|
||||
value = value.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
|
||||
$('#best_before_date').val(value);
|
||||
$('#purchase-form').validator('validate');
|
||||
}
|
||||
});
|
||||
|
||||
$('#best_before_date').on('keypress', function(e)
|
||||
{
|
||||
var element = $(e.target);
|
||||
var value = element.val();
|
||||
var dateObj = moment(element.val(), 'YYYY-MM-DD', true);
|
||||
|
||||
$('.datepicker').datepicker('hide');
|
||||
|
||||
if (value.length === 0)
|
||||
{
|
||||
element.val(moment().format('YYYY-MM-DD'));
|
||||
}
|
||||
else if (dateObj.isValid())
|
||||
{
|
||||
if (e.keyCode === 38) //Up
|
||||
{
|
||||
element.val(dateObj.add(-1, 'days').format('YYYY-MM-DD'));
|
||||
}
|
||||
else if (e.keyCode === 40) //Down
|
||||
{
|
||||
element.val(dateObj.add(1, 'days').format('YYYY-MM-DD'));
|
||||
}
|
||||
else if (e.keyCode === 37) //Left
|
||||
{
|
||||
element.val(dateObj.add(-1, 'weeks').format('YYYY-MM-DD'));
|
||||
}
|
||||
else if (e.keyCode === 39) //Right
|
||||
{
|
||||
element.val(dateObj.add(1, 'weeks').format('YYYY-MM-DD'));
|
||||
}
|
||||
}
|
||||
|
||||
$('#purchase-form').validator('validate');
|
||||
});
|
||||
|
@@ -1,19 +1,23 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-3 col-md-offset-2 main">
|
||||
<h1 class="page-header">Record purchase</h1>
|
||||
<div class="col-sm-4 col-sm-offset-3 col-md-3 col-md-offset-2 main">
|
||||
<h1 class="page-header">Purchase</h1>
|
||||
|
||||
<form id="purchase-form">
|
||||
<div class="form-group">
|
||||
<label for="product_id">Product</label>
|
||||
<label for="product_id">Product <i class="fa fa-barcode"></i></label>
|
||||
<select class="form-control combobox" id="product_id" name="product_id" required>
|
||||
<option value=""></option>
|
||||
<?php foreach ($products as $product) : ?>
|
||||
<option value="<?php echo $product->id; ?>"><?php echo $product->name; ?></option>
|
||||
<option value="<?php echo $product->id; ?>"><?php echo $product->name; ?><?php if (!empty($product->barcode)) echo ' [' . $product->barcode . ']'; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="best_before_date">Best before</label>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control" id="barcode" name="barcode" />
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-barcode"></i>
|
||||
<input type="text" data-isodate="isodate" class="form-control datepicker" id="best_before_date" name="best_before_date" required autocomplete="off">
|
||||
<div id="best_before_date-datepicker-button" class="input-group-addon">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
@@ -23,21 +27,11 @@
|
||||
<input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="best_before_date">Best before</label>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control datepicker" id="best_before_date" name="best_before_date" required>
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<button id="save-purchase-button" type="submit" class="btn btn-default">OK</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 col-md-3 main well">
|
||||
<div class="col-sm-4 col-md-4 main well">
|
||||
<h3>Product overview <strong><span id="selected-product-name"></span></strong></h3>
|
||||
<h4><strong>Purchase quantity:</strong> <span id="selected-product-purchase-qu-name"></span></h4>
|
||||
|
||||
|
Reference in New Issue
Block a user