[Django]-Dynamically updating values of a field depending on the choice selected in another field in Django

0👍

I figured out how to achieve this functionality. I wish I could give the credits to a single person but it’s really a combination of many people’s answers.

in the views.py which returns the HTML page where I want this functionality, I wrote this code, It returns the Product objects to the HTML file:

model_data=Inventory.objects.values_list('product_number','amount')
data=[model for model in model_data.values()]
context = {
    "data": data,
}
return render(request, "entry.html", context)

In the entry.html, I access the data using: {{ data|json_script:"hello-data" }}

Then the data I get is:

[{"product_number": 1, "product": "Laptop", "title": "Lenovo", "amount": 50000}, {"product_number": 2, "product": "Single Table Tennis Ball", "title": "Table Tennis Ball Share", "amount": 4}]

In the entry.html I used some javascript:

<script type="text/javascript">
    var data = JSON.parse(document.getElementById('hello-data').textContent);
    document.getElementById('id_line_one').onchange = function(event){
        var data1 = data.find(({product_number}) => product_number == event.target.value);
        document.getElementById('id_line_one_unit_price').value = data1 && data1.amount ? data1.amount : 0;
};

So, I parse the JSON data, and then when the user clicks the drop-down menu whose id is id_line_one, I check if the returned number(i.e., product_number) matches with any product_number present in the variable data. and then I change the amount of that respective field.

Referrence: https://stackoverflow.com/a/72923853/9350154

3👍

when you pass the dict_obj to your template you can get the json with

{{ dict_obj|json_script:"hello-data" }}

const value = JSON.parse(document.getElementById('hello-data').textContent);

https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#json-script

change the value depending on the selected item

const data = {
    "apple": 2.3,
    "orange": 1.7,
    
}

document.getElementById('inventory_item').onchange = function() {
    document.getElementById('price').value = data[this.value];
};
<select name="InventoryDropdown" id="inventory_item">
<option value="" selected disabled>---</option>
<option value="apple">apple</option>
<option value="orange">orange</option>
</select>
<input type="text" id="price" >

1👍

if i get it right you get the pk of inventory in this line

var line_one=document.getElementById('id_line_one').value

so you need to iterate over the json, to find it – i tested it with your printed JSON File

function getDictEntryByPk(dict_list, pk) {
   for (let i=0; i < dict_list.length; i++) {
       if (dict_list[i].pk == pk) {
           return dict_list[i]
       }
   }
}

and use it like that:

var line_one=document.getElementById('id_line_one').value;
var line_one_data = getDictEntryByPk(data, line_one);
document.getElementById('id_line_one_unit_price').value = line_one_data.fields.amount

EDIT:
same with less code:

function getDictEntryByPk(dict_list, pk) {
    return dict_list.find(element => element.pk == pk);
}

0👍

An easy alternative would be to redefine your Inventory __str__ method to include the unit price, so the drop down becomes e.g. ‘Inventory #1 – ₹500’. You don’t then need to worry about JS, JSON, or updating the amount. The total amount can be refreshed whenever the form is submitted with the quantity. Otherwise you need JS to get the unit price and to calculate the total price with the quantity.

As an aside, your models have lines manually added to the Invoice – i.e. line_one, line_two, etc. – this isn’t a good way of structuring your models or data. You should add an intermediary model called ‘InvoiceLine’ or something similar that can handle any numbers of invoice lines and connects with FKs between your Inventory and Invoice models. The reason why this is particularly important is because at the moment all of your lines have models.CASCADE as the on_delete option, meaning that an Invoice with ten lines could be completely deleted even if just one of your FK-relation Inventory models is deleted!

👤0sVoid

Leave a comment