SuggestBundle или выпадающие ajax списки в Symfony

в 13:45, , рубрики: php, select2, suggest-bundle, symfony

Практически во всех проектах возникает необходимость отобразить выпадающий список в форме, данный в котором грузились бы с помощью 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 SirianSuggestBundleSirianSuggestBundle(),
        // ...
    );
    ...
}

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

use AppMainBundleDocumentUser;
use DoctrineCommonPersistenceManagerRegistry;
use SirianSuggestBundleSuggestDocumentSuggester;
use SirianSuggestBundleSuggestItem;
use SirianSuggestBundleSuggestSuggestQuery;

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: AppMainBundleSuggestAdminSuggester
        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.

Автор: Sirian

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js