6

I have a form whose content is created from a DB.

in my controller i have:

/**
 * @Route("/HR/manage/{projectID}", name="hr_manage")
 */
public function manageHRAction(Request $request, $projectID)
{
//here I get all the data from DB and create the form
if ($form->isValid()) 
    {
    //here I do all the relevant changes in the DB
    return $this->render('HR/show.html.twig', array('hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
    }
return $this->render('HR/show.html.twig', array('hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
}

It updates the info on the DB properly, but it does not build again the form with updated data. Instead of the return inside the "isValid()" I simply need a refresh on the current page.

I assume it's possible and easy to accomplish, but I failed to find how to do it :/

EDIT - here comes more relevant code:

/**
 * @Route("/HR/manage/{projectID}", name="hr_manage")
 */
public function manageHRAction(Request $request, $projectID)
{
$user = $this->container->get('security.context')->getToken()->getUser(); //get current user
$em = $this->getDoctrine()->getManager(); //connect to DB
$prj = $this->getDoctrine()->getRepository('AppBundle:Project')->findOneById($projectID);
[...]
// here comes some code to generate the list of $HRsInThisProject and the list of roles ($rolesListForForm)
[...]
foreach ($HRsInThisProject as $key => $HR)
    {
    $form->add('roleOf_'.$key, 'choice', array('choices'   => $rolesListForForm, 'required'  => true, 'data' => $HR['role'], 'label' => false, ));
    $form->add('isActive_'.$key, 'choice', array('choices'   => [0 => 'Inactive', 1 => 'Active'] , 'required'  => true, 'data' => $HR['is_active'], 'label' => false, ));
    }
[...]
// here there is some code to get the $HRsInMyDomainForForm
[...]
$form->add('HRid', 'choice', array('choices' => $HRsInMyDomainForForm,'required' => false, 'placeholder' => 'Choose a resource', 'label' => false, ));
$form->add('role', 'choice', array('choices' => $rolesListForForm,'required' => false, 'placeholder' => 'Choose a role', 'label' => false, ));            
$form->add('save', 'submit', array('label' => 'Save'));     

$form->handleRequest($request);

if ($form->isValid()) 
    {
        {
        [...] here there is a huge portion of code that determines if I need to generate a new "event" to be stored, or even multiple events as I can change several form fields at once

        // If I needed to create the event I persist it (this is inside a foreach)
        $em->persist($newHREvent);
        }
    $em->flush();
    return $this->render('HR/show.html.twig', array('projectID' => $prj->getId(), 'hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
    }
return $this->render('HR/show.html.twig', array('projectID' => $prj->getId(), 'hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
}

I also include a screenshot of the form: enter image description here

If a user selects to add a new resouce, I need to persist it to DB (and that is done properly) but then I need to see it in the list of available HRs, without the need for the user to reload the page.

Community
  • 1
  • 1
Sergio Negri
  • 2,023
  • 2
  • 16
  • 38

4 Answers4

20

More dynamic way would be:

$request = $this->getRequest();

return $this->redirectToRoute($request->get('_route'), $request->query->all());

or simply

return $this->redirect($request->getUri());
Aistis
  • 3,695
  • 2
  • 34
  • 34
3

I managed to solve it in a simple (and I hope correct) way.

I simply substituted the "render" inside the isValid() with the following:

return $this->redirect($this->generateUrl('hr_manage', array('projectID' => $prj->getId())));

I works, but does anybody foresee problems with this solution?

Sergio Negri
  • 2,023
  • 2
  • 16
  • 38
0

You have to link the form to the request.

$entity = new Entity();
$form = $this->createFormBuilder($entity)
    ->add('field1', 'text')
    ->add('field2', 'date')
    ->add('save', 'submit', array('label' => 'Submit'))
    ->getForm();
$form->handleRequest($request); // <= this links the form to the request.

only after that you test $form->isValid() and pass this form when rendering the template. If you already did this and haven't included in the code above please show more code for better help.

Nelson Teixeira
  • 6,297
  • 5
  • 36
  • 73
0

Here is the right way to do it. Event though you have $projectId slug, in Action you can pass whole Object, in this case Project. Symfony will take care for the rest (fetching right Project entity for you.

/**
 * @Route("/HR/manage/{projectID}", name="hr_manage")
 */
public function manageHRAction(Request $request, Project $project)
{
    $form = $this->createForm(new ProjectType(), $project);
    $form->handleRequest($request);

    // ... your business logic or what ever

    //here I get all the data from DB and create the form
    if ($form->isValid() && $form->isSubmitted()) {
        $em->persist($project);
        // no need to flush since entity already exists
        // no need to redirect
    }

    // here $form->createView() will populate fields with data since you have passed Poroject $project to form
    return $this->render('HR/show.html.twig', array('hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
}

Update

According to your edit, you need to use javascript for client-side dom manipulation. Check this link from Symfony official document embedded forms. Here you'll find an example of what you're trying to accomplish.

Lord Zed
  • 750
  • 7
  • 28
  • The issue is that my form is created dynamically. I'll update my post with more info. – Sergio Negri Dec 27 '14 at 21:16
  • It seems a bit convoluted and probably an overkill. All I need is a refresh :/ – Sergio Negri Dec 28 '14 at 14:52
  • You said you dont want to refresh the page. – Lord Zed Dec 28 '14 at 15:18
  • Probably I've been misunderstood, in my first post I wrote "I simply need a refresh on the current page", and below in one of the comments I wrote "...without the need for the user to reload the page". I meant that I do need a refresh, but I don't want to be the user to perform it manually. – Sergio Negri Dec 28 '14 at 15:37
  • Still you can use the code I've posted to achieve what you want. – Lord Zed Dec 28 '14 at 15:52