django-selectable usage (example) ¶
Include django-selectable to the requirements:
django-selectable==1.2.1
jQuery-UI is needed:
npm install jquery-ui-dist
Add selectable to your INSTALLED_APPS:
INSTALLED_APPS [ ..., 'selectable',
Add the urls to your root url patterns:
urlpatterns = [ ... path('selectable/', include('selectable.urls')),
Inclusions in file base.html:
<script src="{% static 'jquery/dist/jquery.min.js' %}" type="text/javascript"></script> <script src="{% static 'jquery-ui-dist/jquery-ui.min.js' %}" type="text/javascript"></script> <script src="{% static 'selectable/js/jquery.dj.selectable.js' %}" type="text/javascript"></script>
Define the lookup view:
file lookups.py:
from selectable.base import ModelLookup from selectable.registry import registry from backend.models import Contatore class ContatoreLookup(ModelLookup): model = Contatore search_fields = ('seriale__icontains', ) filters = {} def get_query(self, request, term): self.filters['azienda__codice'] = request.GET.get('azienda', '') results = super(ContatoreLookup, self).get_query(request, term) return results def get_item_label(self, item): n = 40 nome = item.nome if len(nome) > n: nome = nome[:n] + "..." return "%s [%s]" % (item.codice, nome) def get_item_value(self, item): return item.codice registry.register(ContatoreLookup)
Use AutoCompleteWidget in the form field:
file forms.py:
from django import forms from selectable.forms import AutoCompleteWidget from .lookups import ContatoreLookup class SelectContatoreForm(forms.Form): contatore = forms.CharField( label='Contatore', widget=AutoCompleteWidget(ContatoreLookup, limit=10), required=False, )
Usage in a modal
You need to call this after form loading:
bindSelectables();
See:
https://github.com/mlavin/django-selectable/issues/78
Tracing selectable events and advanced filtering
function trace_djevents(element) { element.on('djselectablecreate', function(event) { console.log('EVENT: djselectablecreate'); }); element.on('djselectablesearch', function(event) { console.log('EVENT: djselectablesearch'); }); element.on('djselectableopen', function(event) { console.log('EVENT: djselectableopen'); }); element.on('djselectablefocus', function(event) { console.log('EVENT: djselectablefocus'); }); element.on('djselectableselect', function(event) { console.log('EVENT: djselectableselect'); }); element.on('djselectableclose', function(event) { console.log('EVENT: djselectableclose'); }); element.on('djselectablechange', function(event) { console.log('EVENT: djselectablechange'); }); } function after_form_load() { // http://django-selectable.readthedocs.io/en/latest/advanced.html bindSelectables(); var azienda = $('#id_azienda'); var cantiere = $('#id_cantiere'); trace_djevents(cantiere); cantiere.djselectable('option', 'prepareQuery', function(query) { query.azienda = azienda.val(); }); cantiere.on('djselectableselect', function(event) { var url = sprintf('/api/cantiere/%s/%s/', azienda.val(), cantiere.val()); $.ajax({ type: 'GET', url: url, dataType: 'json', data: $(this).serialize(), success: function(data) { console.log(data.nome); cantiere.parent().find('.help-block').text(data.nome); } }); }); azienda.on('change', function(event) { console.log('azienda changed'); cantiere.val(null); cantiere.parent().find('.help-block').html(' '); }); setTimeout(function() { cantiere.focus() }, 500); }
Sample .ui-autocomplete styling (.scss)
.ui-autocomplete { // position: absolute; // z-index: 3000 !important; //cursor: default; background-color: white; list-style: none; padding: 0 8px; font-size: 18px; border: 1px solid #ccc; .ui-menu-item { padding: 4px; a { color: #666; } .highlight { background-color: yellow; } } }