ninsuo/symfony-collection
A lightweight PHP collection library inspired by Symfony, offering fluent, chainable APIs for working with arrays and iterables. Includes helpers for mapping, filtering, sorting, grouping, reducing, and more—usable standalone or alongside Laravel and other frameworks.
Installation Add the package via Composer:
composer require ninsuo/symfony-collection
(Note: Despite the description mentioning jQuery, this package is actually a PHP library for Symfony forms. Verify compatibility with your Symfony/Laravel version.)
Basic Usage
In a Symfony form builder, use the CollectionType with the allow_add and allow_delete options:
use Ninsuo\Collection\CollectionType;
$builder->add('items', CollectionType::class, [
'entry_type' => ItemType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true, // Required for dynamic additions
]);
First Use Case Render the form in a Twig template and ensure JavaScript (jQuery) is loaded for dynamic interactions:
{{ form_start(form) }}
{{ form_widget(form.items) }}
<button type="button" class="add-item">Add Item</button>
{{ form_end(form) }}
Dynamic Addition/Deletion
Use the add-item and remove-item buttons with the following JS (jQuery):
$('.add-item').click(function() {
var prototype = $('#items_prototype').html();
var index = $('#items').data('index');
var newItem = prototype.replace(/__name__/g, index);
$('#items').append(newItem);
index++;
$('#items').data('index', index);
});
$('.remove-item').click(function() {
$(this).closest('.item').remove();
});
Nested Collections
For nested collections (e.g., items.subItems), ensure the prototype template includes the correct __name__ placeholders:
{% for subItem in form.items.subItems %}
{{ form_widget(subItem) }}
<button type="button" class="remove-sub-item">Remove</button>
{% endfor %}
Validation Handling Validate the entire collection before submission:
$('#form').submit(function() {
if (!$('#items').hasClass('valid')) {
alert('Please fix errors in items before submitting.');
return false;
});
FormComponent in Laravel via symfony/form or laravel-bridge. Example:
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Ninsuo\Collection\CollectionType as NinsuoCollectionType;
// Replace CollectionType with NinsuoCollectionType for enhanced features.
// In a service provider or blade template
@push('scripts')
<script src="{{ asset('vendor/ninsuo-collection/js/collection.js') }}"></script>
@endpush
vendor/ninsuo/symfony-collection/Resources/views/ to your project’s templates/NinsuoCollection/ directory.Maintenance Warning The package is not maintained (as per the description). Use at your own risk, or consider alternatives like:
CollectionType with custom JS.stof/doctrine-extensions for ORM-level collection handling.spatie/laravel-collection-macros.jQuery Dependency The package relies on jQuery for dynamic interactions. If using Laravel Mix/Vite, ensure jQuery is included:
// vite.config.js or webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
.jquery();
CSRF Token Conflicts When dynamically adding items, ensure CSRF tokens are included in the prototype template:
{{ form_hidden(form.items.vars.csrf_token) }}
Prototype Template Missing
Forgetting to set 'prototype' => true in the form builder will break dynamic additions. Always include:
'prototype' => true,
console.log($('#items_prototype').length); // Should be > 0
dd($request->request->all()); // Check for 'items' array structure
Custom JavaScript
Extend the default behavior by overriding the add-item and remove-item handlers:
$(document).on('click', '.custom-add-item', function() {
// Custom logic (e.g., AJAX validation)
var prototype = $('#items_prototype').html().replace(/__name__/g, $('#items').data('index'));
// ...
});
Twig Template Overrides Customize the rendering of collection items by extending the base template:
{# app/Resources/views/NinsuoCollection/collection_widget.html.twig #}
<div class="custom-item">
{{ form_row(item) }}
<button type="button" class="remove-item">Remove</button>
</div>
Laravel Form Requests
Validate collections in Laravel’s FormRequest:
public function rules()
{
return [
'items.*' => ['required', 'string', 'max:255'],
];
}
How can I help you explore Laravel packages today?