Яндекс.Метрика

Рассылка обновлений по электронной почте

суббота, 14 декабря 2013 г.

Выпадающий список в поле формы Django с помощью Bootstrap-а

Представим, что у нас есть текстовое поле в формочке, в котором при наборе фразы, должен появляться выпадающий список с подсказками. По мере набора, он бы сокращался в соответствии с уточнением фразы. Что-то, что я назвала бы type-in search. Исправьте меня, если есть более точное название.

Итак. Есть Бутстрап, который умеет это делать через Джаваскрипт. Нам всего лишь нужно в атрибутах ячейки указать class="text", autocomplete="off", чтобы в выпадающем списке не появлялись рандомные поля, запомненные браузером, data-provide="typeahead" и data-source=massive, где massive --- это массив строк, по которым должен производиться поиск.

На этом можно было бы закончить, если бы мы не строили формы с помощью Django. Но я строю. Для этого нам все эти атрибуты поля нужно указать в параметрах атрибута класса формы.

Скажем, есть класс.

class ClientForm(forms.Form):
    client = CharField(
        label=u'Клиент',
        required=True,
        widget=TextInput())

TextInput принимает необязательный аргумент attrs, в котором хранятся как раз атрибуты поля формы. В соответствии с абзацем выше, класс должен принять вид:

 class ClientForm(forms.Form):
    client = CharField(
        label=u'Клиент',
        required=True,
        widget=TextInput(attrs={
            'class': 'text',
            'autocomplete': 'off',
            'data-provide': 'typeahead',
            'data-source': "['makedonskky', 'pluschenko', 'zhukov']"}))

И если ваш набор строк не изменяем, то в общем-то готово. Если же нужно, чтобы нужные значения брались из базы, и отслеживалось, чтобы при изменении значений в базе данных, выпадающий список соответствовал новым значениям, то следует при инициализации формочки, доставать этот список из базы.

Допустим есть модель Client, описывающая нужную таблицу в БД. Тогда класс формы будет выглядеть чуть по-другому:

class ClientForm(forms.Form):
    def __init__(self, user, *args, **kwargs):
        super(ClientForm, self).__init__(*args, **kwargs)

        self.client_list = json.dumps([
            client.name for client in Client.objects.filter(user=user)])

        self.widget = forms.TextInput(attrs={
            'class': 'text',
            'autocomplete': 'off',
            'data-provide': 'typeahead',
            'data-source': self.client_list})

        self.fields['client'] = CharField(
            label=u'Клиент',
            required=True,
            widget=self.widget)

На этом все. Пользуйтесь на здоровье.

2 комментария:

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
  2. class RouteSearch(forms.Form):
    route = forms.CharField(
    label=u'Поиск по маршруту',
    required=True)

    def __init__(self, number, *args, **kwargs):
    super(RouteSearch, self).__init__(*args, **kwargs)
    self.route_list = simplejson.dumps([
    r.route_name for r in Route.objects.filter(tat_number__contains=number)])
    self.widget = forms.TextInput(attrs={
    'class': 'text',
    'autocomplete': 'off',
    'data-provide': 'typeahead',
    'data-items': '10',
    'data-source': self.route_list,
    })

    self.fields['route'] = forms.CharField(
    label=u'Поиск по маршруту',
    required=True,
    widget=self.widget,
    )

    ОтветитьУдалить