PHPackages                             arkounay/ux-collection - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. arkounay/ux-collection

ActiveSymfony-bundle[Templating &amp; Views](/categories/templating)

arkounay/ux-collection
======================

Collection for Symfony forms

4.0.3(1y ago)4687.0k↓10.2%5[1 issues](https://github.com/Arkounay/ux-collection/issues)2MITJavaScript

Since Sep 22Pushed 1y ago2 watchersCompare

[ Source](https://github.com/Arkounay/ux-collection)[ Packagist](https://packagist.org/packages/arkounay/ux-collection)[ RSS](/packages/arkounay-ux-collection/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (5)Versions (34)Used By (2)

Ux Collection
=============

[](#ux-collection)

Symfony Collections that works out of the box with Symfony UX

[![demo-gif](https://github.com/arkounay/ux-collection/raw/master/doc/demo.gif)](https://github.com/arkounay/ux-collection/raw/master/doc/demo.gif)

---

#### Note: Incompatible with [Live Components](https://symfony.com/bundles/ux-live-component/current/index.html) for now - use the provided [LiveCollectionType](https://symfony.com/bundles/ux-live-component/current/index.html#using-livecollectiontype) from LiveComponent instead.

[](#note-incompatible-with-live-components-for-now---use-the-provided-livecollectiontype-from-livecomponent-instead)

---

Installation
------------

[](#installation)

**Before you start, make sure you have [StimulusBundle](https://symfony.com/bundles/StimulusBundle/current/index.html) configured in your app.**

Install the bundle using Composer and Symfony Flex:

```
composer require arkounay/ux-collection
```

If you're using WebpackEncore, install your assets and restart Encore (not needed if you're using AssetMapper):

```
npm install --force
npm run watch

# or use yarn
yarn install --force
yarn watch
```

**If you're using bootstrap 5**, you should disable the sandalone CSS import in `assets\controllers.json` :

```
"@arkounay/ux-collection": {
    "collection": {
        "enabled": true,
        "fetch": "eager",
        "autoimport": {
            "@arkounay/ux-collection/src/style.css": true,
            "@arkounay/ux-collection/src/style-when-not-using-bootstrap-5.css": false
        }
    },
    "tabbed_collection": {
        "enabled": true,
        "fetch": "eager",
        "autoimport": {
            "@arkounay/ux-collection/src/tabbed-style.css": true
        }
    }
}
```

Usage
-----

[](#usage)

In a form, use **UxCollectionType**. It works like a classic CollectionType except it has more options : e.g:

```
    use Arkounay\Bundle\UxCollectionBundle\Form\UxCollectionType;

    // ...

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // ...
            ->add('myCollection', UxCollectionType::class, [
                'entry_type' => MyEntryType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'allow_drag_and_drop' => true,
                'drag_and_drop_filter' => 'input,textarea,a,button,label',
                'display_sort_buttons' => true,
                'add_label' => 'Add an item',
                'min' => 3,
                'max' => 10,
            ])
        ;
    }
```

Options
-------

[](#options)

- **allow\_add**: will display the Add button (default true)
- **allow\_delete**: will display the Delete button (default true)
- **allow\_drag\_and\_drop**: will allow the user to change item positions using drag and drop (default true)
- **drag\_and\_drop\_filter**: when drag and drop is allowed, selectors that do not lead to dragging (default true)
- **drag\_and\_drop\_prevent\_on\_filter**: when drag and drop is allowed, calls `event.preventDefault()` when triggered `filter` (default false)
- **display\_sort\_buttons**: will display arrow up and down buttons to change item positions (default true)
- **display\_insert\_button**: will display an insert button under every collection items (so items can be inserted inside the middle of the collection for example), only if `allow_add` is set to true (default false)
- **add\_label**: The add button label (default "Add")
- **insert\_label**: The insert button label (default "Insert")
- **add\_wrapper\_class**: The class used on the add button wrapper (default "mb-3")
- **add\_class**: The class used on the add button (default "btn btn-outline-secondary collection-add")
- **insert\_class**: The class used on the insert button (default "btn btn-outline-secondary btn-collection-insert collection-add")
- **position\_selector**: If a dom selector is specified and it's targetting an input that is located inside a collection item, it will change this input's value and insert its current position (starting from 0) instead of changing the input's name. (ex: `'.position'`)
- **min**: The number of minimum items within the collection. When a collection has `allow_add` set to `true` and has less items than `min` upon creation, empty items will be added and the remove button will remain hidden until more items are created. (default 1)
- **max**: The number of maximum items within the collection. When the collection reaches the maximum number of items, the add button will be hidden. (default null - no limit)

### Nested collections

[](#nested-collections)

- [When using nested collections, remember to change the `prototype_name` of the child's collection. It needs to be different than the parent's collection (that defaults to `__name__`)](https://symfony.com/doc/current/reference/forms/types/collection.html#prototype-name)
- If you're using `position_selector` in both parent and child collections, make sure they are different

### Extend the default behavior

[](#extend-the-default-behavior)

UxCollection allows you to extend its default behavior using a custom Stimulus controller, ie `custom_collection_controller.js`:

```
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {

    connect() {
        this.element.addEventListener('ux-collection:connect', this._onConnect);
        this.element.addEventListener('ux-collection:change', this._onChange);
        this.element.addEventListener('ux-collection:add', this._onAdd);
        this.element.addEventListener('ux-collection:remove', this._onRemove);
    }

    disconnect() {
        this.element.removeEventListener('ux-collection:connect', this._onConnect);
        this.element.removeEventListener('ux-collection:change', this._onChange);
        this.element.removeEventListener('ux-collection:add', this._onAdd);
        this.element.removeEventListener('ux-collection:remove', this._onRemove);
    }

    _onConnect() {
        console.log('The custom collection was just created');
    }

    _onChange() {
        console.log('The custom collection changed');
    }

    _onAdd(event) {
        console.log('An element was added', event.detail);
    }

    _onRemove(event) {
        console.log('An element was removed', event.detail);
    }

}
```

Then in your form, add your controller as an HTML attribute:

```
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        // ...
        ->add('collection', UxCollectionType::class, [
            'attr' => ['data-controller' => 'custom-collection']
        ])
        // ...
    ;
}
```

### Listening to changes from a parent stimulus controller

[](#listening-to-changes-from-a-parent-stimulus-controller)

If you have a parent stimulus controller and want to monitor changes in the collection (such as updating a total number of items or adjusting prices in a cart), you can utilize the ux-collection:change dispatched event and directly invoke a parent's controller method. For example if you have a stimulus controller called `parent` wrapping the collection with a `onCollectionChange` method, it will be called if you add the proper action in the form:

```
$builder->add('collection', UxCollectionType::class, [
    // ...
    'attr' => ['data-action' => 'ux-collection:change->parent#onCollectionChange']
]);
```

### Note about File inputs

[](#note-about-file-inputs)

If your collection contains File inputs, depending on how you use FileType (e.g if you use a collection of VichUploaderBundle), you might have issues when adding/removing/moving items related to how positionning work. Use either the `position_selector` option to fix this, or disable sorting by setting `allow_drag_and_drop` and `display_sort_buttons` to `false`: this way the form name will not change.

### EasyAdmin integration

[](#easyadmin-integration)

For [easyadmin](https://github.com/EasyCorp/EasyAdminBundle) 3+ you need to manually specify the form theme by overriding configureCrud in your DashboardController to add the theme `@ArkounayUxCollection/ux_collection_form_theme.html.twig`

```
public function configureCrud(): Crud
{
    return Crud::new()->addFormTheme('@ArkounayUxCollection/ux_collection_form_theme.html.twig');
}
```

You will need to configure your admin to use WebpackEncore so Symfony UX is taken into account, for example:

```
public function configureAssets(Assets $assets): Assets
{
    return parent::configureAssets($assets)
        ->addWebpackEncoreEntry('app');
}
```

### QAG integration

[](#qag-integration)

This bundle is already included in [QAG](https://github.com/Arkounay/QuickAdminGeneratorBundle) and works out of the box

Extra collections type
----------------------

[](#extra-collections-type)

There is also **UxHorizontalCollectionType** for collections that need to move horizontally, and **UxTabbedCollectionType** that creates a tab-type collection (works only when bootstrap's used in your project for now, and you will probably need to override the base css a bit for this one - here's a [QuickAdminGeneratorBundle](https://github.com/arkounay/QuickAdminGeneratorBundle) integration example)

[![tabbed-demo-gif](https://raw.githubusercontent.com/Arkounay/ux-collection/master/doc/demo-tabbed.gif)](https://raw.githubusercontent.com/Arkounay/ux-collection/master/doc/demo-tabbed.gif)

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity44

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 93% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~39 days

Recently: every ~116 days

Total

32

Last Release

519d ago

Major Versions

1.1.4 → 2.0.02021-12-14

2.3.1 → v3.x-dev2022-09-20

v2.x-dev → 3.0.02022-09-20

3.3.3 → 4.0.02024-03-01

### Community

Maintainers

![](https://www.gravatar.com/avatar/a6e42acfea7651328f0b5c55d9aa4ba51c0327ce23962a2f2bff34d423dcd77e?d=identicon)[Arkounay](/maintainers/Arkounay)

---

Top Contributors

[![Arkounay](https://avatars.githubusercontent.com/u/9340719?v=4)](https://github.com/Arkounay "Arkounay (53 commits)")[![endelwar](https://avatars.githubusercontent.com/u/28512?v=4)](https://github.com/endelwar "endelwar (2 commits)")[![priyadi](https://avatars.githubusercontent.com/u/1102197?v=4)](https://github.com/priyadi "priyadi (1 commits)")[![xDeSwa](https://avatars.githubusercontent.com/u/33868586?v=4)](https://github.com/xDeSwa "xDeSwa (1 commits)")

---

Tags

symfonysymfony-bundlesymfony-collectionsymfony-formsymfony-uxsymfony-ux

### Embed Badge

![Health badge](/badges/arkounay-ux-collection/health.svg)

```
[![Health](https://phpackages.com/badges/arkounay-ux-collection/health.svg)](https://phpackages.com/packages/arkounay-ux-collection)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M388](/packages/easycorp-easyadmin-bundle)[kimai/kimai

Kimai - Time Tracking

4.8k9.0k1](/packages/kimai-kimai)[ehyiah/ux-quill

Symfony UX Bundle to use Quill JS wysiwyg text editor with full and easy customisation

6492.2k3](/packages/ehyiah-ux-quill)[oro/platform

Business Application Platform (BAP)

645143.5k115](/packages/oro-platform)[symfony/ux-icons

Renders local and remote SVG icons in your Twig templates.

567.3M140](/packages/symfony-ux-icons)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1616.4k14](/packages/2lenet-crudit-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
