I'm having an issue with looping a form in Symfony using while loop. When the user enters one student period and it matches a registration reiterate the form to let them enter a 2nd student period and then a 3rd. I'm not doing it correctly or could I reiterate entity=new Student(); to let them enter two entities .
public function createAction(Request $request){
$entity = new Student();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$student = $em->getRepository('AcmeDemoBundle:Payrollperiod')
->findOneBy([
'begindate'=>$form->get('beginDate')->getData(),
'lastdate'=>$form->get('lastDate')->getData()
]);
$registration = $em->getRepository('AcmeDemoBundle:Payrollweek')
->findBystartdateAndenddate(
$form->get('beginDate')->getData(),
$form->get('lastDate')->getData()
);
$counter = count($registration);
while($counter<=2) {
if ($student){
$this->addFlash('error', 'Duplicate error: Student Period already existed.' );
return $this->redirect($this->generateUrl('student'));
}
elseif ($registration){
foreach ($registration as $reg) {
$reg->setStudentid($entity);
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('payrollperiod'));
}
else{
$this->addFlash('error', ' does not match .');
return $this->redirect($this->generateUrl('student'));
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
Read the documentation here http://symfony.com/doc/current/reference/forms/types/form.html#allow-extra-fields on adding fields. Your UI/Front-end should created more fields when the user needs to add a second or more periods. I should generate proper Symfony form elements and then when you post, you can handle it like a standard form post, iterating over the Request since the periods will be submitted as an array.
I did something like this in the past I adding a new form row was an AJAX call to a template that described the form input fields so I wasn't having to craft form HTML in Javascript/jQuery. .append() the template results to the form-- post and process the request.
Related
I'm working with Symfony 4, and I want to make my own form but to make an insert i need a token that is generated by the form, there is a way to generate the form and get the or what else i can do.
public function new(Request $request): Response
{
$customer = new Customers();
$form = $this->createForm(Customers1Type::class, $customer); // <- here
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($customer);
$em->flush();
return $this->redirectToRoute('customers_index');
}
return $this->render('customers/new.html.twig', [
'customer' => $customer,
'form' => $form->createView(),
]);
}
You basically do not need to get and render the token by yourself. Symfony forms handle that internally and the form_end function renders the hidden field.
When you inspect the generated Form, you will see:
<input type="hidden" id="customer__token" name="customer[_token]" value="the_long_token_auto_generated" /></form>
Then inside your controller action's, you can get the token by the $request method's:
$token = $request->request->get('customer')['_token'];
I'm quite new here, be patient, please.
I'm trying to make notice board project in Symfony2 using FOSUserBundle.
I try to get logged user id to put it into form created with form builder (and then to MySQL database).
One of attempts is:
public function createNoticeAction(Request $request)
{
$notice = new Notice();
$form = $this->createFormBuilder($notice)
->add("content", "text")
->add("user_id","entity",
array("class"=>"FOS/UserBundle/FOSUserBundle:", "choice_label"=>"id"))
->add("isActive", "true")
->add("category", "entity",
array("class" => "AppBundle:Category", "choice_label" => "name"))
->add("save", "submit", array("label" => "Save"))
->getForm();
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
$em->persist($notice);
$em->flush();
return $this->redirectToRoute('app_user_showuserpage');
}
I tried many solutions again and again and I get some error.
You already have the user object Symfony > 2.1.x
In you Controller like this:
$userId = $this->getUser()->getId();
...
$notice->setUserId($userId);
$em->persist($notice);
Don't ->add field in you FormBuilder, its not safely. Set this value in you Controller and don't ->add this field in FormBuilder
for symfony 3.2.13
have excelent solution (just because is working, but is dangerous if someone discover it in pure HTML)
1) first build YourFormType class.
add normal field in Forms/YourFormType.php (if not, formbuilder tell you that you passing smth not quite right (too many fields) ; -) )
$builder
->add(
'MyModelAddedById',
HiddenType::class,
[
'label' => 'echhh', //somehow it has to be here
'attr' => ['style' => 'display:none'], //somehow it has to be here
]
);
2) in your controller
public function addSomethingAction(Request $request){
$form = $this->createForm(MyModelFormType::class);
//set field value
$request->request->set("prodModelAddedById", $this->getUser()->getId());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$product = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
$this->addFlash('success', 'record was added');
return $this->redirectToRoute('products');
}
return $this->render(
'default.add.form.html.twig',
[
'newprod' => $form->createView(),
]
);
}
explenation:
you are passing a field and variable to formbuilder (settig it already to default value!)
and important thing, becose of BUG in my opinion - you can't in your form type set method:
public function getBlockPrefix()
{
//return 'app_bundle_my_form_type';
}
because
$request->request->set
can't work properly if your POST data from form are in bag (parameterbag)
no entity managers, no services, no listeners...
hope it helps.
I have a form containing a collection (allowing add and remove entities) and a validation constraint to check if there are duplicates user's selections.
In case of there is of duplicates, the user is redirected in the new / edit form with an error message.
In this case, I am looking for a way to remove the duplicates fields from the form before rendering the view?
I am able to remove the duplicates from the list in my entity, but not from the form fields.
public function createAction(Request $request)
{
...
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
...
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ispc_show', array('id' => $entity->getId())));
}
// Remove the duplicates from the list in the entity
$entity->removeDuplicate();
// And apply to the form
$form->remove....
return $this->render('CompanyDocumentBundle:ISPC:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
Update
I don't want to remove the duplicates before validation because the error message is important to report to the user. Also, the duplicates are part of the "$request" object, and the form fields are filled with this object, not with the entity.
Can we edit the possible options for a choice field after the field has been created?
Let's say, the possible options for the choice field(a drop down box for categories) comes from my database. My controller would look like this:
public function addAction(Request $request){
//get the form
$categories = $this->service->getDataFromDatabase();
$form = $this->formFactory->create(new CategoryType(), $categories);
$form->handleRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database, redirect
}
return $this->templating->renderResponse('TestAdminBundle:Categories:add.html.twig',
array('form' => $form->createView())
);
}
This works. $categories is populated as a dropdown box so the user can select a category. What I don't like about this code is that it has to hit the "getDataFromDatabase" service again when the user hits submit and the form validates the input. This feels unnecessary to me; ideally it should only need to hit the service when validation fails and the form has to be regenerated for the user. I'm hoping to make the controller look something like this:
public function addAction(Request $request){
//get the form
$form = $this->formFactory->create(new CategoryType());
$form->handleRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database, redirect
}
$categories = $this->service->getDataFromDatabase();
$form->setData($categories); //this tells the choice field to use $categories to populate the options
return $this->templating->renderResponse('TestAdminBundle:Categories:add.html.twig',
array('form' => $form->createView())
);
}
You need to use EventSubscriber, check the docs, here: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-underlying-data
I have this forms + controllers http://pastebin.com/wLPyXvbj
They are working when I'm adding data to DB (new data) but I have troubles while editing, I explain here the best I can.
Case 1
I edit EVERY SINGLE FIELD, data is updated on DB OK.
Case 2
I try to edit FEW fields, only fields I want users to edit instead of editing everything. Fields that have been available for update are inserted into DB without problem, but the other fields, thoose which I didn't want users to modify instead of keeping the old values in DB (because they HAVEN'T changed), they all turn empty values.
So there is something wrong with "selective editing" instead of "all fields edit" but I can't find the problem... I can't make an all fields edit form because some of them are static, no edits.
This is the controller I'm using for the edit action, as you can see it is diferent from the newAction
public function agentupdateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$comments = new VtigerTicketcomments();
$session = $this->get("session");
$proyecto = $session->get('proyecto');
$assets = $session->get('assets');
$contacts = $em->createQuery('SELECT u.contactid, u.email, u.phone, u.mobile FROM WbsGoclientsBundle:VtigerContactdetails u')->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
foreach($assets as $a)
$uuids[$a['UUID']] = $a['UUID'];
$entity = $em->getRepository('WbsGoclientsBundle:VtigerTicketcf')->find($id);
$ticket = $entity->getId();
$solution = $ticket->getSolution();
$ticketcfForm = $this->createForm(new TicketcfType($uuids, $session->get('contacts'), $session->get('rol'), $session->get('tecnicos')), $entity);
$ticketcfForm->submit($request);
if($ticketcfForm->isValid())
{
$data = $ticketcfForm->getData();
if($ticket->getStatus() == 'Closed')
{
if(!$ticket->getSolution())
$ticket->setSolution($solution);
$workflow = new ComVtigerWorkflowtaskQueue();
$workflow->setTaskid('9');
$workflow->setEntityid('9x'.$id);
$workflow->setDoafter('0');
$em->persist($workflow);
$em->flush();
$hoy = new \DateTime();
if($ticketcf->getFReso() == null)
$ticketcf->setFReso($hoy->format('d-m-Y H:i:s'));
}
$em->persist($ticket);
$em->flush();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('tickets_show', array('id' => $ticket->getTicketNo())));
}
return $this->render('WbsGoclientsBundle:Tickets:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'rol' => $session->get('rol'),
'ticket_form' => $ticketForm->createView(),
));
}