Динамически создаваемая форма с подсчетом суммы
Добрый день!
Подскажите есть динамически создаваемая форма:
<div class="row">
<div class="col-1">№</div>
<div class="col-4">Номенклатура</div>
<div class="col-1">Кол-во</div>
<div class="col-2">Цена</div>
<div class="col-2">Сумма</div>
<div class="col-2"></div>
</div>
<div class="row">
<div data-container="set">
<div class="row p-2" data-item="set">
<div class="col-1"><input type="text" value="" name="str[]" value=""></div>
<div class="col-4"> <input type="text" name="name[]" value=""></div>
<div class="col-1"> <input type="text" name="num[]" value=""></div>
<div class="col-2"> <input type="text" name="price[]" value=""></div>
<div class="col-2"> <input type="text" name="sum[]" value="" readonly></div>
<div class="col-2"> <a type="button" data-action="remove" class="remove">[-]</a>
<a type="button" data-action="add" class="add">[+]</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col text-right"><hr>
<label>Итого: <input type="text" name="totalsum" value="" class="total" readonly></label>
</div>
</div>
И скрипт JS:
$(function () {
var $container = $('[data-container="set"]'),
$row = $container.find('[data-item="set"]').clone(true),
$totalsum = $('[name="totalsum"]');
$(document)
.on('click', '[data-action="add"]', function () {
var $clone = $row.clone(true);
$container.append($clone);
$clone.find('input[name]').eq(0).trigger('focus');
})
.on('click', '[data-action="remove"]', function () {
var $parent = $(this).closest('[data-item="set"]');
$totalsum.val($totalsum.val() - $parent.find('[name="sum[]"]').val());
$parent.remove();
})
.on('input', '[name="num[]"], [name="price[]"]', function () {
var $item = $(this),
$parent = $item.closest('[data-item="set"]'),
cost = parseFloat($parent.find('[name="num[]"]').val()),
amount = parseFloat($parent.find('[name="price[]"]').val());
$item.val($item.val().replace(/[^\d\.]/g, '').replace(/^\.+/g, '0.').replace(/^(\d+\.\d+)\.[\d\.]*$/g, '$1'));
if (isFinite(cost) && isFinite(amount)) {
var $sum = $parent.find('[name="sum[]"]'),
prev = parseFloat($sum.val()) || 0,
next = (cost * amount).toFixed(2),
totalPrev = parseFloat($totalsum.val()) || 0;
$totalsum.val((totalPrev + parseFloat(next) - prev).toFixed(2));
$sum.val(next);
}
});
});
мне нужно чтобы все значениея прописывались в value, чтобы передать их в php. Как это сделать? И еще хотелось бы чтобы поле № автоматически при добавлении нового поля присваивался порядковый номер (1,2,3 и т.д.) Как это можно реализовать подскажите? |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
То же самое можно сказать и о поле name="sum[]" - это какую же сумму нужно рассчитывать на клиенте, отправлять на север для сохранения в базе, если такие данные как количество и цена никогда не являлись величинами постоянными? Я выбрасываю эти поля из данных, и все что нужно делать на клиенте, это: - клонировать родительский узел - найти в клоне поля и очистить их значения - у кнопки удаления удалить класс remove, ибо этому классу по умолчанию указано быть невидимым, так как нельзя удалять из формы поля, если их набор в ней единственный - вставить клон в родительский узел (в примере, это добавленный id="parent-box"), ему же делегируется и обработка кнопок удаления/добавления полей. Как видите, если выполнить, отправив форму (добавлено для примера), то все добавленные наборы отправляются и ничего не пропадает.
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<style>
.remove {
display: none;
}
</style>
<script type="text/javascript">
$(function() {
$('#parent-box').on('click', 'a', function(e) {
e.preventDefault();
var src = $(this), dst = src.closest('.row');
if(src.hasClass('add')) {
dst.clone()
.find('input').val('')
.end()
.find('a').removeClass('remove')
.end()
.appendTo(e.delegateTarget)
} else dst.remove();
});
$('form').submit(function(e) {
e.preventDefault();
alert(JSON.stringify($(this).serializeArray(), null, 4))
})
});
</script>
</head>
<body>
<form>
<div id="parent-box">
<div class="row">
<div data-container="set">
<div class="row p-2" data-item="set">
<div class="col-4"> <input type="text" name="name[]" value=""></div>
<div class="col-1"> <input type="text" name="num[]" value=""></div>
<div class="col-2"> <input type="text" name="price[]" value=""></div>
<div class="col-2"> <a type="button" data-action="remove" class="remove">[-]</a>
<a type="button" data-action="add" class="add">[+]</a>
</div>
</div>
</div>
</div>
</div>
<button>GO</button>
</form>
</body>
</html>
Но можно и "нумерацией" на клиенте заняться, но с совсем иной целью. Если на сервере при добавлении в базу используют ненумерованные метки, то пришедший массив данных:
Array
(
[name] => Array
(
[0] => value
[1] => value
.....
)
[num] => Array
(
[0] => value
[1] => value
.....
)
[price] => Array
(
[0] => value
[1] => value
.....
)
)
несложно преобразовать в массив для пакетной записи, как $post = array_map(null, $_POST['name'], $_POST['num'], $_POST['price']); получив массив:
Array
(
[0] => Array
(
[0] => value
[1] => value
[2] => value
)
[1] => Array
(
[0] => value
[1] => value
[2] => value
)
.....
)
Но данные подлежат обязательной фильтрации, и производить ее с таким набором хоть и можно, но неудобно, а если работать с именованными метками (PDO), то такой набор не годится. Но можно именовать поля так (это у полей по умолчанию): name="data[0][name]" name="data[0][num]" name="data[0][price]" код добавления полей заменить на:
if(src.hasClass('add')) {
var i = Date.now();
dst.clone()
.find('input').each(function() {
this.value = '';
this.name = this.name.replace(/\d+/, i)
})
.end()
.find('a').removeClass('remove')
.end()
.appendTo(e.delegateTarget)
} else dst.remove();
то на сервере массив данных уже будет вот таким:
Array
(
[data] => Array
(
[0] => Array
(
[name] => value
[num] => value
[price] => value
)
[1601149425635] => Array
(
[name] => value
[num] => value
[price] => value
)
[1601149432956] => Array
(
[name] => value
[num] => value
[price] => value
)
.....
)
)
получаем $_POST['data'] для дальнейшей работы с данными, и эта структура выгоднее. Здесь метка времени используется как индекс вложенных массивов, что проще чем вычислять какой-то номер, а на сервере он не имеет никакого практического значения. |
| Часовой пояс GMT +3, время: 02:49. |