I’ve got a view with a few different forms in it. The first form has a search field which populates a multiple choice field, and when the user types in their query in the search field, an AJAX call is sent to bring all records which match the query. The user then selects the choices from the first multiple choice field and clicks “Add” to move them to a different Multi Select Box
This works fine, but when the form submits, I receive an error that reads
“Select a valid choice.1 is not one of the available choices.”.
I have tried setting the choices after receiving arguments in the form init, but that doesn’t seem to work.
My Form:
class SiteCoordinatorForm(forms.ModelForm):
selected_studies = forms.MultipleChoiceField(required = False)
site = forms.ChoiceField(required = False)
studies = forms.MultipleChoiceField(required = False)
study_search = forms.CharField(max_length = 50, required = False)
def __init__(self, *args, **kwargs):
super(SiteCoordinatorForm, self).__init__(*args, **kwargs)
if args:
study_list = []
query_dict = args[0]
self.fields['selected_studies'].choices = [(int(x), x) for x in query_dict.getlist('selected_studies')]
self.fields['site'].choices = [(x.pk, "%s (%s)" % (x.primary_name, x.primary_number)) for x in Site.objects.all().order_by('primary_name')]
class Meta:
model = SiteCoordinator
exclude = ('studies', 'site', 'selected_studies')
My AJAX function which populates the box:
def search_studies(request):
return_data = {}
studies = []
make_query = lambda terms, fieldname: reduce(lambda x, y: x & Q(**{fieldname + '__icontains': y}), terms, Q())
if 'search_text' in request.POST:
terms = request.POST['search_text'].split()
for rec in Study.objects.filter(make_query(terms, 'name')):
studies.append({
'study': {'id': rec.id, 'name': rec.name, 'number': rec.id}
})
response = {'status': 'success', 'count': len(studies), 'studies': studies}
return HttpResponse(simplejson.dumps(response), mimetype="application/json")
The function to populate the MultiSelectBox:
function show_results(data, status_code, request){
recs = data.studies;
var select_box = document.getElementById('id_studies');
select_box.options.length = 0;
for (var index = 0; index < recs.length; index ++){
select_box.options[index] = new Option(recs[index].study.name,
recs[index].study.id,
false, false);
}
}
Then the JQuery to move the choices:
$('#add').click(function() {
$('#id_studies option:selected').remove().appendTo('#id_selected_studies');
return false;
});
$('#remove').click(function() {
$('#id_selected_studies option:selected').remove().appendTo('#id_studies');
return false;
});
It is clear that we don’t want validations of
MultipleChoiceFieldbut do wantMultipleSelectWidgetso solution is simply to change field toand do your own validations in