Installation
composer require edfa3ly/handy-form-bundle
Add to config/bundles.php:
return [
// ...
Edfa3ly\HandyFormBundle\Edfa3lyHandyFormBundle::class => ['all' => true],
];
First Use Case Use a custom form type in a Symfony form builder:
use Edfa3ly\HandyFormBundle\Form\Type\DatePickerType;
$builder->add('eventDate', DatePickerType::class);
Ensure jQueryUI assets are loaded in your template:
{{ encore_entry_link_tags('app') }}
Where to Look First
Resources/doc/index.md for detailed usage.Form/Type/ for available form types.Resources/public/js/ for JS dependencies.Basic Integration Replace standard Symfony form types with bundle equivalents:
// Before
$builder->add('birthday', DateType::class);
// After
$builder->add('birthday', DatePickerType::class, [
'widget_attr' => ['class' => 'datepicker']
]);
Dynamic Form Fields
Use CollectionType for dynamic fields (e.g., multi-step forms):
$builder->add('items', CollectionType::class, [
'entry_type' => TextType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
]);
Dependent Fields
Chain Select2DependentFieldType for cascading selects:
$builder->add('country', CountryType::class);
$builder->add('state', StateType::class, [
'dependent_field' => 'country',
]);
Asset Management Load jQueryUI assets via Webpack Encore:
// webpack.config.js
Encore
.addEntry('app', './assets/app.js')
.copyFiles({
from: './vendor/edfa3ly/handy-form-bundle/public',
to: 'bundles/handy-form/[path][name].[ext]'
});
TinyMCE Integration
Configure TinyMCE in config/packages/edfa3ly_handy_form.yaml:
edfa3ly_handy_form:
tinymce:
api_key: 'your-api-key'
plugins: ['advlist', 'autolink']
MultiSelectType with ThraceDataGridBundle for grid-based selects.use Symfony\Component\Validator\Constraints as Assert;
$builder->add('rating', RatingType::class, [
'constraints' => [new Assert\NotBlank(), new Assert\Range(['min' => 1, 'max' => 5])],
]);
templates/Edfa3lyHandyFormBundle/ to customize rendering.Asset Loading
jquery-ui is installed and loaded before bundle JS:
{{ encore_entry_script_tags('app') }}
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
PHP Version Compatibility
composer.json for php requirement and test locally.TinyMCE API Key
edfa3ly_handy_form.yaml configuration or use a free key from TinyMCE.CollectionType Prototype
prototype: true and allow_add: true are set, and check for JS errors in browser console.Recaptcha
sitekey/secret.config/packages/edfa3ly_handy_form.yaml:
edfa3ly_handy_form:
recaptcha:
site_key: 'your-site-key'
secret: 'your-secret-key'
/_profiler) to inspect form rendering issues.dump($form->createView());
Custom Form Types
Extend existing types (e.g., DatePickerType) by creating a subclass:
use Edfa3ly\HandyFormBundle\Form\Type\DatePickerType as BaseDatePicker;
class CustomDatePickerType extends BaseDatePicker {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(['custom_option' => true]);
}
}
Override Templates
Copy Resources/views/Form/ to templates/Edfa3lyHandyFormBundle/Form/ to customize Twig templates.
Configuration
Extend bundle config in config/packages/edfa3ly_handy_form.yaml:
edfa3ly_handy_form:
default_options:
widget_attr:
class: 'my-custom-class'
Event Listeners
Subscribe to form events (e.g., PRE_SET_DATA) to modify behavior:
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$data = $event->getData();
// Modify form based on $data
});
lazy: true for large collections to improve performance.Select2DependentFieldType, handle AJAX responses in a custom JS file:
$(document).on('change', '#country', function() {
$.get('/api/states/' + $(this).val(), function(states) {
$('#state').html(states).trigger('change');
});
});
$formFactory = $this->createMock(FormFactoryInterface::class);
$formFactory->expects($this->once())
->method('createNamed')
->with('form', DatePickerType::class, $options)
->willReturn($form);
How can I help you explore Laravel packages today?