Chào mọi người hôm nay mình sẽ tiếp tục với FormType trong Symfony Framework hôm trước mình đã hướng dẫn cách sử dụng các field type phổ biến hay thường gặp. Tiếp tục bài hôm nay mình sẽ hướng dẫn các bạn làm thế nào để có thể tạo ra nested form
trong Symfony như thế nào nhé
Giới Thiệu:
Với các framework khác thì chúng ta thường gọi là nested form
nhưng đối với Symfony thì nó là Collection Type
field type này thường được sử dụng để render ra các collection
form con chứa bên trong một form lớn, chúng ta có thể dễ dàng thực hiện các thao tác thêm, xóa, sửa, validate trên collection
form con. VD:
Bạn có 2 entity (model) là Task và Tag mối liên kết giữa 2 entity này là one-to-many (1 Task – N Tag), bây giờ chúng ta tạo ra 1 form là của Task
bên trong form này chúng ta chứa nhiều các input control form của Tag
.
Nested form (CollectionType Field)
Tạo Entity (Model)
Trước khi bắt đầu mình sẽ tạo ra 2 entity là Task
và Tag
như sau:
- src/Entity/Task.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | namespace AppEntity; use DoctrineCommonCollectionsArrayCollection; class Task { protected $description; protected $tags; public function __construct() { $this->tags = new ArrayCollection(); } public function getDescription() { return $this->description; } public function setDescription($description) { $this->description = $description; } public function getTags() { return $this->tags; } } |
- src/Entity/Tag.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace AppEntity; class Tag { private $name; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } |
Tạo FormType
Tiếp theo mình sẽ tạo ra 2 form type tương ứng với 2 entity trên là TaskType
và TagType
nếu các bạn đã quên cách tạo form type như thế nào thì các bạn có thể tham khảo ở các bài viết trước mình có hướng dẫn cách tạo form type:
- src/Form/TaskType.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // src/Form/TaskType.php namespace AppForm; use AppEntityTask; use SymfonyComponentFormAbstractType; use SymfonyComponentFormFormBuilderInterface; use SymfonyComponentOptionsResolverOptionsResolver; class TaskType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('description'); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Task::class, ]); } } |
- src/Form/TagType.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | namespace AppForm; use AppEntityTag; use SymfonyComponentFormAbstractType; use SymfonyComponentFormFormBuilderInterface; use SymfonyComponentOptionsResolverOptionsResolver; class TagType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('name'); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Tag::class, ]); } } |
Bây giờ chúng ta đã tạo ra được 2 form type tương ứng với 2 entity là Task
và Tag
, bây giờ mình sẽ add TagType
vào trong TaskType
như 1 collection type hay nested như sau:
Ở trong file src/Form/TaskType.php
các bạn add thêm 1 type là CollectionType
với field option entry_type
link đến TagType
:
1 2 3 4 5 6 7 8 9 10 | public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('description') ->add('tags', CollectionType::class, [ 'entry_type' => TagType::class, 'entry_options' => ['label' => false], ]); } |
OK đến bước này là bạn đã tạo ra được 1 form type Task
bên trong chứa form type Tag
là nested form. Bây giờ công việ cuối cùng chúng ta sẽ phải hiển thị nó lên view.
Render template
Các bạn mở bất kì template .twig
nào mà các bạn muốn nó hiển thị ra và làm như thế này:
1 2 3 4 5 6 7 8 9 10 11 | {{ form_start(form) }} {{ form_row(form.description) }} --> field này là của Task <h3>Tags</h3> <ul class="tags"> {% for tag in form.tags %} <li>{{ form_row(tag.name) }}</li> --> field này là của Tag {% endfor %} </ul> {{ form_end(form) }} |
Kết luận
Trên đây mình đã hướng dẫn làm thế nào để tạo ra nested form trong symfony một phần cũng rất cần thiết và hay gặp trong các dự án chạy symfony cũng khá là thú vị đúng không nhỉ Ở các phần tiếp theo mình sẽ hướng dẫn làm thế nào để có thể thực hiện các thao tác thêm, xóa, sửa, validate cho nested form nhé
Tham khảo
https://symfony.com/doc/current/reference/forms/types/collection.html