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)4573.4k↓17%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 1mo 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

45

—

FairBetter than 93% of packages

Maintenance41

Moderate activity, may be stable

Popularity43

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

473d 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

[kimai/kimai

Kimai - Time Tracking

4.6k7.4k1](/packages/kimai-kimai)[symfony/ux-icons

Renders local and remote SVG icons in your Twig templates.

555.8M69](/packages/symfony-ux-icons)[ehyiah/ux-quill

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

5868.1k2](/packages/ehyiah-ux-quill)[artgris/filemanager-bundle

FileManager is a simple Multilingual File Manager Bundle for Symfony

182420.8k9](/packages/artgris-filemanager-bundle)[ibexa/oss

A meta package for installing Ibexa Open Source

19772.4k11](/packages/ibexa-oss)[symfony/ux-toolkit

A tool to easily create a design system in your Symfony app with customizable, well-crafted Twig components

1432.0k](/packages/symfony-ux-toolkit)

PHPackages © 2026

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