#javascript #html #jquery
Вопрос:
Как я могу поместить описание и сумму элементов счета-фактуры в квитанцию внизу (аналогично дате оплаты), это имеет несколько динамических строк ввода и также может быть удалено.
Я думал запустить счетчик, и после каждой добавленной строки он будет увеличивать счетчик, не знаю, лучший ли это способ сделать
var generalPreset = [{ description: "This is item 1", amount: "30.00" }, { description: "This is item 2", amount: "45.00" }]; var discountPresets = [{ description: "Siblings discount" }, { description: "Annual relief" }]; // receipt var receipt = new Object(); $('#duedate').change(function() { receipt.duedate = $(this).val(); $('.invoice-preview-card-duedate-value').text(receipt.duedate); }); // for adding invoice item $('.add-invoice-item').click(function() { $('.inv-table-body').append(`<div class="body-row row m-0"> <div class="px-2 col-3"> <select name="item_type[]" class="form-control invoiceType" required> <option value="newitem">New Item</option> <option value="presetitem">Present Item</option> <option value="discount">Discount</option> <option value="subsidy">Subsidy</option> </select> </div> <div class="px-2 col-6 item-description" style="display: flex;"> <input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 1"> </div> <div class="px-2 col-2"> <input type="number" class="form-control invoiceItemAmount" name="amount[]" value="" placeholder="0" required> </div> <div class="col-1 del-icon-container"><button class="del-invoice-item">Del</button></div> </div> `); }); // for deleting invoice item $(document).on('click', '.del-invoice-item', function() { $(this).closest('.body-row').remove(); }); // for description of invoice type change $(document).on('change', '.invoiceType', function() { let $field = $(this); let invoiceType = $field.val(); // :selected not needed if (invoiceType === 'newitem') { $field.closest('.body-row').find('.item-description').html(`<input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 1">`); } else if (invoiceType === 'presetitem') { var options; $.each(generalPreset, function(key, value) { options = options '<option value="' value.amount '">' value.description '</option>'; }); $field.closest('.body-row').find('.item-description').html(` <select class="form-control general-presets" name="description[]" required style="flex: 1"> <option></option> ` options ` </select> `); } else if (invoiceType === 'discount') { var dicountOptions; $.each(discountPresets, function(key, value) { dicountOptions = dicountOptions '<option>' value.description '</option>'; }); $field.closest('.body-row').find('.item-description').html(`<div class="mr-2 divForCalculation" style="flex: 1"> <div style="display: flex" class="calculation-container"> <div class="mr-2" style="flex: 1"> <div class="input-group my-group"> <input type="text" class="form-control discountAmount" name="snpid" placeholder="0"> <select id="lunch" class="form-control amountOrPercent" style="padding: 4px;"> <option value="amount">
lt;/option>
<option value="percentage">%</option>
</select>
</div>
</div>
</div>
</div>
<select class="form-control discount-presets" name="description[]" required style="flex: 2">
<option></option>
`
dicountOptions
`
</select>
`);
} else if (invoiceType === 'subsidy') {
$field.closest('.body-row').find('.item-description').html(`<div class="mr-2 divForCalculation" style="flex: 1">
<div style="display: flex" class="calculation-container">
<div class="mr-2" style="flex: 1">
<div class="input-group my-group">
<input type="text" class="form-control discountAmount" name="snpid" placeholder="0">
<select id="lunch" class="form-control amountOrPercent" style="padding: 4px;">
<option value="amount">lt;/option>
<option value="percentage">%</option>
</select>
</div>
</div>
</div>
</div>
<input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 2">
`);
}
});// populate invoice amount by preset items
$(document).on('change', '.general-presets', function() {
var presetSelectValue = $(this).find(":selected").val();
$(this).closest(".body-row").find(".invoiceItemAmount").val(presetSelectValue);
});// Percentage or Amount structure change
$(document).on('change', '.amountOrPercent', function() {
var amountOrPercent = $(this).find(":selected").val();
if (amountOrPercent == 'amount') {
$(this).closest('.body-row').find('.extraForPercentage').remove();
$(this).closest('.body-row').find('.amountOrPercent').css('padding', '4px');
$(this).closest('.body-row').find('.divForCalculation').css('flex', '1');
} else if (amountOrPercent == 'percentage') {
$(this).closest('.body-row').find('.divForCalculation').css('flex', '2');
$(this).closest('.body-row').find('.amountOrPercent').css('padding', '0');
$(this).closest('.body-row').find('.calculation-container').append(`<div class="extraForPercentage" style="flex: 1">
<span class="mr-2 pt-2">Of</span>
<div style="display: inline;">
<input type="text" class="form-control totalof" placeholder="0" required style="display: inline; width: 60%;" value="">
</div>
</div>
`);
}
});$(document).on("change keyup keypress", ".discountAmount, .totalof , .amountOrPercent", function() {
var selector = $(this).closest(".divForCalculation") //get closest divvar discountAmount = 0;
var discountPercentage = 0;
var totalof = 0;
var result = 0;
discountAmount = selector.find(".discountAmount").val();
totalof = selector.find(".totalof").val();//added cond if not visible
if (totalof == null || totalof == 0 || !selector.find(".totalof").is(":visible")) {
totalof = 0;
//change value depending on select values
result = selector.find(".amountOrPercent").val() == "amount" ? -discountAmount : 0;
} else {
result = -parseFloat((parseInt(totalof) / 100 * parseInt(discountAmount)));
}//use nextAll..
// selector.nextAll('.invoiceItemAmount').val(result);
$(this).closest(".body-row").find(".invoiceItemAmount").val(result);
});.invoice-preview-card-header { padding: 44px 24px; } .invoice-preview-card-body { padding: 18px 24px; background-color: #ebf2ef; } .invoice-preview-card-duedate-value { font-weight: bold; } .invoice-preview-card-table { margin-top: 12px; } .invoice-preview-card-table-header { padding: 10px 0; border-bottom: 1px solid #d8d8d8 } .invoice-preview-card-table-column1 { width: 75%; display: inline-block; } .invoice-preview-card-table-column2 { width: 20%; display: inline-block; } .invoice-preview-card-table-body { border-bottom: 1px solid #d8d8d8; } .invoice-preview-card-table-row { padding-top: 12px; } .invoice-preview-card-table-row:last-child { padding-bottom: 12px; } .invoice-preview-card-table-body > .invoice-preview-card-table-row { font-weight: bold; } .invoice-preview-card-table-column2 { text-align: right; } .invoice-preview-card-table-footer { padding: 10px 0; } .invoice-preview-card-table-footer > .invoice-preview-card-table-column2 { font-weight: normal; } .invoice-preview-card-table-footer > .invoice-preview-card-table-column2 span{ font-weight: bold; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="form-card"> <div class="row"> <div class="form-group col-md-4"> <label for="">Invoice Due Date</label> <input type="date" class="form-control" name="duedate" id="duedate"> </div> <div class="form-group col-md-8"> <div class="row mr-0"> <label for="" class="col-12 pl-0">Date of Service(optional)</label> <input type="date" class="form-control col" name="service_start" id=""> <span class="service-span">to</span> <input type="date" class="form-control col" name="service_end" id=""> </div> </div> </div> <hr> <h5>Invoice Details</h5> <div class="card" style="border: 1px solid #d8d8d8;"> <div class="inv-table"> <div class="inv-table-head"> <div class="head-row row m-0"> <div class="px-2 col-3">Row</div> <div class="px-2 col-6">Description</div> <div class="px-2 col-2">Amount</div> <div class="px-2 col-1"></div> </div> </div> <div class="inv-table-body"> <div class="body-row row m-0"> <div class="px-2 col-3"> <select name="invoice_type" class="form-control invoiceType" required> <option value="newitem">New Item</option> <option value="presetitem">Preset Item</option> <option value="discount">Discount</option> <option value="subsidy">Subsidy</option> </select> </div> <div class="px-2 col-6 item-description" style="display: flex;"> <input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 1"> </div> <div class="px-2 col-2"> <input type="number" class="form-control invoiceItemAmount" name="amount[]" placeholder="0" value="" required> </div> <div class="col-1 del-icon-container"><i class="fas fa-trash"></i></div> </div> </div> <div class="inv-table-footer"> <div class="row"> <div class="col-6"> <span class="add-invoice-item"> <i class="fas fa-plus-circle"></i> ADD INVOICE ITEM </span> </div> <div class="col-6"> <span class=""> <b>Total: </b>
lt;span class="tatalAmountShow">0</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div><br><br>
<hr>
<br><div class="invoice-preview-card-body">
<div class="invoice-preview-card-duedate">
Due Date: <span class="invoice-preview-card-duedate-value"></span>
</div>
<div class="invoice-preview-card-duedate">
Invoice Period: <span class="invoice-preview-card-duedate-value">May 1, 2021 - May 10, 2021</span>
</div>
<div class="invoice-preview-card-table">
<div class="invoice-preview-card-table-header">
<div class="invoice-preview-card-table-column1">
Description
</div>
<div class="invoice-preview-card-table-column2">
Amount
</div>
</div>
<div class="invoice-preview-card-table-body">
<div class="invoice-preview-card-table-row">
<div class="invoice-preview-card-table-column1">
This is item 1
</div>
<div class="invoice-preview-card-table-column2">
$30
</div>
</div>
<div class="invoice-preview-card-table-row">
<div class="invoice-preview-card-table-column1">
This is item 2
</div>
<div class="invoice-preview-card-table-column2">
$45
</div>
</div>
</div>
<div class="invoice-preview-card-table-footer">
<div class="invoice-preview-card-table-column1">
</div>
<div class="invoice-preview-card-table-column2">
Total <span>$0</span>
</div>
</div>
</div>
</div>
Комментарии:
1. Когда
Description
появилось%
поле выбора, что должно быть в описании счета-фактуры ?2. Он должен печатать только описание и значение суммы из входных данных счета-фактуры.
%
есть только скидка и субсидия, так что это только для расчета. Эти значения не поступают в квитанцию.3. Но, когда пользователь выбирает опцию скидки, нет поля «Описание»? Потому что я вижу, что у всех остальных трех вариантов есть поле desc, но не для скидки . Можете ли вы привести пример вывода всех опций ?
4. @Swati Я добавил пример вывода, субсидия также совпадает со скидкой, но субсидия-это текстовое поле вместо выпадающего списка. Я не показывал этого в примере
Ответ №1:
Вы можете поместить всю часть расчета в отдельную функцию и вызывать ее при необходимости .Внутри этой функции вы можете использовать .each
цикл для перебора body-row
, затем получить значения внутри этого div и передать их в тег тела счета .
Демонстрационный код :
var generalPreset = [{ description: "This is item 1", amount: "30.00" }, { description: "This is item 2", amount: "45.00" }]; var discountPresets = [{ description: "Siblings discount" }, { description: "Annual relief" }]; // receipt var receipt = new Object(); $('#duedate').change(function() { receipt.duedate = $(this).val(); $('.invoice-preview-card-duedate-value').text(receipt.duedate); }); // for adding invoice item $('.add-invoice-item').click(function() { $('.inv-table-body').append(`<div class="body-row row m-0"> <div class="px-2 col-3"> <select name="item_type[]" class="form-control invoiceType" required> <option value="newitem">New Item</option> <option value="presetitem">Present Item</option> <option value="discount">Discount</option> <option value="subsidy">Subsidy</option> </select> </div> <div class="px-2 col-6 item-description" style="display: flex;"> <input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 1"> </div> <div class="px-2 col-2"> <input type="number" class="form-control invoiceItemAmount" name="amount[]" value="" placeholder="0" required> </div> <div class="col-1 del-icon-container"><button class="del-invoice-item">Del</button></div> </div> `); }); // for deleting invoice item $(document).on('click', '.del-invoice-item', function() { $(this).closest('.body-row').remove(); build_invoice() //call this }); // for description of invoice type change $(document).on('change', '.invoiceType', function() { let $field = $(this); let invoiceType = $field.val(); // :selected not needed if (invoiceType === 'newitem') { $field.closest('.body-row').find('.item-description').html(`<input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 1">`); } else if (invoiceType === 'presetitem') { var options; $.each(generalPreset, function(key, value) { options = options '<option value="' value.amount '">' value.description '</option>'; }); $field.closest('.body-row').find('.item-description').html(` <select class="form-control general-presets" name="description[]" required style="flex: 1"> <option></option> ` options ` </select> `); } else if (invoiceType === 'discount') { var dicountOptions; $.each(discountPresets, function(key, value) { dicountOptions = dicountOptions '<option>' value.description '</option>'; }); $field.closest('.body-row').find('.item-description').html(`<div class="mr-2 divForCalculation" style="flex: 1"> <div style="display: flex" class="calculation-container"> <div class="mr-2" style="flex: 1"> <div class="input-group my-group"> <input type="text" class="form-control discountAmount" name="snpid" placeholder="0"> <select id="lunch" class="form-control amountOrPercent" style="padding: 4px;"> <option value="amount">
lt;/option>
<option value="percentage">%</option>
</select>
</div>
</div>
</div>
</div>
<select class="form-control discount-presets" name="description[]" required style="flex: 2">
<option></option>
`
dicountOptions
`
</select>
`);
} else if (invoiceType === 'subsidy') {
$field.closest('.body-row').find('.item-description').html(`<div class="mr-2 divForCalculation" style="flex: 1">
<div style="display: flex" class="calculation-container">
<div class="mr-2" style="flex: 1">
<div class="input-group my-group">
<input type="text" class="form-control discountAmount" name="snpid" placeholder="0">
<select id="lunch" class="form-control amountOrPercent" style="padding: 4px;">
<option value="amount">lt;/option>
<option value="percentage">%</option>
</select>
</div>
</div>
</div>
</div>
<input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 2">
`);
}});
// populate invoice amount by preset items
$(document).on('change', '.general-presets', function() {
var presetSelectValue = $(this).find(":selected").val();
$(this).closest(".body-row").find(".invoiceItemAmount").val(presetSelectValue);
build_invoice() //call this
});// Percentage or Amount structure change
$(document).on('change', '.amountOrPercent', function() {
var amountOrPercent = $(this).find(":selected").val();
if (amountOrPercent == 'amount') {
$(this).closest('.body-row').find('.extraForPercentage').remove();
$(this).closest('.body-row').find('.amountOrPercent').css('padding', '4px');
$(this).closest('.body-row').find('.divForCalculation').css('flex', '1');
} else if (amountOrPercent == 'percentage') {
$(this).closest('.body-row').find('.divForCalculation').css('flex', '2');
$(this).closest('.body-row').find('.amountOrPercent').css('padding', '0');
$(this).closest('.body-row').find('.calculation-container').append(`<div class="extraForPercentage" style="flex: 1">
<span class="mr-2 pt-2">Of</span>
<div style="display: inline;">
<input type="text" class="form-control totalof" placeholder="0" required style="display: inline; width: 60%;" value="">
</div>
</div>
`);
}
});$(document).on("change keyup keypress", ".discountAmount, .totalof , .amountOrPercent", function() {
var selector = $(this).closest(".divForCalculation") //get closest divvar discountAmount = 0;
var discountPercentage = 0;
var totalof = 0;
var result = 0;
discountAmount = selector.find(".discountAmount").val();
totalof = selector.find(".totalof").val();//added cond if not visible
if (totalof == null || totalof == 0 || !selector.find(".totalof").is(":visible")) {
totalof = 0;
//change value depending on select values
result = selector.find(".amountOrPercent").val() == "amount" ? -discountAmount : 0;
} else {
result = -parseFloat((parseInt(totalof) / 100 * parseInt(discountAmount)));
}//use nextAll..
// selector.nextAll('.invoiceItemAmount').val(result);
$(this).closest(".body-row").find(".invoiceItemAmount").val(result);
build_invoice() //call this
});function build_invoice() {
$(".invoice-preview-card-table-body").html("")
var total = 0
console.clear()
//loop through body-row
$(".inv-table-body > .body-row").each(function() {
//because genral slect value="number" that's why text
var desc = $(this).find(".item-description [name*='description']").hasClass("general-presets") ? $(this).find(".item-description [name*='description']").find("option:selected").text() : $(this).find(".item-description [name*='description']").val();
//get amt
var amt = $(this).find(".invoiceItemAmount").val() != "" ? $(this).find(".invoiceItemAmount").val() : 0
//append in body
$(".invoice-preview-card-table-body").append(`<div class="invoice-preview-card-table-row">
<div class="invoice-preview-card-table-column1">
${desc}
</div>
<div class="invoice-preview-card-table-column2">
${amt}
</div>
</div>`)
total = parseFloat(amt) //for total
})
$("#to_inv").text("$" total) //add total}
.invoice-preview-card-header { padding: 44px 24px; } .invoice-preview-card-body { padding: 18px 24px; background-color: #ebf2ef; } .invoice-preview-card-duedate-value { font-weight: bold; } .invoice-preview-card-table { margin-top: 12px; } .invoice-preview-card-table-header { padding: 10px 0; border-bottom: 1px solid #d8d8d8 } .invoice-preview-card-table-column1 { width: 75%; display: inline-block; } .invoice-preview-card-table-column2 { width: 20%; display: inline-block; } .invoice-preview-card-table-body { border-bottom: 1px solid #d8d8d8; } .invoice-preview-card-table-row { padding-top: 12px; } .invoice-preview-card-table-row:last-child { padding-bottom: 12px; } .invoice-preview-card-table-body>.invoice-preview-card-table-row { font-weight: bold; } .invoice-preview-card-table-column2 { text-align: right; } .invoice-preview-card-table-footer { padding: 10px 0; } .invoice-preview-card-table-footer>.invoice-preview-card-table-column2 { font-weight: normal; } .invoice-preview-card-table-footer>.invoice-preview-card-table-column2 span { font-weight: bold; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="form-card"> <div class="row"> <div class="form-group col-md-4"> <label for="">Invoice Due Date</label> <input type="date" class="form-control" name="duedate" id="duedate"> </div> <div class="form-group col-md-8"> <div class="row mr-0"> <label for="" class="col-12 pl-0">Date of Service(optional)</label> <input type="date" class="form-control col" name="service_start" id=""> <span class="service-span">to</span> <input type="date" class="form-control col" name="service_end" id=""> </div> </div> </div> <hr> <h5>Invoice Details</h5> <div class="card" style="border: 1px solid #d8d8d8;"> <div class="inv-table"> <div class="inv-table-head"> <div class="head-row row m-0"> <div class="px-2 col-3">Row</div> <div class="px-2 col-6">Description</div> <div class="px-2 col-2">Amount</div> <div class="px-2 col-1"></div> </div> </div> <div class="inv-table-body"> <div class="body-row row m-0"> <div class="px-2 col-3"> <select name="invoice_type" class="form-control invoiceType" required> <option value="newitem">New Item</option> <option value="presetitem">Preset Item</option> <option value="discount">Discount</option> <option value="subsidy">Subsidy</option> </select> </div> <div class="px-2 col-6 item-description" style="display: flex;"> <input type="text" class="form-control" name="description[]" placeholder="Add Invoice Description" required style="flex: 1"> </div> <div class="px-2 col-2"> <input type="number" class="form-control invoiceItemAmount" name="amount[]" placeholder="0" value="" required> </div> <div class="col-1 del-icon-container"><i class="fas fa-trash"></i></div> </div> </div> <div class="inv-table-footer"> <div class="row"> <div class="col-6"> <span class="add-invoice-item"> <i class="fas fa-plus-circle"></i> ADD INVOICE ITEM </span> </div> <div class="col-6"> <span class=""> <b>Total: </b>
lt;span class="tatalAmountShow">0</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div><br><br>
<hr>
<br><div class="invoice-preview-card-body">
<div class="invoice-preview-card-duedate">
Due Date: <span class="invoice-preview-card-duedate-value"></span>
</div>
<div class="invoice-preview-card-duedate">
Invoice Period: <span class="invoice-preview-card-duedate-value">May 1, 2021 - May 10, 2021</span>
</div>
<div class="invoice-preview-card-table">
<div class="invoice-preview-card-table-header">
<div class="invoice-preview-card-table-column1">
Description
</div>
<div class="invoice-preview-card-table-column2">
Amount
</div>
</div>
<div class="invoice-preview-card-table-body"></div>
<div class="invoice-preview-card-table-footer">
<div class="invoice-preview-card-table-column1">
</div>
<div class="invoice-preview-card-table-column2">
Total <span id="to_inv">$0</span>
</div>
</div>
</div>
</div>
Комментарии:
1. Я создал 2
New Items
, но результат не отображается, он отображается только тогда, когда я выбираю какой-либо предустановленный элемент2. Вам нужно запускать эту функцию всякий раз, когда вам нужно записать событие изменения в desp, а также вызывать эту функцию оттуда .
3. Большое вам спасибо, кстати, мне нравится ваше имя @Swati 🙂