I am trying to modify a sale in which I have this view:
views.py
class VentaUpdate(UpdateView):
model = Venta
template_name = 'venta/venta_form.html'
form_class = VentaForm
success_url = reverse_lazy('venta:ventas_listar')
def get_context_data(self, **kwargs):
data = super(VentaUpdate, self).get_context_data(**kwargs)
if self.request.POST:
data['detalleformset'] = DetalleFormSet(self.request.POST, instance=self.object)
else:
data['detalleformset'] = DetalleFormSet(instance=self.object)
return data
def form_valid(self, form):
context = self.get_context_data()
detalleformset = context['detalleformset']
with transaction.atomic():
self.object = form.save()
if detalleformset.is_valid():
detalleformset.instance = self.object
detalleformset.save()
return super(VentaUpdate, self).form_valid(form)
It works correctly in these cases: 1.Edit a product (If it was 1 soda change it for 1 water). 2.Add another product (Add another product more) But does not work when you want to remove a product, that is, if the sale is 1 soda and 1 chocolate .. and I want to remove the chocolate from the sale, it does not take it away from me.
forms.py
class DetalleForm(forms.ModelForm):
class Meta:
model = DetalleVenta
fields = [
'producto',
'cantidad',
'subtotal',
]
labels = {
'producto':'Producto',
'cantidad':'Cantidad',
'subtotal':'Subtotal',
}
widgets = {
'producto':forms.Select(attrs={'class':'form-control'}),
'cantidad':forms.NumberInput(attrs={'class':'form-control'}),
'subtotal':forms.NumberInput(attrs={'class':'form-control'}),
}
DetalleFormSet = inlineformset_factory(Venta, DetalleVenta,
form=DetalleForm, extra=1)
And so that the formset is dynamic, that is to be able to add more fields, which I think the error is from javascript but I can not find the error
template
{% extends 'base/base.html' %}
{% load static %}
{% block titulo%} Registrar venta {%endblock%}
{% block contenido %}
<form method="post">
{% csrf_token %}
<div class="col-md-4 form-group">
<label class="font-weight-bold" for="{{form.cliente.name}}">{{form.cliente.label}}</label>
{{form.cliente}}
</div>
<div class="col-md-12">
<h4 class="text-left">Detalle de venta: </h4>
{{ detalleformset.management_form }}
<table class="table table-striped">
<thead>
<tr>
<th>Producto</th>
<th>Cantidad</th>
<th>Precio unitario</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
{% for form in detalleformset.forms %}
<tr>
{{ form.id }}
<td>{{ form.producto }}</td>
<td width="1em">{{ form.cantidad }}</td>
<td>5.50</td>
<td width="115px">{{ form.subtotal }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button id="add-item" class="btn btn-primary" type="button">Agregar</button>
<button id="remove-item" class="btn btn-danger" type="button">Quitar</button>
<div class="row justify-content-md-end">
<div class="col-md-2">
<label class="font-weight-bold" for="{{form.total.name}}">{{form.total.label}}</label>
{{form.total}}
</div>
</div>
<div class="form-group">
<label class="font-weight-bold" for="{{form.descripcion.name}}">{{form.descripcion.label}}</label>
{{form.descripcion}}
</div>
<div class="col-md-4 offset-md-4">
<button class="btn btn-block btn-lg btn-primary" type="submit">Registrar venta</button>
</div>
</div>
</form>
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function() {
$("#add-item").on("click", addItem);
$("#remove-item").on("click", removeItem);
var total = $("#id_detalleventa-TOTAL_FORMS").val();
if(total<=1){
$("#remove-item").hide();
}
});
function addItem() {
var newElement = $(".table tr:last").clone(true);
var total = $("#id_detalleventa-TOTAL_FORMS").val();
newElement.find(":input").each(function() {
var name = $(this).attr("name").replace("-" + (total-1) + "-", "-" + total + "-");
var id = "id_" + name;
$(this).attr({"name": name, "id": id}).val("");
});
total++;
$("#id_detalleventa-TOTAL_FORMS").val(total);
$(".table tr:last").after(newElement);
if (total > 1) {
$("#remove-item").show();
}
}
function removeItem() {
var lastElement = $(".table tr:last");
var total = $("#id_detalleventa-TOTAL_FORMS").val();
$(lastElement).remove();
total--;
$("#id_detalleventa-TOTAL_FORMS").val(total);
if (total < 2) {
$("#remove-item").hide();
}
}
</script>
{% endblock %}
This javascript guide me of this publication: Use inline - formssets with dynamically created content