You could set a hidden field to have the real "state" value, then use jQuery to create the <select>
list and, on .select()
, copy its value to the hidden field. Then, on page load, your jQuery code can fetch the hidden field's value and use it to select the right item in the <select>
element after it's populated.
The key concept here is that the State popup menu is a fiction created entirely in jQuery and not part of the Django form. This gives you full control over it, while letting all the other fields work normally.
EDIT: There's another way to do it, but it doesn't use Django's form classes.
In the view:
context = {'state': None, 'countries': Country.objects.all().order_by('name')}
if 'country' in request.POST:
context['country'] = request.POST['country']
context['states'] = State.objects.filter(
country=context['country']).order_by('name')
if 'state' in request.POST:
context['state'] = request.POST['state']
else:
context['states'] = []
context['country'] = None
# ...Set the rest of the Context here...
return render_to_response("addressform.html", context)
Then in the template:
<select name="country" id="select_country">
{% for c in countries %}
<option value="{{ c.val }}"{% ifequal c.val country %} selected="selected"{% endifequal %}>{{ c.name }}</option>
{% endfor %}
</select>
<select name="state" id="select_state">
{% for s in states %}
<option value="{{ s.val }}"{% ifequal s.val state %} selected="selected"{% endifequal %}>{{ s.name }}</option>
{% endfor %}
</select>
You'll also need the usual JavaScript for reloading the states selector when the country is changed.
I haven't tested this, so there are probably a couple holes in it, but it should get the idea across.
So your choices are:
- Use a hidden field in the Django form for the real value and have the select menus created client-side via AJAX, or
- Ditch Django's Form stuff and initialize the menus yourself.
- Create a custom Django form widget, which I haven't done and thus will not comment on. I have no idea if this is doable, but it looks like you'll need a couple
Select
s in a MultiWidget
, the latter being undocumented in the regular docs, so you'll have to read the source.