Source code for django_select2_chained.widgets

"""Contains all the Django widgets for select2-chained."""

import logging

from django.utils.safestring import mark_safe
from django_select2.util import JSFunctionInContext
from django_select2.widgets import AutoHeavySelect2Widget

__all__ = (
    'PrepopulatedSelect2Widget', 'ChainedAutoSelect2Widget'
)

logger = logging.getLogger(__name__)


[docs]class PrepopulatedSelect2Widget(AutoHeavySelect2Widget): """ A prepopulated :py:class:`django_select2.widgets.AutoHeavySelect2Widget`. It allows sending empty search queries to the server. """ def __init__(self, **kwargs): """ Init method. :keyword select2_options: A dictionary containing select2 options. """ if not isinstance(kwargs.get('select2_options'), dict): kwargs['select2_options'] = {} kwargs['select2_options'].update({ # This will allow select2 to send empty search to server. 'minimumInputLength': 0, # This is needed, otherwise search field will be hidden by select2. 'minimumResultsForSearch': 0, }) super(PrepopulatedSelect2Widget, self).__init__(**kwargs)
[docs]class ChainedAutoSelect2Widget(PrepopulatedSelect2Widget): """A :py:class:`PrepopulatedSelect2Widget` to be used with chained fields.""" def __init__(self, *args, **kwargs): """ Init method. :keyword chain_field: Name of the field in the form. :keyword model_field: Name of the field in the model. """ self.chain_field = kwargs.pop('chain_field', None) self.model_field = kwargs.pop('model_field', None) super(ChainedAutoSelect2Widget, self).__init__(*args, **kwargs)
[docs] def render(self, name, value, attrs=None, choices=()): """Render the widget.""" if not self.chain_field or not self.model_field: raise NotImplementedError(u"Chain field and model field must be specified.") if len(name.split('-')) > 1: # formset chain_field = '-'.join(name.split('-')[:-1] + [self.chain_field]) else: chain_field = self.chain_field data_div = '<div class="field-chained-select-data" style="display: none" data-chained-field="%s" ' \ 'data-value="%s" data-id="%s"></div>' \ % (chain_field, value, attrs['id']) output = super(ChainedAutoSelect2Widget, self).render(name, value, attrs, choices) output += data_div return mark_safe(output)
class Media: js = ['/static/js/select2_chained.js']
[docs] def init_options(self): """Initialize widget options.""" self.options['ajax']['data'] = JSFunctionInContext('django_select2_chained.extra_url_params') self.options['chain_field'] = self.chain_field