Symfony Forms একটি অত্যন্ত শক্তিশালী টুল যা ডেটা সংগ্রহ, প্রক্রিয়া, এবং প্রেজেন্টেশন কাজগুলোকে সহজ করে তোলে। তবে, যখন ফর্মের মধ্যে জটিল সম্পর্ক বা সাব-ফর্ম ব্যবহারের প্রয়োজন হয়, তখন Collection Type এবং Embedded Forms খুবই গুরুত্বপূর্ণ। এই দুইটি ব্যবহার করে, আপনি একটি ফর্মের মধ্যে আরো জটিল ফর্ম স্ট্রাকচার তৈরি করতে পারেন, যেমন ডাইনামিক ফর্ম ফিল্ড, সাবমিশন ফর্ম বা সম্পর্কিত ডেটা।
Collection Type (কলেকশন টাইপ)
Collection Type ব্যবহার করে একটি ফর্মের মধ্যে একাধিক সাব-ফর্ম তৈরি করা হয়, যেমন আপনি একটি ব্যবহারকারীর জন্য একাধিক ফোন নম্বর বা ঠিকানা সংগ্রহ করতে পারেন। এটি একটি ফর্মে একাধিক সাব-ফর্মের ইনপুট গ্রহণ করার সুযোগ দেয়, যা FormType এর মাধ্যমে করা হয়।
CollectionType এর মৌলিক ব্যবহার:
ধরা যাক, আপনার একটি ফর্মে ব্যবহারকারীর একাধিক ঠিকানা সংযুক্ত করার জন্য একটি addresses নামে একটি কলেকশন ফিল্ড তৈরি করতে চান।
কোড উদাহরণ:
Entity ফাইল (AddressEntity.php)
প্রথমেAddressনামে একটি Entity তৈরি করি:// src/Entity/Address.php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Address { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] private $id; #[ORM\Column(type: 'string')] private $street; #[ORM\Column(type: 'string')] private $city; // Getters and Setters... }Form Type (UserType.php)
এরপর,Userফর্মের মধ্যেaddressesকলেকশন ফিল্ড তৈরি করতে হবে:// src/Form/UserType.php namespace App\Form; use App\Entity\User; use App\Entity\Address; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('email', EmailType::class) ->add('addresses', CollectionType::class, [ 'entry_type' => AddressType::class, // AddressType ফর্ম ব্যবহার করা হবে 'allow_add' => true, // নতুন Address অ্যাড করার সুযোগ 'by_reference' => false, 'allow_delete' => true, // ডিলিট করার সুযোগ ]); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => User::class, ]); } }Address Subform (AddressType.php)
AddressTypeফর্মেstreetএবংcityফিল্ড তৈরি করতে হবে।// src/Form/AddressType.php namespace App\Form; use App\Entity\Address; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class AddressType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('street', TextType::class) ->add('city', TextType::class); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Address::class, ]); } }Controller
ফর্মটি কন্ট্রোলারে রেন্ডার করা:// src/Controller/UserController.php namespace App\Controller; use App\Entity\User; use App\Form\UserType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class UserController extends AbstractController { #[Route('/user', name: 'user_create')] public function create(Request $request): Response { $user = new User(); $form = $this->createForm(UserType::class, $user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // ডেটাবেসে সেভ করা $entityManager = $this->getDoctrine()->getManager(); $entityManager->persist($user); $entityManager->flush(); return $this->redirectToRoute('success'); } return $this->render('user/create.html.twig', [ 'form' => $form->createView(), ]); } }Template (Twig Template)
Twig টেমপ্লেটে ফর্ম রেন্ডার করা:{# templates/user/create.html.twig #} {{ form_start(form) }} {{ form_row(form.email) }} <div> {{ form_label(form.addresses) }} <div> {{ form_widget(form.addresses) }} </div> <button type="button" class="add-address">Add Address</button> </div> <button type="submit">Submit</button> {{ form_end(form) }}
উল্লেখযোগ্য বিষয়:
allow_add: ব্যবহারকারী নতুন আইটেম অ্যাড করতে পারবে।allow_delete: ব্যবহারকারী কোনো আইটেম ডিলিট করতে পারবে।by_reference:falseসেট করলে নতুন আইটেম তৈরি হবে এবং পুরোনো আইটেমগুলো আপডেট হবে।
Embedded Forms (এম্বেডেড ফর্মস)
Embedded Forms হল এমন একটি ফিচার যার মাধ্যমে আপনি একটি ফর্মের মধ্যে অন্য ফর্ম এম্বেড করতে পারেন। এটি সাধারণত OneToMany বা ManyToMany রিলেশনships ব্যবহারের সময় প্রয়োজন হয়, যেমন একটি User এর সাথে Address সম্পর্ক। Symfony-তে এটি Embedded Forms ব্যবহার করে করা হয়।
Embedded Forms উদাহরণ:
উপরের Collection Type উদাহরণে, addresses ফিল্ডটি একটি Embedded Form হিসেবে কাজ করছে, যেখানে AddressType ফর্মটি UserType ফর্মের মধ্যে এম্বেড করা হয়েছে।
এডভান্সড ফর্মস: Dynamic Collection Type
Symfony ফর্মে ডাইনামিক ফর্ম তৈরি করতে আপনি JavaScript ব্যবহার করতে পারেন। ব্যবহারকারীরা ফর্মে নতুন ইনপুট ফিল্ড অ্যাড করতে পারবে বা ডিলিট করতে পারবে।
JavaScript দিয়ে Dynamic Collection Type:
JavaScript ফাইল:
// public/js/app.js document.addEventListener('DOMContentLoaded', function () { const addButton = document.querySelector('.add-address'); const formContainer = document.querySelector('#addresses'); addButton.addEventListener('click', function () { const newForm = formContainer.querySelector('div').cloneNode(true); formContainer.appendChild(newForm); }); });Twig Template:
<div id="addresses"> {{ form_widget(form.addresses) }} </div> <button type="button" class="add-address">Add Address</button>
এখানে, একটি "Add Address" বাটন থাকবে যা ক্লিক করলে নতুন Address ফর্ম তৈরি হবে।
সারাংশ
Symfony-তে CollectionType এবং Embedded Forms এর মাধ্যমে আপনি জটিল ফর্ম স্ট্রাকচার তৈরি করতে পারেন, যেমন একাধিক সাব-ফর্ম বা সম্পর্কিত ডেটা ফর্ম। এটি OneToMany বা ManyToMany সম্পর্কের জন্য বিশেষভাবে উপযোগী। CollectionType আপনাকে ডাইনামিকলি ফর্মে আইটেম যোগ বা মুছে ফেলার সুযোগ দেয়, যা ব্যবহারকারী অভিজ্ঞতা উন্নত করে। Symfony ফর্ম সিস্টেমটি একটি অত্যন্ত শক্তিশালী টুল, যা আপনার অ্যাপ্লিকেশনটিকে অত্যন্ত কাস্টমাইজেবল এবং স্কেলেবল করে তোলে।