Практически во всех проектах возникает необходимость отобразить выпадающий список в форме, данный в котором грузились бы с помощью ajax. В связи с этим еще 2 года назад я написал SuggestBundle для симфони, который содержит дополнительный тип формы, который может использоваться вместо стандартных типов entity и document. Ключевая особенность бандла в том, что выпадающий список подгружается с помощью ajax (при помощи библиотеки select2). На днях я наконец собрался с силами, чтобы написать документацию по бандлу и решил поделиться разработкой с сообществом.


Кроме того бандл можно использовать и для построения выпадающих список, которые никак не связаны с Doctrine ORM и Doctrine ODM.


Под катом инструкция по установке, настройке и использованию бандла.



Ссылка на бандл: https://github.com/sirian/suggest-bundle.


1. Установка


Добавьте sirian/suggest-bundle пакет в секцию require в файле composer.json.


$ composer require sirian/suggest-bundle

Добавьте SuggestBundle в ваш AppKernel.php:


<?php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Sirian\SuggestBundle\SirianSuggestBundle(),
        // ...
    );
    ...
}

2. Конфигурация


После утсановки бандла, добавьте следующие строки в конфигурацию роутинга:


# app/config/routing.yml

_sirian_suggest:
    resource: "@SirianSuggestBundle/Resources/config/routing.yml"
    prefix:   /suggest

И выберите версию виджета, которая будет использоваться по-умолчанию для форм (зависит от версии библиотеки select2, которую вы будете использовать в проекте). Допустимые значения select2_v3, select2_v4. Также вы можете указать другие опции формы, которые будут использоваться по умолчанию при использовании типа формы SuggestType::class


# app/config/config.yml

...
sirian_suggest:
    form_options:
        widget: select2_v4
        attr:
            placeholder: "Search..."

3. Настройка саггестеров


Для документов из Doctrine ODM и сущностей Doctrine ORM вы можете легко описать необходимые саггестеры в файле config.yml вашего проекта.


3.1. Doctrine ODM Document (Mongodb)


# app/config/config.yml

...
sirian_suggest:
    odm:
        category:
            class: "MainBundle:Category"
            property: name

        user:
            class: "MainBundle:User"
            property: username
            search:
                email: ~
                username: ~

3.2. Doctrine ORM Entity


# app/config/config.yml

...
sirian_suggest:
    orm:
        category:
            class: "MainBundle:Category"
            property: name

        user:
            class: "MainBundle:User"
            property: username
            search:
                email: ~
                username: ~

3.3. Произвольные саггестеры


В случае если вам необходима дополнительная логика для построения выпадающего спика — вы можете создать свой собственный саггестер. Например, давайте создадим AdminSuggester который будет содержать только тех пользователей, которые имеют роль ROLE_ADMIN. Для простоты мы может унаследовать класс от абстрактного класса DocumentSuggester (или EntitySuggester для Doctrine ORM).


<?php

namespace App\MainBundle\Suggest;

use App\MainBundle\Document\User;
use Doctrine\Common\Persistence\ManagerRegistry;
use Sirian\SuggestBundle\Suggest\DocumentSuggester;
use Sirian\SuggestBundle\Suggest\Item;
use Sirian\SuggestBundle\Suggest\SuggestQuery;

class AdminSuggester extends DocumentSuggester
{
    public function __construct(ManagerRegistry $registry)
    {
        $options = [
            'class' => User::class,
            'id_property' => 'id',
            'property' => 'username', // Свойство или метод, который будет использоваться для текстового представления в выпадающем списке
            'search' => ['name' => 1, 'username' => 1, 'email' => 1]
        ];

        parent::__construct($registry, $options);
    }

    protected function createSuggestQueryBuilder(SuggestQuery $query)
    {
        $qb = parent::createSuggestQueryBuilder($query);

        $qb->field('roles')->equals('ROLE_ADMIN');

        return $qb;
    }
}

Опишите новый сервис в services.yml с тегом sirian_suggest.suggester


    app.suggester.admin:
        class: App\MainBundle\Suggest\AdminSuggester
        arguments: ["@doctrine_mongodb"]
        tags: 
            - {name: 'sirian_suggest.suggester', alias: 'admin'}

Алиас admin будет использоваться в параметре suggester для типа формы SuggestType::class и в url-адресе /suggest/admin .


4. Использование


$formBuilder->add('category', SuggestType::class, [
    'suggester' => 'category'
])

P.S.Больше информации по использованию бандла и дополнительному функционалу вы найдете на странице https://github.com/sirian/suggest-bundle.

Поделиться с друзьями
-->

Комментарии (8)


  1. psylosss
    02.07.2016 12:50

    вместо стандартных типов entity и document
    document? Вероятно, имелся в виду collection?

    Удобный бандл, спасбо!


    1. Sirian
      02.07.2016 14:39
      +1

      Спасибо. Нет, именно document. Это как entity, только для DoctrineMongoDBBundle


  1. qRoC
    02.07.2016 15:55

    Всегда приходилось писать вручную. Спасибо. Только вот jQuery и select2 с этим бандлом нужно будет подключать сверху?


    1. Sirian
      02.07.2016 16:19
      +1

      Да, jquery и select2 в бандле не прилагаются, т.к. на разных проектах разные версии и сборки библиотек используются


      1. qRoC
        02.07.2016 16:56

        Я про то, что снизу их не подключить?


        1. Sirian
          02.07.2016 20:16

          К сожалению так будет тяжелее кастомизировать js опции.

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


  1. alitvinenko
    03.07.2016 23:06

    Пользуюсь этим бандлом уже несколько лет и могу уверенно сказать: это незаменимый бандл во всех моих проектах.

    Так же добавлю, что бандл работает как с Symfony >= 2.8, так и с Symfony 3.


  1. AnisimovAM
    04.07.2016 05:11

    После утсановки бандла

    Опечатка