我在我的 django 项目中使用了 Inlineformset
,但我必须使用我自己的 js 来增加表单!但我没有找到任何方法让它工作
这是我的models.py
class Invoice(models.Model):
seller = models.ForeignKey(User,on_delete=models.CASCADE)
customer = models.CharField(max_length=50)
items = models.ManyToManyField(Item,through='InvoiceItem')
class InvoiceItem(models.Model):
item = models.ForeignKey(Item,on_delete=models.CASCADE)
invoice = models.ForeignKey(CustomerInvoice,on_delete=models.CASCADE,related_name='invoice')
quantity = models.IntegerField()
price = models.DecimalField(max_digits=20,decimal_places=3)
cash = models.DecimalField(max_digits=20,decimal_places=3)
discount = models.DecimalField(max_digits=20,decimal_places=3)
这段代码是我的 views.py ,我使用了基于类的视图
class CreateClientInvoiceView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
model = CustomerInvoice
form_class = ClientInvoiceForm
template_name = 'invoiceapp/create_invoice.html'
def get_context_data(self,*args,**kwargs):
data = super().get_context_data(*args,**kwargs)
if self.request.POST:
data['items'] = CustomerInvoiceInlineFormset(self.request.POST)
data['items'].full_clean()
else:
data['items'] = CustomerInvoiceInlineFormset()
return data
def form_valid(self, form):
res = super().form_valid(form)
self.object = form.save()
context = self.get_context_data()
items = context['items']
with transaction.atomic:
form.instance.seller = self.request.user
if form.is_valid() and items.is_valid() and items.cleaned_data !={}:
items.instance = self.object
items.save()
form.save()
else:
return render(self.request,self.template_name,context)
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('invoiceapp:customer-invoice',kwargs={'pk':self.object.pk})
这是我的 html + js 代码
{% extends 'base.html' %}
{% load widget_tweaks %}
{% load static %}
{% block title %}
create new invoice
{% endblock %}
{% block content %}
<form method="POST">{% csrf_token %}
{{items.management_form}}
<div class="w-full md:w-11/12 mx-auto realative p-2 bg-gray-200 invoice" style="direction: ltr !important;">
<div class="p-1 pr-2 pb-1 text-xs border border-black rounded-lg flex flex-wrap">
<div class="flex w-8/12 lg:w-9/12">
<div class="w-10/12 ml-8 border-b border-gray-600 border-dotted">
{{form.customer | add_class:'bg-transparent w-full text-right focus:outline-none'}}
</div>
<div class="">
: ناو
</div>
</div>
</div>
<!-- table -->
<div class="mt-1 border border-black">
<!-- header -->
<div class="flex flex-wrap grayBG text-sm text-white">
<div class="w-1/12 text-center border-r">
<i class="fas fa-cog"></i>
</div>
<div class="w-2/12 border-r text-center">
total price
</div>
<div class="w-2/12 border-r text-center">
discount
</div>
<div class="w-1/12 border-r text-center">
cash
</div>
<div class="w-1/12 border-r text-center">
loan
</div>
<div class="w-1/12 border-r text-center">
price
</div>
<div class="w-2/12 border-r text-center">
quantity
</div>
<div class="w-2/12 border-r text-center">
product
</div>
</div>
<!-- inputs -->
<div id="allInp">
<div class="flex flex-wrap grayBG text-sm text-black inp">
<div class="w-1/12 border-r">
</div>
<div class="w-2/12 p-2 border-r text-center">
<input type="number" class="totalSumField rounded-lg focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center">
<input type="text" onkeyup="totalSum()" class="rounded-lg discount focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg cash focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg loan focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg price focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg quantity focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center">
<datalist id="jor">
<option value="test">
<option value="test">
<option value="test">
<option value="test">
<option value="test">
</datalist>
<input type="text" list="jor" class="w-full rounded-lg focus:outline-none py-1">
</div>
</div>
</div>
<div class="flex flex-wrap grayBG justify-between text-sm mt-2 text-black">
<button class=" grayBG border border-white focus:outline-none text-white m-2 rounded-lg py-1 px-4 text-sm" id="addRow">
add new row <i class="fas fa-plus"></i>
</button>
<div class="w-6/12 flex">
<div class="w-6/12 p-2 border-r text-center">
<p class="mb-2 text-white">total invoice price </p>
<input type="number" id="total" class="rounded-lg focus:outline-none py-1 w-full text-center" placeholder="total invoice price">
</div>
<div class="w-6/12 p-2 border-r text-center">
<p class="mb-2 text-white">total loan</p>
<input type="number" id="loan" class="rounded-lg focus:outline-none py-1 w-full text-center" placeholder="loan">
</div>
</div>
</div>
<!-- clone -->
<div class="hidden">
<div class="inp flex flex-wrap grayBG text-sm text-black" id="inputs">
<div class="w-1/12 border-r flex flex-wrap justify-center items-center">
<button id="removeRow" class="bg-white rounded-lg text-red-500 px-3">
<i class="fas fa-trash"></i>
</button>
</div>
<div class="w-2/12 p-2 border-r text-center">
<input type="text" class="rounded-lg totalSumField focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center">
<input type="text" onkeyup="totalSum()" class="rounded-lg focus:outline-none discount py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg cash focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg loan focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg price focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg quantity focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center">
<datalist id="jor">
<option value="test">
<option value="test">
<option value="test">
<option value="test">
<option value="test">
</datalist>
<input type="text" list="jor" class="w-full rounded-lg focus:outline-none py-1">
</div>
</div>
</div>
</div>
</div>
<div class="w-6/12 text-center mt-1 mx-auto mb-6">
<button type="submit" class= w-full bg-white text-gray-900" id="print">print</button>
</div>
</form>
</div>
</div>
</body>
</html>
<script>
$('#print').click(function(){
$('.invoice').printThis();
})
$("#addRow").click(function () {
totalSum();
var html = $("#inputs").clone();
$('#allInp').append(html);
});
$(document).on('click', '#removeRow', function () {
$(this).closest('#inputs').remove();
totalSum();
});
function counting(result) {
document.getElementById("total").value= result;
}
function countingloan(result) {
document.getElementById("loan").value= result;
}
counting(0);
countingloan(0);
function totalSumField () {
let inp = document.querySelectorAll("#allInp > .inp");
let result=0;
for(let i=0;i<inp.length;i++){
let price=inp[i].getElementsByClassName("price")[0].value;
let quantity=inp[i].getElementsByClassName("quantity")[0].value;
let cash=inp[i].getElementsByClassName("cash")[0].value;
let discount=inp[i].getElementsByClassName("discount")[0].value;
inp[i].getElementsByClassName("totalSumField")[0].value=(price*quantity)-discount;
inp[i].getElementsByClassName("loan")[0].value=((price*quantity)-discount)-cash;
}
}
function totalSum () {
let inp = document.querySelectorAll("#allInp > .inp");
let result=0;
let loan=0;
for(let i=0;i<inp.length;i++){
let price=inp[i].getElementsByClassName("price")[0].value;
let quantity=inp[i].getElementsByClassName("quantity")[0].value;
let cash=inp[i].getElementsByClassName("cash")[0].value;
let discount=inp[i].getElementsByClassName("discount")[0].value;
result+=(price*quantity)-discount;
loan+=((price*quantity)-discount)-cash;
}
countingloan(loan);
counting(result)
totalSumField()
}
</script>
{% endblock %}
问题就在这里我想制作我自己的 html 和 js 而不是使用 jquery.formset.js
因为当有人写价格和数量时我必须这样做,然后它会自动将它们相乘并且在一个字段中写下总价,现在我想知道如何添加输入字段以获得我期望的结果?
这项工作仅适用于第一种形式
<div id="allInp">
{% for item in items.forms %}
{{item.id}}
<div class="flex flex-wrap grayBG text-sm text-black inp">
<div class="w-1/12 border-r">
</div>
<div class="w-2/12 p-2 border-r text-center">
<input type="number" class="totalSumField rounded-lg focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center">
{{item.discount | add_class:'rounded-lg discount focus:outline-none py-1 w-full'}}
</div>
<div class="w-1/12 p-2 border-r text-center ">
{{item.cash|add_class:'rounded-lg cash focus:outline-none py-1 w-full'}}
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg qarz focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
{{item.price | add_class:'rounded-lg price focus:outline-none py-1 w-full'}}
</div>
<div class="w-2/12 p-2 border-r text-center ">
{{item.quantity | add_class:'rounded-lg quantity focus:outline-none py-1 w-full'}}
</div>
<div class="w-2/12 p-2 border-r text-center">
{{item.item|add_class:'w-full rounded-lg focus:outline-none py-1'}}
</div>
</div>
{% endfor %}
</div>
<div class="hidden">
<div class="inp flex flex-wrap grayBG text-sm text-black" id="inputs">
<div class="w-1/12 border-r flex flex-wrap justify-center items-center">
<button id="removeRow" class="bg-white rounded-lg text-red-500 px-3">
<i class="fas fa-trash"></i>
</button>
</div>
<div class="w-2/12 p-2 border-r text-center">
<input type="text" class="rounded-lg totalSumField focus:outline-none py-1 w-full">
</div>
<div class="w-2/12 p-2 border-r text-center">
{{item.discount | add_class:'rounded-lg discount focus:outline-none py-1 w-full'}}
</div>
<div class="w-1/12 p-2 border-r text-center ">
{{item.cash|add_class:'rounded-lg cash focus:outline-none py-1 w-full'}}
</div>
<div class="w-1/12 p-2 border-r text-center ">
<input type="number" onkeyup="totalSum()" class="rounded-lg qarz focus:outline-none py-1 w-full">
</div>
<div class="w-1/12 p-2 border-r text-center ">
{{item.price | add_class:'rounded-lg price focus:outline-none py-1 w-full'}}
</div>
<div class="w-2/12 p-2 border-r text-center ">
{{item.quantity | add_class:'rounded-lg quantity focus:outline-none py-1 w-full'}}
</div>
<div class="w-2/12 p-2 border-r text-center">
{{item.item|add_class:'w-full rounded-lg focus:outline-none py-1'}}
</div>
</div>
</div>
非常感谢您的帮助,请让我知道 最问候..