Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/arkounay/ux-collection
Collection for Symfony forms using Symfony UX
https://github.com/arkounay/ux-collection
symfony symfony-bundle symfony-collection symfony-form symfony-ux
Last synced: 3 days ago
JSON representation
Collection for Symfony forms using Symfony UX
- Host: GitHub
- URL: https://github.com/arkounay/ux-collection
- Owner: Arkounay
- License: mit
- Created: 2021-09-22T14:30:56.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2024-10-28T21:48:35.000Z (17 days ago)
- Last Synced: 2024-10-28T22:32:48.002Z (17 days ago)
- Topics: symfony, symfony-bundle, symfony-collection, symfony-form, symfony-ux
- Language: JavaScript
- Homepage:
- Size: 215 KB
- Stars: 37
- Watchers: 3
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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)
---
#### 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.
---## 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:
```sh
composer require arkounay/ux-collection
```If you're using WebpackEncore, install your assets and restart Encore (not needed if you're using AssetMapper):
```sh
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` :
```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
In a form, use **UxCollectionType**. It works like a classic CollectionType except it has more options :
e.g:```php
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
- **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
- [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
UxCollection allows you to extend its default behavior using a custom Stimulus controller, ie `custom_collection_controller.js`:
```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:
```php
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
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:
```php
$builder->add('collection', UxCollectionType::class, [
// ...
'attr' => ['data-action' => 'ux-collection:change->parent#onCollectionChange']
]);
```### 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
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`
```php
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:
```php
public function configureAssets(Assets $assets): Assets
{
return parent::configureAssets($assets)
->addWebpackEncoreEntry('app');
}
```### QAG integration
This bundle is already included in [QAG](https://github.com/Arkounay/QuickAdminGeneratorBundle) and works out of the box
## 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)