src/Twig/TodoListFormComponent.php
use App\Entity\TodoList;
use App\Form\TodoListForm;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;
#[AsLiveComponent('todo_list_form')]
class TodoListFormComponent extends AbstractController
{
use ComponentWithFormTrait;
use DefaultActionTrait;
#[LiveProp(fieldName: 'formData')]
public ?TodoList $todoList;
protected function instantiateForm(): FormInterface
{
return $this->createForm(
TodoListForm::class,
$this->todoList
);
}
#[LiveAction]
public function addItem(): void
{
$this->formValues['todoItems'][] = [];
}
#[LiveAction]
public function removeItem(#[LiveArg] int $index): void
{
unset($this->formValues['todoItems'][$index]);
}
}
templates/components/todo_list_form.html.twig
<div
{{ attributes }}
>
{{ form_start(form) }}
<div class="row">
<div class="col-4">
{{ form_row(form.name, {
label: false,
attr: {
placeholder: 'Give your list a name'
}
}) }}
</div>
</div>
<table class="table table-borderless form-no-mb">
<thead>
<tr>
<td>Item</td>
<td>Priority</td>
</tr>
</thead>
<tbody>
{% for key, itemForm in form.todoItems %}
<tr>
<td>
{{ form_row(itemForm.description, {
label: false,
attr: {
placeholder: 'Walk the pygmy hippo'
}
}) }}
</td>
<td>
{{ form_row(itemForm.priority, {
row_attr: {class: ''},
label: false,
}) }}
</td>
<td>
<button data-action="live#action" data-action-name="removeItem(index={{ key }})" type="button" class="btn btn-outline-danger">X</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% do form.todoItems.setRendered %}
<button data-action="live#action" data-action-name="addItem" type="button" class="btn btn-outline-primary">+ Add Item</button>
<button type="submit" class="btn btn-success" formnovalidate>Save</button>
{{ form_end(form) }}
</div>