hello-sebastian / hello-stimulus-bundle
Symfony Bundle with Stimulus.js Helper functions
Installs: 955
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=7.1.3
- sensio/framework-extra-bundle: ^5.1
- symfony/form: ^4.4|^5.0
- symfony/twig-bundle: ^4.4|^5.0
This package is auto-updated.
Last update: 2025-04-09 01:29:21 UTC
README
This Bundle provides Twig and Symfony form helper functions for Stimulus.js.
Overview
Features
- Twig helper functions
- Symfony Forms helper functions
Installation
Step 1: Download the Bundle
Open a command console, enter your project directory and execute the following command to download this bundle:
$ composer require hello-sebastian/hello-stimulus-bundle
Step 2: Enable the Bundle (without flex)
Then, enable the bundle by adding it to the list of registered bundles in the config/bundles.php
file of your project:
// config/bundles.php return [ // ... HelloSebastian\HelloStimulusBundle\HelloStimulusBundle::class => ['all' => true], ];
Twig helper functions
hello_stimulus_controller(controllerName, values = [])
Render value controller attribute. Optional with values.
Parameters
controllerName: name of the controller
values: array of stimulus values (optional)
Examples
<div {{ hello_stimulus_controller('hello') }}></div> <div {{ hello_stimulus_controller('hello', [ {name: 'myValue', value: 'Hey!'}, {name: 'myNumber', value: 1234} ]) }}></div>
is rendered to
<div data-controller="hello"></div> <div data-controller="hello" data-hello-my-value-value="Hey!" data-hello-my-number-value="1234"></<div>
You can use two ways to specify the controller:
Assuming the controller is located at assets/controllers/user/user_form_controller.js
-
the "HTML" stimulus type
<div {{ hello_stimulus_controller('user--user-form') }}></div> {# rendered to data-controller="user--user-form" #}
-
the "JavaScript" type
<div {{ hello_stimulus_controller('user/user_form') }}></div> {# rendered to data-controller="user--user-form" #}
Both variants give the same result.
hello_stimulus_target(controllerName, target)
Render value target attribute.
Parameters
controllerName: name of controller for this target
target: name of the target attribute
Examples
<h1 {{ hello_stimulus_target('hello', 'greeting') }}></h1>
is rendered to
<div data-hello-target="greeting"></div>
hello_stimulus_action(controllerName, event, method)
Render action data attribute.
Parameters
controllerName: name of controller for this action
event: DOM event to listen for
method: name of the JavaScript method inside the controller class
Examples
<button type="button" {{ hello_stimulus_action('hello', 'click', 'handleBtnClick') }}> Hey! </button>
is rendered to
<button type="button" data-action="click->hello#handleBtnClick"> Hey! </button>
hello_stimulus_value(controllerName, name, value)
Render value data attribute.
Parameters
controllerName: name of controller for this value
name: name of this value
value: value of this value
Examples
<div {{ hello_stimulus_value('hello', 'username', 'hello_sebastian') }}></div>
is rendered to
<div data-hello-username-value="hello_sebastian"></div>
Form helper functions
In Symfony Forms it is helpful to pass attributes of stimulus directly to the types. For this purpose, this bundle provides a helper class with two methods (target()
and value()
).
Full example of StimulusFormHelper
StimulusFormHelper API
__construct(controllerName, defaultEvent = "click")
Paramters
controllerName: name (and location) of the JavaScript controller class
defaultEvent: (optional): default DOM event to listen for (default is the "click" event)
Usage
You can use two ways to specify the controller:
Assuming the controller is located at assets/controllers/user/user_form_controller.js
-
the "HTML" stimulus type
$this->formController = new StimulusFormHelper('user--user-form'); // rendered to data-controller="user--user-form" to the form tag
-
the "JavaScript" type
$this->formController = new StimulusFormHelper('user/user_form'); // rendered to data-controller="user--user-form" to the form tag
Both variants give the same result.
target(target)
Parameters
target: name of target property inside stimulus controller
Returns
array("data-[controllerName]-target" => "[target]");
Usage
->add('firstName', TextType::class, array( 'label' => 'First name', 'attr' => $this->formController->target('firstNameInput') ))
action(method, event = null)
Parameters
method: name of JavaScript method inside stimulus controller
event: (optional) DOM event to listen for (if null, default event from constructor is taken)
Returns
array("data-action" => "[event]->[controllerName]#[method]");
Usage
->add('isActive', CheckboxType::class, array( 'label' => 'is Active', 'required' => false, 'attr' => $this->formController->action("handleIsActive", "change") ))
Example
//src/Form namespace App\Form; use App\Entity\User; use HelloSebastian\HelloStimulusBundle\Form\StimulusFormHelper; // <-- don't forget this use statement use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; class UserType extends AbstractType { private $userFormController; public function __construct() { $this->formController = new StimulusFormHelper('user-form'); } public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('firstName', TextType::class, array( 'label' => 'First name', 'attr' => $this->formController->target('firstNameInput') )) ->add('lastName', TextareaType::class, array( 'label' => 'Last name', 'label_attr' => $this->formController->target('lastNameLabel') 'attr' => $this->formController->target('lastNameInput') )) ->add('email', TextareaType::class, array( 'label' => 'Email' )) ->add('isActive', CheckboxType::class, array( 'label' => 'is Active', 'required' => false, // if you want to use both inside the same attr, you can use array_merge() 'attr' => array_merge( $this->formController->action("handleIsActive", "change"), $this->formController->target("isActiveCheckbox"), array('class' => 'my-checkbox-class') ) )) ; } public function buildView(FormView $view, FormInterface $form, array $options) { $this->formController->setControllerNameToFormView($view); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => User::class, )); } }
action
and traget
return an array. If you want to use both inside the same attr
, you can use array_merge()
.