Hi all,
This is my problem
PRODUCT-FORM FIELDS: pos_station <ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul>
UNIT-FORM FIELDS: unit <ul class="errorlist"><li>This field is required.</li></ul>
UNIT-FORM FIELDS: value <ul class="errorlist"><li>This field is required.</li></ul>
UNIT-FORM FIELDS: uom_options <ul class="errorlist"><li>This field is required.</li></ul>
I’m using ajax to display toast messages. I have many forms to save them by one click on one save button. These are my forms
form = ProductForm(request.POST or None, request.FILES or None, prefix="pro")
price_form = ProductPriceForm(request.POST or None, prefix="price")
extension_form = ProductExtensionForm(request.POST or None, prefix="extension")
uom_form = UOMForm(request.POST or None, prefix="uom")
vendor_form = ProductVendorsForm(request.POST or None, prefix="ven")
cat_form = ProductCategoryForm(request.POST or None, prefix="cat")
img_form = ProductImageForm(request.POST or None, request.FILES or None, prefix="img")
So I have many fields, And I tried to pass their values and save them as follows but I failed
match_name = Product.objects.filter(name=pro_name).exists()
match_name_ar = Product.objects.filter(name=pro_name_ar).exists()
if form.is_valid() and uom_form.is_valid():
if not match_name : # and not match_name_ar
save_form = form.save(commit=False)
save_form.user = request.user
save_form.updated_user = request.user
save_form.reference_code = save_form.pro_code
save_form.pos_station_id = pos
save_form.store_id = store
save_form.expire_ref = expire_ref #choices.HOUR
save_form.hint_ref = hint_ref # choices.HOUR
save_form.save()
save_uom_form = uom_form.save(commit=False)
save_uom_form.product_id = save_form.id
save_uom_form.uom_options = [obj for obj in unit_options]
save_uom_form.value = [obj for obj in unit_value]
save_uom_form.unit_id = [obj for obj in unit]
save_uom_form.save()
data['pro_id'] = save_form.id
data['error'] = 'Product saved successfully ...'
data['type'] = 'success'
return JsonResponse(data)
The next code illustrate the ajax call to submit the from
$(document).ready(function () {
$.ajaxSetup({
headers: {
"X-CSRFToken": '{{ csrf_token }}'
}
});
$(document).on('submit', ".product-form", function (e) {
// e.preventDefault();
// console.log();
let name = $('#id_pro-name').val();
let nameAr = $('#id_pro-name_ar').val();
var optionValues = $('.unit-options').map(function() {
return $(this).find('select').val();
}).get();
var unitValues = $('.unit-select').map(function() {
return $(this).find('select').val();
}).get();
var values = $('.unit-value').map(function() {
return $(this).find('input').val();
}).get();
console.log(
'submit button clicked successfully',
'PRO-NAME :', name,
'OPTIONS:', optionValues,
'UNIT-VALUEs:', unitValues,
'VALUES :', values,
);
$.ajax({
type: 'POST',
url: '{% url "products:add_product" %}',
data: {
'pro-branch': $('[name=pro-branch] option:selected').val(),
'pro-pos_station': $('[name=pro-pos_station] option:selected').val(),
'pro-store': $('[name=pro-store] option:selected').val(),
'pro-name': name,
'pro-name_ar': nameAr,
'pro-barcode': $('#id_pro-barcode').val(),
'pro-reference_code': $('#id_pro-reference_code').val(),
'pro-is_deleted': $('[name=pro-is_deleted]').is(':checked'),
'pro-inactive': $('[name=pro-inactive]').is(':checked'),
'pro-consumable': $('[name=pro-consumable]').is(':checked'),
'pro-on_pos': $('[name=pro-on_pos]').is(':checked'),
'pro-purchased': $('#id_pro-purchased').is(':checked'),
'pro-sold': $('#id_pro-sold').is(':checked'),
'pro-favorite': $('#id_pro-favorite').is(':checked'),
'pro-is_inventory': $('#id_pro-is_inventory').is(':checked'),
'pro-sale': $('#id_pro-sale').is(':checked'),
'pro-manufactured': $('#id_pro-manufactured').is(':checked'),
'pro-expiry': $('#id_pro-expiry').is(':checked'),
'pro-has_limit_plus': $('#id_pro-has_limit_plus').is(':checked'),
'pro-has_limit_minus': $('#id_pro-has_limit_minus').is(':checked'),
'pro-expire_period': $('#id_pro-expire_period').val(),
'pro-expire_ref': $('#id_pro-expire_ref').val(),
'pro-expire_period_hint': $('#id_pro-expire_period_hint').val(),
'pro-hint_ref': $('#id_pro-hint_ref').val(),
'pro-order_limit_plus': $('#id_pro-limit_plus').val(),
'pro-order_unit_plus': $('#id_pro-order_unit_plus').val(),
'pro-order_limit_minus': $('#id_pro-limit_minus').val(),
'pro-order_unit_minus': $('#id_pro-order_unit_minus').val(),
'img-photo': $('#id_img-photo').val(),
'uom-uom_options': $('#uom-uom_options :selected').val(),// optionValues,
'uom-unit': $('#uom-unit :selected').val(), // unitValues,
'uom-value': $('#uom-value').val(), //values,
},
success: function (data) {
console.log(
'WHAT IS GOING ON HERE FROM SUCCESS: ',
'DATA ERROR MSG --> ', data['error'],
'AFTER-SUBMITTING:: ', optionValues,
'AFTER-SUBMITTING:: ', unitValues,
'AFTER-SUBMITTING:: ', values,
);
$(function() {
var Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 9000
});
var proId = data['pro_id'];
if (data['type'] == 'error'){
console.log(data['type'])
toastr.error(data['error']);
} else if (data['type'] == 'success') {
toastr.success(data['error']);
console.log('PRO-ID: ', data['pro_id']);
} else if (data['type'] == 'info') {
toastr.info(data['error']);
}
});
},
error: function (){
console.log('ERROR with ajax request');
},
});
e.preventDefault();
});
});
And use ajax also to populate the drop-down input(pos_station) based on the value of another drop-down input (branch) using this code snippet
$(document).on('change', '#id_pro-branch', function() {
console.log('BRANCH CHANGED TRUE')
let branchSelected = $(this).find('option:selected').val();
$.ajax({
url:'{% url "ajax_product_cat_tab" %}',
type:'POST',
dataType:'json',
data: {
'pro-branch': branchSelected,
},
success: function (data) {
console.log(
"Success from POST ",
);
$(function(){
var posNames = (data['pos_names']);
$('#id_pro-pos_station').text('');
if (posNames.length > 0) {
// alert(values);
$('#id_pro-pos_station').append('<option>----------</option>');
for (var i = 0; i < posNames.length; i++) {
//show where value is same..
$('#id_pro-pos_station').append('<option>'+(posNames[i])+'</option>');
}
}
});
},
error: function (data) {
console.log(data, 'Something went wrong in POST !!!');
}
});
});
and the view is
def ajax_product_cat_tab(request):
branch_name = request.POST.get('pro-branch')
pos_stations = PosStation.objects.values_list(
'name', flat=True
).filter(
branch=Branches.objects.select_related(
'user'
).get(
id=branch_name
)
)
pos_names = [obj for obj in pos_stations]
data = {
'pos_names': pos_names,
}
return JsonResponse(data)
Also (expire_ref and hint_ref) don’t accept the value or initial (it appears on the form but I must choose from the drop-down list to avoid the error “This field is required.”) I don’t know why
self.fields['expire_ref'].widget.attrs['value'] = choices.HOUR
self.fields['expire_ref'].initial = choices.DAY
self.fields['hint_ref'].widget.attrs['value'] = choices.HOUR
self.fields['hint_ref'].initial = choices.DAY
Really I spent many times to fix this issue and I can use “HTML inputs” instead of django forms but I prefer forms to use its benefits .
May be I miss something here or there , I don’t know
Any suggestions thanks