简体   繁体   中英

Symfony3 change form field type in the controller

I have a form builder which builds a form

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->
        add('typeTask',TextType::class,array('label'=>"Вид заявка"))->
        add('description',TextareaType::class,array('label'=>"Описание"))->
        add('term',DateType::class, array(
            'widget' => 'choice',
            'label'=>"Краен срок"
        ))->
        add('designer',TextareaType::class,array('label'=>"Дизайнер",
            "required"=>false))->
        add('executioner',TextareaType::class,array('label'=>"Под изпълнител",
            "required"=>false))->
        add("file",TextType::class,array('label'=>"Файл",
            "required"=>false))->
        add("ergent",CheckboxType::class,array('label'=>"Спешно",
            "required"=>false))->add("approved",HiddenType::class,array(
            "required"=>false
        ))->add("rejected",HiddenType::class,array(
            'required'=>false
        ));
    }

As you see I have 2 fields which are "approved" which can be true or false and rejected which can also be true and false. Usually they are hidden because only 1 type of user can access them - ROLE_ADMIN and the rest is for ROLE_EDITOR. In my case the ADMIN needs to only approve or reject it and the EDITOR can't do that. The biggest issue is that I don't need a whole form, but rather 2 buttons - "Approve" and "Reject" when the Project is shown ("show" action), but the action which changes the Project is "edit" and so what I tried so far is from "show" to send a form to "edit" and then when the edit action is over to load the "show" action again.I tried achieving this by creating 2 forms - approveForm and rejectForm which can hold only 1 property each and send and flush them to "edit" function, but the edit function doesn't accept the form and also if it did it would have deleted everything else. Here is my code so far

In show action -

$projectFormApprove = $this->createForm('AppBundle\Form\ProjectType', $project,array(
            "method"=>"post"
        ));
        $projectFormApprove->remove("description");
        $projectFormApprove->remove("designer");
        $projectFormApprove->remove("executioner");
        $projectFormApprove->remove("term");
        $projectFormApprove->remove("typeTask");
        $projectFormApprove->remove("file");
        $projectFormApprove->remove("ergent");
        $projectFormApprove->remove("approved");
        $projectFormApprove->remove("rejected");
        $projectFormApprove->add("approved",HiddenType::class,array(
            "data"=>true
        ));
        $projectFormReject = $projectFormApprove;
        $projectFormReject->remove("approved");
        $projectFormReject->add("rejected",HiddenType::class,array(
            'data'=>true
        )); 

This will create 2 forms each having 1 property and here is what happens in my twig template

  <tr>
        <td>
           {{ form_start(approveForm, {'action': path('project_edit', { 'id': project.id })}) }}
           {{ form_widget(approveForm) }}
               <input type="submit" value="Approve" />
           {{ form_end(approveForm) }}
        </td>
   </tr>
   <tr>
       <td>
        {{ form_start(rejectedForm,{'action': path('project_edit', { 'id': project.id })}) }}
               {{ form_widget(rejectedForm) }}
                 <input type="submit" value="Reject" />
               {{ form_end(rejectedForm) }}
           </td>
       </tr>

I need two forms since there are 2 buttons which simply submit them and no one actually changes the value ( this is the reason why in "show" function the created property have "data"=>true . If the form is submitted it will do it automatically. Here is what is in my "edit" function -

/** @var  $user User */
        $user = $this->getUser();
        $project = new Project();
        $form = $this->createForm('AppBundle\Form\ProjectType', $project);
        if($user->getType() != "LittleBoss"){
            $form->remove("designer");
            $form->remove("executioner");
        }
        $form->handleRequest($request);


        if ($form->isSubmitted() && $form->isValid()) {
        $project->setFromUser($user->getUsername());
        $project->setDepartment($user->getDepartment());
        $project->setIsOver(false);
        $project->setDate(new \DateTime());
        $project->setSeenByDesigner(false);
        $project->setSeenByExecutioner(false);
        $project->setSeenByLittleBoss(false);
        $project->setSeenByManager(false);
            $em = $this->getDoctrine()->getManager();
            $em->persist($project);
            $em->flush();

            return $this->redirectToRoute('project_show', array('id' => $project->getId()));
        }

        return $this->render('project/new.html.twig', array(
            'project' => $project,
            'form' => $form->createView(),
        ));

Now to my actual problem - As you see I first remove "approved" field and then I add new one with predefined value. What I want is to change not the values, but the type of description and the rest fields. Is there a way to say $form->change(); or anything that can change the types of the fields without having to remove them. The type I want them to be is HiddenType and set their data so that when I submit one of the 2 forms it will be accepted as valid in the "edit" action then flushed to the database and everything will be fine. So far when one of the buttons - "Approve" or "Reject" is clicked in the "edit" action $edit_form->IsSubmited() returns false.

I suggest you to create seperate forms, one for editor and another for admin. Then in controller use the form you need by permissions of the logged in user.

if ($this->authorizationChecker->isGranted('ROLE_EDITOR')) {
     $form = $this->createForm(EditorType::class);
} elseif ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
     $form = $this->createForm(AdminType::class);
}

$form->handleRequest($request);

In both forms you can use same entity, but different fields.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM