0

I am using two ChoiceFields in my form. The available choices in the second one depend on the one in the first one.
I created an on change event in my template:

$("#id_department").change(function(){
  console.log($(this).val())
  var department = $(this).val();
  $.ajax({
    type: "POST",
    url : "{% url "load-choices" %}",
    data : {"department" : department},
    success: function(data){
      console.log(data)
      $("#id_usage").append(data);

    },
  });
});

which points to my view:

class LoadChoices(View):
    def post(self, request, *args, **kwargs):
        usages = {
            "new": _("New Device is created"),
            "room": _("Room is changed"),
            "owner": _("person currently lending is changed"),
            "reminder": _("Reminder that device is still owned"),
            "overdue": _("Reminder that device is overdue"),
            "trashed": _("Device is trashed")
        }
        department = request.POST["department"]
        used = MailTemplate.objects.values_list('usage', flat=True).filter(department = department)
        valid = [x for x in usages if not any(y in x for y in used)]
        return(HttpResponse(valid))

usages are the available choices, used are the choices that I do not want to include in the dropdown and valid are the choices I want to show in the dropdown. Normally, if I was in the edit view, I would just assign validto the field. But as this is the ajax view, as far as I understand it, I have to return valid.
But if I try to do that as shown above, the template receives a string like roomownernewremindertrashedoverdue and the dropdown choices do not change, they stay at their initial values that are determined when the form is loaded. (valid, when printed from the ajax view, has this format: [u'room', u'owner', u'new', u'reminder', u'trashed', u'overdue'].)
Now, for my question: How do I have to format/return these choices and how do I have to pass them to the ChoiceField, if not with append?

Brown Bear
  • 19,655
  • 10
  • 58
  • 76
LizzAlice
  • 678
  • 7
  • 18
  • Possible duplicate of [Creating a JSON response using Django and Python](https://stackoverflow.com/questions/2428092/creating-a-json-response-using-django-and-python) – Brown Bear Apr 17 '18 at 09:48

1 Answers1

1

You need to return your data as json so change the end of your view something like:

return HttpResponse(
    json.dumps(valid),
    content_type="application/json"
)

Then within the JavaScript append the options

var select = document.getElementByID('id_usage')
for (key in data.valid) {
   var option = document.createElement("option");      
   option.text = data.valid[key];
   option.value = key;
   select.add(option);
}
HenryM
  • 5,557
  • 7
  • 49
  • 105
  • I had to make a few changes to the code, for example changing `data.valid` to `data` and changing the returned values to a dictionary. Now, the right choices are shown in the dropdown. However, if I try to select one one them that was not in the initial choices ( defined by `fieldname.choices`), I am told that it is not a valid choice and cannot be selected. Apparently, I have to overwrite the`.choices` attribute of the field... Any idea how to to that? – LizzAlice Apr 18 '18 at 09:02
  • My code was only meant to point you in the right direction - I'm glad it helped. Is `fieldname.choices` in the `django` or `javascript`? I cannot see it above. I'm guessing it is in `Django` and the problem will be the key in Javascript is a number and you actually need to pass back whatever the `choice` needs to know which `choice` is being used. – HenryM Apr 18 '18 at 09:18
  • I know, I already passed the django choice key as key... According to the print, it seems normal... Also, if the choice was present in the initial choices, it is recognized and accepted... But if it was not, it does not work. – LizzAlice Apr 19 '18 at 10:00