Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django, ajax populate form with model data

So I got a simple registration form. In this form there are 3 more fields:

  • University
  • Course
  • Module

What I'm trying to do is to filter the data. So when the user select a University, the course field(select) will show all the courses that belong to this university. Also when the user select a course, the module field(select) will show all the modules that belong to this course. If you check the image, you will see it's kinda simple.

I managed to show all the universities, courses and modules but that's not practical since the data aren't correct(shows all entries). I know how to filter the queryset but I don't know how to use AJAX to do that. Tried many tutorials but couldn't find something so I'm sorry for not posting code.

If you can point me to the right tutorial, example or give me some code to start working on it...

Screenshot of the form

UPDATE I used Del's example to start working on it. The thing is that I'm not good at all with AJAX and JS. So I created a view which receives the request from the ajax form(for now it just returns all courses, no filtering). The issue I'm having is that when I select the university, then the course select gets empty. So I guess it doesn't get the data from the view. If you can have a look..

view

def ajax_get_courses(request):
    courses = Course.objects.all()
    if request.is_ajax():
        data = serializers.serialize('json', courses)
        return HttpResponse(data,'json')
    else:
        return render_to_response('registration/registration_form_teacher.html', {'courses':courses}, context=RequestContext(request))

js

$(document).ready(function(){
    $("#university").change(function(){
        var request = $.ajax({
            url: "{% url 'ajax_get_courses' %}",
            type: "POST",
            data: { university: $("#university").val(),
                    csrfmiddlewaretoken: '{{ csrf_token }}'
                  },
            dataType: "html"
        });

        request.done(function(msg) {
                  $("#course").html( msg );
        });

    });

});

UPDATE 2

So after I select a university, the select course source code is like this:

<select id="course" name="course" class="form-control">[{"pk": 1, "model": "studies.course", "fields": {"attendance": "FT", "name": "Computer Science", "degree": "BSc (Hons)", "university": 1, "modules": [], "years": 3}}, {"pk": 2, "model": "studies.course", "fields": {"attendance": "FT", "name": "Computer Science", "degree": "MComp (Hons)", "university": 1, "modules": [], "years": 4}}, {"pk": 3, "model": "studies.course", "fields": {"attendance": "FT", "name": "Civil Engineering", "degree": "BEng (Hons)", "university": 1, "modules": [], "years": 3}}, {"pk": 4, "model": "studies.course", "fields": {"attendance": "FT", "name": "Civil Engineering", "degree": "MEng (Hons)", "university": 1, "modules": [], "years": 4}}, {"pk": 5, "model": "studies.course", "fields": {"attendance": "FT", "name": "Pharmacy", "degree": "MPharm (Hons)", "university": 1, "modules": [], "years": 4}}, {"pk": 6, "model": "studies.course", "fields": {"attendance": "FT", "name": "Aeronautical Engineering", "degree": "MEng (Hons)", "university": 4, "modules": [], "years": 4}}, {"pk": 7, "model": "studies.course", "fields": {"attendance": "FT", "name": "Biochemistry", "degree": "BSc (Hons)", "university": 3, "modules": [], "years": 3}}, {"pk": 8, "model": "studies.course", "fields": {"attendance": "FT", "name": "Chemistry", "degree": "BSc (Hons)", "university": 3, "modules": [], "years": 3}}, {"pk": 9, "model": "studies.course", "fields": {"attendance": "FT", "name": "Business Studies", "degree": "BSc (Hons)", "university": 3, "modules": [], "years": 3}}]</select>

Which means that I'm getting the data but i have to add some html? Like <li>...</li>?

like image 548
manosim Avatar asked Apr 25 '14 23:04

manosim


1 Answers

This would require a few steps to accomplish, but it looks more intimidating than it actually is.

First create a new view that will receive your ajax request and return the proper selection options as either HTML or JSON.

Then set the ajax request using the jQuery ajax function to fire when University selection box changes.

Here is a simple example to try to help you get started: ...

$("#university").change(function(){
 $.ajax({
          url: "{% url 'universities:view_name' %}",
          type: "POST",
          data: { university: $("#university").val(),
                  csrfmiddlewaretoken: '{{ csrf_token }}'
                },
          dataType: "html"
        });
  }

// When the request returns, update the contents of the select with HTML received
// from your processing view

request.done(function(msg) {
          $("#university").html( msg );
        });

I hope this helps a bit. Best of luck.

EDIT: In your update, you are creating a json in your view, but requesting html with ajax. Instead of json, just build the html as a string and render it as the sole content of your template.

Something like this in your view:

html_string="" 
for course in Courses.objects.all(): 
    html_string += '<option value="%s">%s</option>' % (course.pk, course.name)

You could perform this task with javascript on the client side using the json data, but I think it is easier and requires less data transfer to handle it in the view.

like image 143
Del Avatar answered Nov 02 '22 09:11

Del