1

I am using Django and AJAX to implement a chained-dropdown. The user will first be prompted to select a brand_name from a dropdown, and depending upon the brand_name selected, all the names of the products that are made by that brand will be displayed in the second dropdown.

views.py

def chained_dropdown(request):
    if request.method == "POST":
        brand = request.POST['brand']
        print(brand)

        sort_by_brand = list(models.Product.objects.filter(brand=brand).order_by('product_id').values('product_id', 'product_name'))

        data = {
            'SortByBrand': sort_by_brand
        }

        return JsonResponse(data)

AJAX request:

var brand = $('#brand').val()

    $.ajax({
        type: "POST",
        url: "/changeddropdown",
        data:{
            "brand": brand,
        }, success: function (data){
           
           // What should I do here?
 
           console.log(data)
        },
    })

templates snippet: This is where I want the product names to be displayed, and the option value should be their corresponding product_id.

<label for="product_id"> Product ID</label>

<select name="product_id" id="product_id">

<option disabled selected="true"> --Select -- </option>

<option value=""> </option>

</select>

For your reference, this is what console.log(data) prints:

{SortByBrand: [{product_id: 31, product_name: "Lotion"}, {product_id: 32, product_name: "Deo"}]}

I am having trouble displaying this information in the template, any help would be greatly appreciated.

2 Answers 2

1

Below code should work

var brand = $('#brand').val()

$.ajax({
    type: "POST",
    url: "/changeddropdown",
    data:{
        "brand": brand,
    }, success: function (data){
       
       var select = document.getElementById("product_id");
       //clear previous data
       document.getElementById('product_id').innerText = null;
       data.SortByBrand.forEach(function(element, index, list) { 
            var option = document.createElement('option');
            option.text = element.product_name;
            option.value = element.product_id
            select.add(option, 0);
            list[index] = {'name': element}; 
        });

    },
})
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer! It works, but as I pointed out in the other answer, when I select another brand_name, the names of products belonging to the previously selected brand_name are still appearing too. Is there a way this can be fixed?
I have edited code to clear dropdown before populating it, hope it will work now
0

You have to handle the response in success callback of Ajax request.

$.ajax({
    type: "POST",
    url: "/changeddropdown",
    data:{
        "brand": brand,
    },
    success: function (data){
       console.log(data);

       // Add below snippet no
       let productSelectBox = $('#product_id');
       const productsData = data.SortByBrand;
       $.each(productsData, function(idx, product) {
           let productOption = $("<option/>", {
               value: product.product_id,
               text: product.product_name
           });
       
       productSelectBox.append(productOption);
       });
    }
});

Django view seems to be working. Although, you can improve your architecture by using Django REST Framework but this is not scope of this question.

2 Comments

Hi. Thanks a ton for your answer. It is working fine, but there's just one caveat. When I select "brand name 1" for the first time, it is displaying the product names correctly. However, when I select "brand name 2", the name of the products belonging to "brand name 1" are displayed along with that of "brand name 2". I feel that this may be caused because of the append function, am I right? The thing is, this is my first ever real project, and I had 0 experience with Django and everything related to web development up until about a week ago. I'll certainly checkout REST FW!
Hi.. you have to remove the existing options for brand 1 before issuing Ajax request for brand 2. You can write this code in beforeSend callback of Ajax. Just empty all the options from the select box.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.