Сообщение от l30
|
в php попадают значения только из первой строки, которая по дефолту появляется
|
Чего-то не то. Давайте так - данные уж точно будут писаться в базу, и такой переданный массив выгоднее писать в нее в пакетном режиме (многострочная вставка). Ограничения в таком режиме накладываются не на количество строк, а на их общий размер, и определяется sql-параметром max_allowed_packet. А учитывая то, что в базе каждая запись должна иметь свой уникальный идентификатор и формирование такового, это есть сам механизм SQL, а никак не нумерация клиентом, и записи в базу не только добавляются, но могут и удаляться из нее, наличие в ваших данных поля name="str[]", это нечто непонятное и никчемное.
То же самое можно сказать и о поле 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'] для дальнейшей работы с данными, и эта структура выгоднее. Здесь метка времени используется как индекс вложенных массивов, что проще чем вычислять какой-то номер, а на сервере он не имеет никакого практического значения.