#javascript #php #html #forms
#javascript #php #HTML #формы
Вопрос:
У меня есть форма со строками, каждая из которых вычисляет общее количество строк. Эти строки клонируются до числа, необходимого пользователю. Общий итог обновляется по мере заполнения строк.
Единственная проблема заключается в том, что если кто-то добавляет несколько пустых строк перед вводом данных, общий итог не обновляется, пока они не введут данные в последней строке. Если введено слишком много строк, и пользователь решает удалить последнюю строку без ввода данных, общий итог не заполняется. ЕСЛИ после удаления пустой строки они «повторно вводят» данные в последней используемой строке, общий итог затем вычисляется. Но это просто не совсем правильно. Чего мне не хватает?
Пожалуйста, посмотрите фрагмент. (отредактировано с рабочим результатом)
$(document).on("keyup", "[id^='numberunits']", function() {
var total=$("[id^='linetotal']");
var row = $( this ).attr('id').split('_').slice(1);
var qty=$("#numberunits_" row );
var price=$("#priceperunit_" row );
var total=isNaN(parseInt(qty.val()* $("#priceperunit_" row).val())) ? 0 :(qty.val()* $("#priceperunit_" row).val())
var roundedTotal = parseFloat(Math.round(total * 100) / 100).toFixed(2);
$("#linetotal_" row).val(roundedTotal);
if($("#numberunits_" row ).val() !== "" amp;amp; $("#priceperunit_" row).val() !== ""){
$('#btnAdd_1').removeAttr('disabled');
}
var totalVal = 0;
$("[id^='linetotal']").each(function(){
totalVal = parseFloat($(this).val()) ;
});
roundedTotalVal = parseFloat(Math.round(totalVal * 100) / 100).toFixed(2);
$("#grandtotal").val(roundedTotalVal);
});
$(document).on("keyup", "[id^='priceperunit']", function() {
var total=$("[id^='linetotal']");
var row = $( this ).attr('id').split('_').slice(1);
var qty=$("#numberunits_" row );
var price=$("#priceperunit_" row );
var total=isNaN(parseInt(qty.val()* $("#priceperunit_" row).val())) ? 0 :(qty.val()* $("#priceperunit_" row).val())
var roundedTotal = parseFloat(Math.round(total * 100) / 100).toFixed(2);
$("#linetotal_" row).val(roundedTotal);
if($("#numberunits_" row ).val() !== "" amp;amp; $("#priceperunit_" row).val() !== ""){
$('#btnAdd_1').removeAttr('disabled');
}
var totalVal = 0;
$("[id^='linetotal']").each(function(){
totalVal = parseFloat($(this).val()) ;
});
roundedTotalVal = parseFloat(Math.round(totalVal * 100) / 100).toFixed(2);
$("#grandtotal").val(roundedTotalVal);
});
// Cloned Section 1 Script
$('#btnAdd_1').click(function () {
var num = $('.clonedInput_1').length, // Checks to see how many "duplicatable" input fields we currently have
newNum = new Number(num 1), // The numeric ID of the new input field being added, increasing by 1 each time
phpNum = new Number(newNum - 1), // The numeric ID of the new input field being added, increasing by 1 each time
newElem = $('#entry' num).clone().attr('id', 'entry' newNum).fadeIn('slow'); // create the new element via clone(), and manipulate it's ID using newNum value
/* This is where we manipulate the name/id values of the input inside the new, cloned element
Below are examples of what forms elements you can clone, but not the only ones.
There are 2 basic structures below: one for an H2, and one for form elements.
To make more, you can copy the one for form elements and simply update the classes for its label and input.
Keep in mind that the .val() method is what clears the element when it gets cloned. Radio and checkboxes need .val([]) instead of .val('').
*/
// numberunits - text
newElem.find('.label_numberunits').attr('for', 'numberunits_' newNum);
newElem.find('.input_numberunits').attr('id', 'numberunits_' newNum).attr('name', 'purchline[' phpNum '][numberunits]').val('');
// priceperunit - text
newElem.find('.label_priceperunit').attr('for', 'priceperunit_' newNum);
newElem.find('.input_priceperunit').attr('id', 'priceperunit_' newNum).attr('name', 'purchline[' phpNum '][priceperunit]').val('');
// linetotal - text
newElem.find('.label_linetotal').attr('for', 'linetotal_' newNum);
newElem.find('.input_linetotal').attr('id', 'linetotal_' newNum).attr('name', 'purchline[' phpNum '][linetotal]').val('');
// Insert the new element after the last "duplicatable" input field and set focus on first field
$('#entry' num).after(newElem);
$('numberunits_' newNum).focus();
// Enable the "remove" button. This only shows once you have a duplicated section.
$('#btnDel_1').attr('disabled', false);
$('#btnAdd_1').attr('disabled', true);
$("#add_purchase_lines").parsley().destroy();
$('.filled').remove()
$('#add_purchase_lines').parsley();
});
$('#btnDel_1').click(function () {
// Confirmation dialog box. Works on all desktop browsers and iPhone.
if (confirm("Are you sure you wish to remove this section? This cannot be undone."))
{
var num = $('.clonedInput_1').length;
// how many "duplicatable" input fields we currently have
$('#entry' num).slideUp('slow', function () {$(this).remove();
// if only one element remains, disable the "remove" button
if (num -1 === 1)
$('#btnDel_1').attr('disabled', true);
// enable the "add" button
$('#btnAdd_1').attr('disabled', true).prop('value', "add section");});
var totalVal = 0;
$("[id^='linetotal']").each(function(){
totalVal = parseFloat($(this).val()) ;
});
totalVal = totalVal - parseFloat($("#linetotal_" num).val());
roundedTotalVal = parseFloat(Math.round(totalVal * 100) / 100).toFixed(2);
$("#grandtotal").val(roundedTotalVal);
}
return false; // Removes the last section you added
});
// Enable the "add" button
$('#btnAdd_1').attr('disabled', true);
// Disable the "remove" button
$('#btnDel_1').attr('disabled', true);
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.9.2/parsley.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" >
<form id="add_purchase_lines" role="form" method="post" action="" enctype="multipart/form-data" data-parsley-validate>
<!-- BEGINNING OF CLONED SECTION-->
<h4 class="">Purchase Detail</h4>
<div id="entry1" class="clonedInput_1">
<fieldset>
<div class="row">
<div class="form-group col-sm-4" style="margin-bottom: 0px;">
<label class="label_numberunits" for="numberunits_1">Number Units</label>
<input class="input_numberunits form-control" name="purchline[0][numberunits]" id="numberunits_1" type="number" required />
</div>
<div class="form-group col-sm-4" style="margin-bottom: 0px;">
<label class="label_priceperunit" for="priceperunit_1">Price:</label>
<input class="input_priceperunit form-control" name="purchline[0][priceperunit]" id="priceperunit_1" type="number" step="0.01" required /><br />
</div>
<div class="form-group col-sm-4" style="margin-bottom: 0px;">
<label class="label_linetotal" for="linetotal_1">Total:</label>
<input class="input_linetotal form-control" name="purchline[0][linetotal]" id="linetotal_1" type="number" step="0.01" />
</div>
</div>
</fieldset>
</div>
<!-- end #CLONED SECTION -->
<!-- Buttons for Cloning -->
<div class="col-sm-6 col-md-6 col-lg-6">
<button id="btnAdd_1" name="btnAdd_1" class="btn btn-sm btn-info" disabled>Add Line</button>
<button id="btnDel_1" name="btnDel_1" class="btn btn-sm btn-danger">Remove Line</button>
</div>
<div class="row">
<div class="form-group offset-sm-8 col-sm-4">
<label class="label_grandtotal" for="grandtotal">Purchase Total:</label>
<input class="form-control" name="grandtotal" id="grandtotal" type="number" step="0.01" />
</div>
</div>
</form>
Комментарии:
1. Извините, ваш вопрос немного сбивает с толку, так что ваш общий итог вычисляется неправильно?
2. Извините, что не могу быть яснее, это немного странно. Общий итог вычисляется правильно. Вы должны поиграть с фрагментом. Для восстановления — поместите данные в первую строку. Общий итог в порядке. Добавьте строку, введите данные, итог в порядке. Добавьте 3 строки без ввода данных — общий итог перестанет работать.
3. Сделайте так, чтобы предыдущие входные данные были заполнены, чтобы добавить больше входных данных
4. Мне потребовалось некоторое время, но я это сделал. Это должно было прийти мне в голову, но, поскольку я один из тех людей, которые добавляют кучу строк перед выполнением ввода, этого не произошло. Теперь я только что понял, что, поскольку мои итоги меняются при вводе, удаление заполненной строки уже оставляет меня с неправильным общим итогом. Иногда я действительно ненавижу кодирование….
5. Спасибо за указания. Фрагмент обновлен и полностью функционален. Возможно, это не лучший способ сделать все это, но это работает!