Skip to main content

Chained select box widget for Django framework using AJAX requests.

Project description

This library is inspired by django-chained-selectbox from s-block (https://github.com/s-block/django-chained-selectbox).

It serves chained select box widget for Django framework using AJAX requests for chaining select boxes together. The values change depending on the parent value.

Previous mentioned library was intended for use in Django admin only. The new library has frontend functionality, improved existing instance data initialization and new ChainedModelChoiceField. It also uses custom TestClient which is able pass request.user variable into AJAX view if user is logged in. It is very useful if you need to filter result queryset by user permissions for example.

Tested on Django 1.4.5.

Requirements

  • Django

  • jQuery

Installation

  1. Install python library using pip: pip install django-clever-selects

  2. Add clever_selects to INSTALLED_APPS in your Django settings file

  3. Add clever_selects_extras to your {% load %} statement and put {% clever_selects_js_import %} tag before closing </body> element. It is important to load clever-selects.js file after body content, so do not put it in the <head></head>!

Usage

Forms

Form must inherit from ChainedChoicesMixin (or from ChainedChoicesForm / ChainedChoicesModelForm, depends on your needs) which loads the options when there is already an instance or initial data:

from clever_selects.form_fields import ChainedChoiceField
from clever_selects.forms import ChainedChoicesForm


class SimpleChainForm(ChainedChoicesForm):
    first_field = ChoiceField(choices=(('', '------------'), (1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'), ))
    second_field = ChainedChoiceField(parent_field='first_field', ajax_url=reverse_lazy('ajax_chained_view'))


class MultipleChainForm(ChainedChoicesForm):
    first_field = ChoiceField(choices=(('', '------------'), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), ))
    second_field = ChainedChoiceField(parent_field='first_field', ajax_url=reverse_lazy('ajax_chained_view'))
    third_field = ChainedChoiceField(parent_field='second_field', ajax_url=reverse_lazy('ajax_chained_view'))
    fourth_field = ChainedChoiceField(parent_field='third_field', ajax_url=reverse_lazy('ajax_chained_view'))
    fifth_field = ChainedChoiceField(parent_field='fourth_field', ajax_url=reverse_lazy('ajax_chained_view'))


class ModelChainForm(ChainedChoicesModelForm):
    brand = forms.ModelChoiceField(queryset=CarBrand.objects.all(), required=True,
        empty_label=_(u'Select a car brand'))
    model = ChainedModelChoiceField(parent_field='brand', ajax_url=reverse_lazy('ajax_chained_models'),
        empty_label=_(u'Select a car model'), model=BrandModel, required=True)
    engine = forms.ChoiceField(choices=([('', _('All engine types'))] + Car.ENGINES), required=False)
    color = ChainedChoiceField(parent_field='model', ajax_url=reverse_lazy('ajax_chained_colors'),
        empty_label=_(u'Select a car model'), required=False)

    class Meta:
        model = Car

Notice that ajax URLs could differ of each field for different purposes. See example project for more use cases.

Views

Ajax call is made whenever the parent field is changed. You must set up the ajax URL to return json list of lists:

class AjaxChainedView(BaseDetailView):
    """
    View to handle the ajax request for the field options.
    """

    def get(self, request, *args, **kwargs):
        field = request.GET.get('field')
        parent_value = request.GET.get("parent_value")

        vals_list = []
        for x in range(1, 6):
            vals_list.append(x*int(parent_value))

        choices = tuple(zip(vals_list, vals_list))

        response = HttpResponse(
            json.dumps(choices, cls=DjangoJSONEncoder),
            mimetype='application/javascript'
        )
        add_never_cache_headers(response)
        return response

Or you can use ChainedSelectChoicesView class helper:

class AjaxChainedView(ChainedSelectChoicesView):
    def get_choices(self):
        vals_list = []
        for x in range(1, 6):
            vals_list.append(x*int(self.parent_value))
        return tuple(zip(vals_list, vals_list))

Don’t forget to update your urls.py:

url(r'^ajax/custom-chained-view-url/$', AjaxChainedView.as_view(), name='ajax_chained_view'),

Authors

Library is by Erik Telepovsky from Pragmatic Mates. See our other libraries.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-clever-selects-0.6.8.tar.gz (8.4 kB view details)

Uploaded Source

File details

Details for the file django-clever-selects-0.6.8.tar.gz.

File metadata

File hashes

Hashes for django-clever-selects-0.6.8.tar.gz
Algorithm Hash digest
SHA256 66de02f3191b251e157e6ad493f54aa8a870c34c99ef57d8a09843fd011eb6fa
MD5 55fec5f9c2c719e6c20e7ddb3f049bd4
BLAKE2b-256 6aac9eceb42a51b2dfe1405abb3c085884e12425f409855d95c02c69bf3ec3dc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page