viwes.py
class RestaurantsTransactionView(LoginRequiredMixin,SuccessMessageMixin, View):
template_name = 'restaurants_transaction.html'
def get(self, request):
commom_form = TransactionCommonForm()
item_formset = TransactionItemFormSet()
return render(request, self.template_name, {'common_form': commom_form, 'item_formset': item_formset})
def post(self, request):
common_form = TransactionCommonForm(request.POST)
item_formset = TransactionItemFormSet(request.POST)
if common_form.is_valid() and item_formset.is_valid():
common_data = common_form.cleaned_data
inv_no = common_data['inv_no']
transaction_date = common_data['transaction_date']
from_restaurant = common_data['from_restaurant']
to_restaurant = common_data['to_restaurant']
for item_form in item_formset:
item_data = item_form.cleaned_data
if item_data:
item_code = item_data['item']
sub_item = item_data['sub_item']
pastry_item = item_data['pastry_item']
butcher_item = item_data['butcher_item']
quantity = item_data['quantity']
transaction = Transaction(
inv_no = inv_no,
transaction_date = transaction_date,
from_restaurant = from_restaurant,
to_restaurant= to_restaurant,
item_code = item_code,
sub_recipe_code = sub_item,
pastry_code = pastry_item,
butcher_code = butcher_item,
quantity = quantity
)
transaction.save()
messages.success(request, 'Transaction created successfully!')
return redirect('inventory:restaurant_transaction_create'
)
else:
return render(request, self.template_name, {'commom_form': common_form, 'item_formset': item_formset})
forms.py
class TransactionCommonForm(forms.ModelForm):
from_restaurant = forms.ChoiceField(choices=FROM_RES, widget=forms.RadioSelect(attrs={'class': 'form-control'}))
to_restaurant = forms.ChoiceField(choices=TO_RES, widget=forms.RadioSelect(attrs={'class': 'form-control'}))
class Meta:
model = Transaction
fields = ['inv_no', 'from_restaurant', 'to_restaurant', 'transaction_date']
widgets = {
'inv_no': forms.NumberInput(attrs={'class': 'form-control'}),
'transaction_date': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'date', 'format': '%d-%m-%Y'}),
}
labels = {
'inv_no': 'Invoice Number',
'transaction_date': 'Transaction Date',
}
def clean(self):
cleaned_data = super().clean()
inv_no = cleaned_data.get('inv_no')
if not inv_no:
raise ValidationError('Invoice number is required.')
return cleaned_data
class TransactionItemForm(forms.Form):
item_code = forms.ModelChoiceField(
queryset=Fooditems.objects.all(),
empty_label='Select item',
required=False
)
sub_recipe_code = forms.ModelChoiceField(
queryset=AwDishes.objects.all(),
empty_label='Select sub item',
required=False
)
pastry_code = forms.ModelChoiceField(
queryset=pastryItem.objects.all(),
empty_label='Select pastry item',
required=False
)
butcher_code = forms.ModelChoiceField(
queryset=ButcherItem.objects.all(),
empty_label='Select butcher item',
required=False
)
quantity = forms.DecimalField(
label='Quantity',
required=True,
min_value=0
)
def __init__(self, *args, **kwargs):
super(TransactionItemForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False # Since it's part of a formset
self.helper.layout = Layout(
Field('item_code', css_class='form-control select2'),
Field('sub_recipe_code', css_class='form-control select2'),
Field('pastry_code', css_class='form-control select2'),
Field('butcher_code', css_class='form-control select2'),
Field('quantity', css_class='form-control'),
)
def clean(self):
cleaned_data = super().clean()
item = cleaned_data.get('item_code')
sub_item = cleaned_data.get('sub_recipe_code')
pastry_item = cleaned_data.get('pastry_code')
butcher_item = cleaned_data.get('butcher_code')
quantity = cleaned_data.get('quantity')
if not item and not sub_item and not pastry_item and not butcher_item:
raise ValidationError('At least one item is required.')
if not quantity:
raise ValidationError('Quantity is required.')
return cleaned_data
TransactionItemFormSet = formset_factory(TransactionItemForm, extra=1)
template
<!-- restaurants_transaction.html -->
{% extends 'base/base.html' %}
{% load crispy_forms_tags %}
{% load static %}
<head>
<title>Add Transaction</title>
<!-- Include your CSS files -->
<link rel="stylesheet" href="{% static 'css/home.css' %}">
<link rel="stylesheet" href="{% static 'css/abd_Elwahab.css' %}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
</head>
{% block content %}
<div class="container" style="display: block; justify-content: center; align-items: center; background-color: #e9e5e5; border-radius: 12px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width:900px; padding:10px;">
<h3>Add Transaction</h3>
<form method="post">
{% csrf_token %}
{{ common_form|crispy }}
<h4>Items</h4>
{{ item_formset.management_form }}
<div id="item-formset">
{% for form in item_formset %}
<div class="item-form">
{{ form|crispy }}
<button type="button" class="remove-item btn btn-danger">Remove</button>
</div>
{% endfor %}
</div>
<button type="button" id="add-item" class="btn btn-secondary">Add Item</button>
<br><br>
<button type="submit" class="btn btn-info">Submit</button>
<a href="{% url 'home' %}" class="btn btn-light">Cancel</a>
</form>
</div>
<!-- Empty form template for JavaScript cloning -->
<div id="empty-form" style="display: none;">
<div class="item-form">
{{ item_formset.empty_form|crispy }}
<button type="button" class="remove-item btn btn-danger">Remove</button>
</div>
</div>
<!-- Include jQuery first -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Include Select2 JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
<!-- Your custom JavaScript code -->
<script type="text/javascript">
$(document).ready(function() {
// Function to initialize Select2 on elements
function initializeSelect2(element) {
element.find('.select2').select2();
}
// Initialize Select2 on page load
initializeSelect2($(document));
// Function to update form indices
function updateFormIndices() {
$('#item-formset .item-form').each(function(index, element) {
$(element).find(':input').each(function() {
const name = $(this).attr('name');
const newName = name.replace(/form-\d+-/, 'form-' + index + '-');
const id = 'id_' + newName;
$(this).attr({'name': newName, 'id': id});
});
});
$('#id_form-TOTAL_FORMS').val($('#item-formset .item-form').length);
}
// Add new item form
$('#add-item').click(function() {
const formIdx = $('#id_form-TOTAL_FORMS').val();
const newFormHtml = $('#empty-form').html().replace(/__prefix__/g, formIdx);
const newForm = $(newFormHtml);
$('#item-formset').append(newForm);
$('#id_form-TOTAL_FORMS').val(parseInt(formIdx) + 1);
// Initialize Select2 on new elements
initializeSelect2(newForm);
});
// Remove item form
$(document).on('click', '.remove-item', function() {
$(this).closest('.item-form').remove();
updateFormIndices();
});
});
</script>
{% endblock %}
I want to add search function inside the dropdown menu with select2 i tried alot but it does not work can anyone help me ?