Brainstorm's snippets (1/247)

  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('&nbsp;');
    });

    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;
        }
    }
}