Symfony UX integration for collection form type

Installs: 2 698

Dependents: 0

Suggesters: 0

Security: 0

Stars: 11

Watchers: 4

Forks: 5

Open Issues: 2



UX collection JS is a Symfony bundle providing Symfony UX integration for collection form type with the help from Symfony Collection JS library.


Bootstrap 3

Screenshot Bootstrap 3

Bootstrap 5

Screenshot Bootstrap 5


Screenshot EasyAdmin


UX Collection JS requires PHP 7.4+ and Symfony 4.4+.

Install this bundle using Composer and Symfony Flex:

composer require tienvx/ux-collection-js:^1.0

# Don't forget to install the JavaScript dependencies as well and compile
yarn add --dev '@symfony/stimulus-bridge@^2.0.0'
yarn install --force
yarn encore dev



Use the new CollectionType class defined by this bundle:

// ...
use Tienvx\UX\CollectionJs\Form\CollectionJsType;

class PostType extends AbstractType
    public function buildForm(FormBuilderInterface $builder, array $options)
            // ...
            ->add('authors', CollectionJsType::class, [
                'entry_type' => TextType::class,
                'prototype' => true,
                'allow_add' => true,
                'allow_delete' => true,
                'allow_move_up' => true,
                'allow_move_down' => true,
                'call_post_add_on_init' => true,
            // ...

    // ...

Then you need to set the form theme:

# config/packages/twig.yaml
      - '@CollectionJs/bootstrap_5_layout.html.twig'

Available themes:

  • @CollectionJs/bootstrap_5_layout.html.twig
  • @CollectionJs/bootstrap_4_layout.html.twig
  • @CollectionJs/bootstrap_3_layout.html.twig


Create webpack entry:

// webpack.config.js
.addEntry('stimulus', './assets/stimulus.js')

Then create that javascript file:

// assets/stimulus.js

// start the Stimulus application
import './bootstrap';

Use the new collection type in the easyadmin controller:

namespace App\Controller\EasyAdmin;

use Tienvx\UX\CollectionJs\Form\CollectionJsType;

class FormFieldReferenceController extends AbstractCrudController
    public function configureCrud(Crud $crud): Crud
        return $crud
            // ...
            ->setFormThemes(['@EasyAdmin/crud/form_theme.html.twig', '@CollectionJs/bootstrap_5_layout.html.twig']);

    public function configureFields(string $pageName): iterable
        yield CollectionField::new('collectionSimple', 'Collection Field (simple)')
                    'entry_type' => CollectionSimpleType::class,
                    'allow_add' => true,
                    'allow_delete' => true,
                    'allow_move_up' => true,
                    'allow_move_down' => true,
                    'call_post_add_on_init' => true,


Config name Description Type Default
prototype CollectionJsType form type need prototype = true Boolean true
allow_add Allow show/hide 'Add a new item' button Boolean false
allow_delete Allow show/hide 'Remove the item' button Boolean false
allow_move_up Allow show/hide 'Move item up' button Boolean false
allow_move_down Allow show/hide 'Move item down' button Boolean false
call_post_add_on_init Trigger 'ux-collection-js:post-add' event on init Boolean false

Stimulus Events

Namespace Event Description Detail
ux-collection-js post-add After an item is added new_elem, context, index
ux-collection-js post-delete After an item is removed delete_elem, context, index
ux-collection-js post-up After an item is moved up elem, switched_elem, index
ux-collection-js post-down After an item is moved down elem, switched_elem, index


// SomeController.php
$form = $this->createFormBuilder($task)
    ->add('some_field', SomeType::class, [
        'attr' => [
            'data-controller' => 'items',
            'data-action' => 'ux-collection-js:post-add->items#postAdd ux-collection-js:post-delete->items#postDelete ',
// items_controller.js
import { Controller } from 'stimulus';

export default class extends Controller {
    postDelete(event) {
        const { delete_elem, context, index } = event.detail;

    postAdd(event) {
        const { new_elem, context, index } = event.detail;


Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.