2

I'm trying to create a non-admin form with two dependent drop down lists (continent, country) in django using autocomplete-light. The first drop down list will contain a list of continents and the second a list of countries. Once the user selects one of the continent only the countries from that continent will be displayed in the country drop down list.

I've been able to get two dependent input fields working fine but am unable to convert these input fields to drop down lists. Below is the code I'm using, I'm hoping some one could help explain what's required to convert the dependent input fields to dependent drop down lists. I've attempted applying widgets in forms.py with no success, if I remove the "widgets = autocomplete_light.get_widgets_dict(Locations)" line from forms.py the drop down lists appear but I loose the dependancy between the two lists.

#models.py
    from django.db import models
    from django import forms
    import autocomplete_light

    class Continent(models.Model):
       continent_id = models.BigIntegerField(primary_key=True)
       continent_nm = models.CharField(max_length=100, blank=True)    
       class Meta:
          db_table = 'continent'

       def __unicode__(self):
          #return self.continent_nm       
          return u'%s %s' % (self.continent_id, self.continent_nm)    


    class Country(models.Model):
       country_id = models.BigIntegerField(primary_key=True)
       country_nm = models.CharField(max_length=100, blank=True)
       continent  = models.ForeignKey(Continent, null=True, blank=True)
       class Meta:
          db_table = 'country'

       def __unicode__(self):
          #return self.country_nm       
          return u'%s %s' % (self.country_nm, self.country_id)    

    class Locations(models.Model):
        continent = models.ForeignKey(Continent) 
        country   = models.ForeignKey(Country) 

        def __unicode__(self):
            return u'%s %s' % (self.continent, self.country)  


#forms.py
    import autocomplete_light 
    from django import forms
    from insights.models import Locations

    class DummyForm(forms.ModelForm):  
        class Meta:
            model = Locations    
            widgets = autocomplete_light.get_widgets_dict(Locations) 


# views.py
    from django.shortcuts import render
    from django.http import HttpResponse
    from insights.forms import DummyForm

    def index(request):
       form = DummyForm()
       context = {'form': form}   
       return render(request, 'insights/index.html', context) 



# autocomplete_light_registry.py
    import autocomplete_light
    import logging
    from insights.models import Continent, Country


    class AutocompleContinent(autocomplete_light.AutocompleteModelBase):
        search_fields= ('continent_id', 'continent_nm',)
        autocomplete_js_attributes={'placeholder': 'continent name ..'}


    autocomplete_light.register(Continent, AutocompleContinent)

    class AutocompleteCountry(autocomplete_light.AutocompleteModelBase):
        autocomplete_js_attributes={'placeholder': 'country name ..'}
        search_fields=('country_id', 'country_nm',)

        def choices_for_request(self):
            q = self.request.GET.get('q', '')
            continent_id = self.request.GET.get('continent_id', None)

            choices = self.choices.all()
            if q:
                choices = choices.filter(country_nm__icontains=q)
            if continent_id:
                choices = choices.filter(continent_id=continent_id)

            return self.order_choices(choices)[0:self.limit_choices]

    autocomplete_light.register(Country, AutocompleteCountry)    

#HTML

    <!-- index.html -->

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.js" type="text/javascript"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script type="text/javascript" src="/static/insights/dependant_autocomplete.js"></script>
    {% load staticfiles %}
    {% include 'autocomplete_light/static.html' %}

    <body>
    {% block content %}
      <form action='' method='post' enctype='multipart/form-data'>
      {{ form.as_p }}
      {% csrf_token %}        
      </form>
    {% endblock %}                
    </body>

dependant_autocomplete.js

$(document).ready(function() {
    $('body').on('change','.autocomplete-light-widget select[name$=continent]', function() {
        alert('autocomplete dependant');
        var continentSelectElement = $(this);
        var countrySelectElement = $('#' + $(this).attr('id').replace('continent', 'country'));
        var countryWidgetElement = countrySelectElement.parents('.autocomplete-light-widget');

        // When the continent select changes
        value = $(this).val();

        if (value) {
            // If value is contains something, add it to autocomplete.data
            countryWidgetElement.yourlabsWidget().autocomplete.data = {
                'continent_id': value[0],
            };
        } else {
            // If value is empty, empty autocomplete.data
            countryWidgetElement.yourlabsWidget().autocomplete.data = {}
        }

    })
});
tshepang
  • 12,111
  • 21
  • 91
  • 136
  • It would help if you could paste `/static/insights/dependant_autocomplete.js`. Anyway, did you read this doc ? https://django-autocomplete-light.readthedocs.org/en/latest/dependant.html – jpic Aug 16 '13 at 10:34
  • I've now added dependant_autocomplete.js, and thanks I have read the document. As mentioned the autocomplete functionality is working fine on two dependent input fields. – user2552125 Aug 17 '13 at 02:02
  • I don't really understand what doesn't work then ... – jpic Aug 17 '13 at 11:12
  • I unable to get to dependant drop down lists. The country list contains all countries which are not filtered by continent. – user2552125 Aug 18 '13 at 04:03
  • IS the `alert()` ever called on continent change ? I'm really not sure this is right: `'.autocomplete-light-widget select[name$=continent]'` – jpic Aug 18 '13 at 04:28
  • I've converted to smart_selects and now have this working. Thank you. – user2552125 Aug 18 '13 at 20:24
  • No problem, any time B) – jpic Aug 19 '13 at 09:32

0 Answers0