Installation:
composer require braunstetter/choosy
Ensure Encore (Webpack Encore) is configured in your Laravel project (this package relies on frontend assets).
First Use Case:
Add ChoosyType to a form builder in a controller or form class:
use Braunstetter\ChoosyBundle\Form\Type\ChoosyType;
$form = $this->createFormBuilder()
->add('tags', ChoosyType::class, [
'choices' => [
'Option 1' => 'value1',
'Option 2' => 'value2',
],
])
->getForm();
Frontend Setup: Run the provided Yarn commands (from the README) to compile assets:
yarn --cwd ./vendor/braunstetter/choosy/src/Resources/assets install --force
yarn --cwd ./vendor/braunstetter/choosy/src/Resources/assets dev
Ensure the compiled JS/CSS is included in your layout (e.g., via @braunstetter_choosy/styles in your Webpack entry).
Basic Tag Picker:
Use ChoosyType for simple key-value choices (e.g., predefined tags):
$builder->add('predefinedTags', ChoosyType::class, [
'choices' => ['Admin' => 'admin', 'User' => 'user'],
'multiple' => true, // Enable multi-select
]);
Entity-Based Picker:
Use ChoosyEntityType for dynamic database-backed options (e.g., fetching tags from a Tag model):
$builder->add('dynamicTags', ChoosyEntityType::class, [
'class' => Tag::class,
'property' => 'name', // Display property
'multiple' => true,
]);
Customizing Choosy Options: Pass JavaScript options directly (see Choosy docs):
$builder->add('searchableTags', ChoosyType::class, [
'choices' => [],
'options' => [
'js_options' => [
'search' => true,
'placeholder' => 'Search tags...',
],
],
]);
Integration with Form Events:
Dynamically populate choices via PRE_SET_DATA or PRE_SUBMIT:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$data = $event->getData();
$choices = $this->tagRepository->findByUser($data->getUser());
$event->getForm()->add('tags', ChoosyType::class, [
'choices' => $choices,
]);
});
Validation:
Use Symfony’s validation constraints (e.g., NotBlank, Valid) alongside Choosy:
$builder->add('requiredTags', ChoosyType::class, [
'choices' => [],
'constraints' => [
new NotBlank(),
],
]);
Asset Compilation:
yarn dev (or yarn build) is executed after installation. Check your webpack.mix.js includes:
mix.encore
.addEntry('choosy', './vendor/braunstetter/choosy/src/Resources/assets/js/choosy.js')
.copyDirectories(['./vendor/braunstetter/choosy/src/Resources/public', 'public/build']);
EntityType Dependencies:
ChoosyEntityType requires Doctrine ORM (or a compatible entity manager).Tag entity (or similar) is properly mapped and the class option points to a valid entity class.JavaScript Conflicts:
js_options to customize selectors:
'options' => [
'js_options' => [
'selector' => '.my-choosy-picker',
],
],
Empty Choices:
choices array may break rendering.PRE_SET_DATA or provide a fallback:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$choices = $event->getData()['choices'] ?? [];
if (empty($choices)) {
$form->add('tags', ChoosyType::class, ['choices' => []]);
}
});
Check Compiled Assets: Verify the Choosy JS/CSS is output in your template:
{{ encore_entry_script_tags('choosy') }}
{{ encore_entry_link_tags('choosy') }}
Inspect Browser Console:
Look for errors like Choosy is not defined (missing JS) or 404 (asset paths).
Symfony Profiler: Use the profiler to inspect form data and submitted values for debugging:
dump($form->getData());
Custom Templates:
Override the default Twig template by setting the template option:
$builder->add('tags', ChoosyType::class, [
'template' => '@YourBundle/choosy/custom_template.html.twig',
]);
Dynamic Choices via AJAX:
Use js_options to fetch choices dynamically:
'options' => [
'js_options' => [
'ajax' => [
'url' => '/api/tags',
'dataType' => 'json',
],
],
],
Event Listeners: Extend functionality with form events (e.g., post-submit processing):
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$data = $event->getData();
// Process Choosy-submitted data (e.g., normalize values)
});
Localization: Customize labels/placeholders via translation domains:
# config/packages/braunstetter_choosy.yaml
braunstetter_choosy:
default_options:
js_options:
placeholder: '{{ "choosy.placeholder"|trans }}'
How can I help you explore Laravel packages today?