I create 2 forms not linked to any entity in the same controller.
Each form have it owns submitted button.
I never goes to the submitted function of the second form.
I think it is because the 2 forms have same default name 'form'.
The problem is how to change the form name?
Below what I did
public function index(Request $request)
{
$form1 = $this->createFormBuilder()
->add('sn', TextType::class, [
'required' => false,
])
->add('search', SubmitType::class, ['label' => 'Search'])
->getform();
$form1->handleRequest($request);
if ($form1->isSubmitted() && $form1->isValid()) {
//Do something
}
$form2 = $this->createFormBuilder();
$form2->add('Agree', CheckboxType::class, [
'label' => 'Agree',
'required' => false,
]);
$form2->add('detail', SubmitType::class, ['label' => 'Detail']);
$form2 = $form2->getForm();
$form2->handleRequest($request);
if ($form2->isSubmitted() && $form2->isValid()) {
//Do something else
}
return $this->render('search/index.html.twig', [
'form1' => $form1->createView(),
'form2' => $form2->createView(),
]);
}
If you want to modify the form name, use the createNamed() method:
$form1 = $this
->get('form.factory')
->createNamed('my_name', TextType::class, $task);
You can even suppress the name completely by setting it to an empty string.
Related
I was posting a Symfony form via AJAX post and after I made a field edit on my "Siparis" entity and related form field in "SiparisType" I keep getting 419 on post.
Symfony version: 6.0.2 - PHP version:8.1.2 Database: 10.4.22-MariaDB
I tried to disable csrf protection and still getting the same status 419 and nothing else.
Symfony route to handle AJAX post(I reverted my latest changes after editing the field below version was working fine earlier):
#[Route('/save/', name: 'save', methods: ['POST'])]
public function save_siparis(Request $request, EntityManagerInterface $entityManager): JsonResponse
{
$siparis = new Siparis();
try {
$form = $this->createForm(SiparisType::class, $siparis);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($siparis);
$entityManager->flush();
return new JsonResponse(['result' => 'OK', 'siparis_id' => $siparis->getId()]);
}
}catch(\Exception $e){
error_log($e->getMessage());
return new JsonResponse(array('result' => $e->getMessage()), 419);
}
}
Render Form route on Controller:
Only change is: 'firma' => $id option for form in this section
#[Route('/new/{id}', name: 'new', methods: ['GET'])]
public function new($id, Request $request, EntityManagerInterface $entityManager, SiparisRepository $siparisRepository,FirmaRepository $firmaRepository, IlgiliRepository $ilgiliRepository): Response
{
$siparis = new Siparis();
$latest_siparis = $siparisRepository->findBy(['Musteri' => $id], ['id' => 'desc', ]);
$siparis_id = 1;
if(!is_null($latest_siparis))
$siparis_id = count($latest_siparis) + 1;
$musteri = $firmaRepository->find($id);
$siparisNo = 'TST-'.str_replace(' ', '-',$musteri->getKod()).'-'.str_pad($siparis_id, 3, '0', STR_PAD_LEFT);
$form = $this->createForm(SiparisType::class, $siparis, ['firma' => $id,'attr' => ['id' => 'siparis_form']]);
$firmalar = $firmaRepository->findBy(['Type' => 0]);
$maliyet = new Maliyetler();
$maliyet_form = $this->createForm(MaliyetlerType::class, $maliyet, ['attr' => ['id' => 'maliyet_form']]);
return $this->renderForm('siparis/new.html.twig', [
'siparisNo' => $siparisNo,
'sipari' => $siparis,
'form' => $form,
'maliyet_form' => $maliyet_form,
'satici_firmalar' => $firmalar,
'musteri' => $musteri,
'mode' =>'NEW'
]);
}
My FormType:
The field: 'siparis_veren' was a TextType and i have changed this one as a EntityType and fetched the related entities via query builder
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$firma = $options['firma'];
$SIPARIS_CHOICES = ['Devam Ediyor' => '1','Tamamlandı' => '2','İptal' => '3'];
$builder
->add('teslim_tarihi', DateType::class, [
'widget' => 'single_text',
'label' => 'Teslim Tarihi', 'attr' =>['class' => 'form-control', 'placeholder' => 'Teslim Tarihi']
])
->add('siparis_tarihi', DateType::class, [
'widget' => 'single_text',
'label' => 'Sipariş Tarihi', 'attr' =>['class' => 'form-control', 'placeholder' => 'Sipariş Tarihi']
])
->add('siparis_veren', EntityType::class,['class' => Ilgili::class,
'choice_label' => 'full_name',
'query_builder' => function (EntityRepository $er) use ($firma) {
return $er->createQueryBuilder('ilgili')
->andWhere('ilgili.firma = :firma')
->setParameter('firma', $firma);
},
'label' => 'Siparişi Veren', 'attr' =>['class' => 'form-control', 'placeholder' => 'Siparişi Veren']])
->add('siparis_durum', ChoiceType::class,['choices' => $SIPARIS_CHOICES,'attr' =>['class' => 'form-control', 'placeholder' => 'Siparişi Alan'] ])
->add('siparis_turu', HiddenType::class)
->add('siparis_genel_aciklama', TextType::class,['label' => 'Sipariş Genel Açıklaması', 'attr' =>['class' => 'form-control', 'placeholder' => 'Sipariş Genel Açıklaması']])
->add('siparis_satir_aciklama', HiddenType::class)
->add('siparis_miktari', HiddenType::class)
->add('siparis_fiyati', HiddenType::class)
->add('fatura_durumu', HiddenType::class)
->add('siparisNo', HiddenType::class)
->add('siparis_kdv_orani', HiddenType::class);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Siparis::class,
'csrf_protection' => true,
'csrf_field_name' => '_token',
]);
$resolver->setRequired(['firma']);
}
My AJAX form post on client side(No change here):
$('form[name="siparis"]').submit(function(e) {
e.preventDefault();
var url = "{{ path('siparis_save') }}";
var formSerialize = $(this).serialize();
$.post(url, formSerialize, function(response) {
if(response.result === "OK")
{
$( 'form[name="maliyetler"]' ).submit();
}
else
{
console.log(response.result);
}
}, 'JSON');
});
In my Siparis Entity siparis_veren was a text field and i added a ManyToOne relation with Ilgili class to it and after my changes post keep giving me 419 error.
#[ORM\ManyToOne(targetEntity: Ilgili::class, inversedBy: 'siparisler')]
#[ORM\JoinColumn(nullable: false)]
private $siparis_veren;
I tried clearing cache, removed related siparis_veren field from form type and controller but result is same unless I revert siparis_veren to TextType as it was before.
Sorry if my explanation is not enough, I couldn't find any results regarding this issue and SO is my only choice, I am a newbie in Symfony.
Thank you.
Okay found the issue, I didn't notice that I set status to 419 on Try Catch catch block so thought it was about Symfony or client side. After doing some debugging I get "An error has occurred resolving the options of the form "App\Form\SiparisType": The required option "firma" is missing." error which is caused by
SiparisConroller.php
$form = $this->createForm(SiparisType::class, $siparis);
This line in save_siparis() function. In SiparisType I have set 'firma' field as required
SiparisType.php
$resolver->setRequired(['firma']);
Therefore I got an error in Try Catch block.
Thanks to #jean-max for his advice to check Try Catch.
I have a field in my FormType that I'm trying to get the value of at the time it's being successfully submitted and pass it to my controller. I set the value of the field by passing a variable to the form and using the attr of the textbox to set it to the corresponding value in $options, the end result of the html is <input type="hidden" id="listing_editId" name="listing[editId]" required="required" value="1288701182" readonly="readonly">
ListingType.php
->add('editId', HiddenType::class, [
'required' => true,
'disabled' => false,
'mapped' => true,
'attr' => [
'value' => $options['editId'],
'readonly' => true,
]
])
I've tried $form->get('editId'); but it doesn't return the value, I've also tried $request->get('editId'); to no avail.
ListingController.php
/**
* #Route("/account/listings/create", name="listing_create")
*/
public function createAction(Request $request)
{
$r = sprintf('%09d', mt_rand(0, 1999999999));
$form = $this->createForm(ListingType::class, null, [
'currency' => $this->getParameter('app.currency'),
'hierarchy_categories' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Category'), 'category', 'categories'),
'hierarchy_locations' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Location'), 'location', 'locations'),
'editId' => $r,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$listing = $form->getData();
$listing->setUser($this->getUser());
try {
$em = $this->getDoctrine()->getManager();
$em->persist($listing);
// I'd like to be able to get the value of an input field that is "editId" here
$em->flush();
$this->addFlash('success', $this->get('translator')->trans('Listing has been successfully created.'));
} catch (\Exception $e) {
$this->addFlash('danger', $this->get('translator')->trans('An error occurred when creating listing object.'));
}
return $this->redirectToRoute('listing_my');
}
return $this->render('FrontBundle::Listing/create.html.twig', [
'form' => $form->createView(),
'editId' => $r]);
}
Try $form->get('editId')->getData() or $request->request->get('editId') or $form->getData()['editId']
How to get field value in form builder in Symfony.
I have 2 Dropdowns in the form
I want to should the related option in Dropdown2 based on Dropdown1 in when the Page is Opening.
Here is My Form
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Event\DataEvent;
use C2Educate\ToolsBundle\Entity\Students;
public function buildForm(FormBuilder $builder, array $options) {
Field 1:
$builder->add('leadSource', 'entity', array(
'label' => 'How did you hear about C2? Source ',
'class' => 'C2EducateToolsBundle:LeadSources',
'query_builder' => function($repo) {
return $repo->createQueryBuilder('p')->orderBy('p.sort_order', 'ASC');
},
'property' => 'name',
'empty_value' => 'Select'
));
$leadSource = 1;
$leadSource = 1; - it works when I assign value statically, but I want to get the value of "leadSource" and assign it to $leadSource
I want to get the leadSource and pass it to leadSourceSub query
Field 2:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (DataEvent $event) {
$form = $event->getForm();
$entity = $event->getData();
$leadSource = $entity->getLeadSourceID();
$form->add('leadSourceSub', 'C2Educate\ToolsBundle\Entity\Students', array(
'label' => ' Source Detail ',
'required' => true,
'class' => 'C2EducateToolsBundle:LeadSourceSubs',
'query_builder' => function($repo) use ($leadSource) {
return $repo->createQueryBuilder('p')
->where('p.lead_source_id =:leadSource')
->setParameter('leadSource', $leadSource)
->orderBy('p.sort_order', 'ASC');
},
'property' => 'name',
'empty_value' => 'Select'
));
});
You cannot get form data from $builder, because... it's a form builder, not a form. It doesn't contain any data yet.
To make this work you need to make use of FormEvents. In this case, you probably will need FormEvents::PRE_SET_DATA event listener.
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
// in your case it's C2EducateToolsBundle:LeadSourceSubs
$entity = $event->getData();
$leadSource = $entity->getLeadSource();
// adding this field again will override it.
$form->add('leadSourceSub', 'entity', array(
'label' => ' Source Detail ',
'required' => true,
'class' => 'C2EducateToolsBundle:LeadSourceSubs',
'query_builder' => function($repo) use ($leadSource) {
return $repo->createQueryBuilder('p')
->where('p.lead_source_id =:leadSource')
->setParameter('leadSource', $leadSource)
->orderBy('p.sort_order', 'ASC');
},
'property' => 'name',
'empty_value' => 'Select'
));
}
});
Please note that this code is not tested and may need some validation like to check if $entity is what you expect it to be in any case.
I started learn symfony 3. For the first project i chose a simple totodlist.
So now i have possibility to create and save the user in my database. Next I can create a task for them.
I want to create a checkbox where can i choose a users to perform a task.
So i need put data from my user database to checkbox form ($temp_users varbiable). I don't know how to do it.
Can anybody show me how to do it.
below is my code:
public function createAction(Request $request)
{
$todo = new Todo;
$users = $this->getDoctrine()
->getRepository('AppBundle:User')
->findAll();
$temp_users = array();
foreach($users as $user) {
$temp_users[$user->getUsername()] = $user->getId();
}
$form = $this->createFormBuilder($todo)
->add('name', TextType::class, array('attr' => array('class' => 'form- control', 'style' => 'margin-bottom:15px')))
->add('wykona', CheckboxType::class, array('label' => $temp_users, 'required' => false,))
I'm not sure what you mean by checkbox - are you wanting to select one, or many users? I'm going to assume you want to select just one for simplicity's sake (you can adapt this to your liking)
You don't need to get all the users like you're trying to do, something like this should work (untested)
$form = $this->createFormBuilder($todo)
->add('user', EntityType::class, array(
'label' => 'Name',
'class' => AppBundle\Entity\User::class,
'choice_label' => 'name', //if you have a variable 'name' in your User entity, otherwise you will need a __toString method in the User entity
));
Try this code inside your createAction.
ADD this into your code
$form = $this->createFormBuilder($todo)
->add('users', EntityType::class, array(
'class' => 'AppBundle:User',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.name', 'ASC')
},
'choice_label' => 'name',
'multiple' => true,
'expanded' => true,
));
Also you don't need the following code anymore inside createAction.
REMOVE Below code from your code
$users = $this->getDoctrine()
->getRepository('AppBundle:User')
->findAll();
$temp_users = array();
foreach($users as $user) {
$temp_users[$user->getUsername()] = $user->getId();
In Symfony I have this part of my code where I am building a view with some data and a form with some radio buttons. When submitting the form I am doing a dump in the view to check which data has been submitted, but the data does not match with the one the form was build. Can someone help? Thanks.
public function playAction(Request $request){
$data = $this->getDbQuestion();
$questionData = $data[0];
dump($questionData);
$answerData = $data[1];
dump($answerData);
$form = $this->createFormBuilder($answerData)
->add('answers', ChoiceType::class,
array(
'choices'=> $answerData,
'multiple'=>false,'expanded'=>true,
'choice_label' => 'answer',
))
->add('Submit',SubmitType::class, array('label' => 'Send Answer'))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted()) {
$formData = $form->getData();
return $this->render('QuizViews/correctAnswer.html.twig', array(
'ss' => $formData
));
}
return $this->render('QuizViews/playQuiz.html.twig', array(
'form' => $form->createView(),
'question' => $questionData
));
}
Twig
<a href="/quiz/question">
<input type="button" value="Start Quiz" />
</a>
<br>
FormData Correct {{ dump(ss) }}
After chatting, this might be a better solution for the answer section:
->add('answers', EntityType::class, array(
'class' => 'AppBundle:Answer',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('a')
->where('a.question_id->getId() = :qID')
->setParameter('qID', 1);
},
'multiple'=>false,
'expanded'=>true,
'choice_label' => 'answer',
))
Try it!
Your call to get the data after verifying the form isSubmitted is incorrect. You need to call like so:
$formData = $form->get('answers')->getData();
That just gets the 'answers' only.
Edit #2
You might also want to change this:
->add('answers', ChoiceType::class,
array(
'choices'=> $answerData,
'multiple'=>false,
'expanded'=>true,
'choice_label' => 'answer',
'choice_value' => $answerData,
))
Which sets the 'choice_value', what is actually selected and returned from the getData().
Can you post your twig answers file please? Edit your post and so I can see.