Динамически создаваемая форма с подсчетом суммы
Добрый день!
Подскажите есть динамически создаваемая форма: <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, время: 10:22. |