dravpuso44681
2018-12-11 23:15
浏览 96
已采纳

如何从Symfony3中提交的表单中获取数据?

I faced up with some non-ordinary situation for me.

1) I have a dependent list that rendering by Symfony FormType like this: enter image description here

2) Location and Instruction fields are depend from Company field.

3) When I change Company field (onchange event js) then goes ajax request that retrieves data from the database and build a dropdown list.

4) But when form is submitted I have an error: enter image description here

Please help me to resolve this. Thanks in advance.

My formType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('hours')
        ->add('messageText', null, ['required' => false])
        ->add('company', null, [
            'choice_label' => 'name',
            'placeholder' => 'Please select company',
            'required' => true
        ])
        ->add('procedure', TextType::class, ['attr' => ['placeholder' => 'Please type code or description'] ])
        ->add('instruction', ChoiceType::class, ['mapped' => false])
        ->add('location', ChoiceType::class, ['mapped' => false])

    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => InstructionNotification::class
    ));
}

Action from controller:

/**
 * @Route("/admin/api/instructions", name="admin_api_instructions")
 * @param Request $request
 * @return JsonResponse
 */
public function getInstructionsByCompanyId(Request $request)
{
    $id = $request->get('id');
    if (!$id) {
        return new JsonResponse('No data', 404);
    }

    $instructions = $this->getDoctrine()->getRepository('OctaneBundle:Instruction')->findInstructionsByCompanyId($id);

    return new JsonResponse($instructions);
}

findInstructionsByCompanyId($id):

public function findInstructionsByCompanyId($id)
{
    $qb = $this->createQueryBuilder('i');
    if ($id) {
        $qb
            ->where('i.company = :id')
            ->setParameter('id', $id);
    }

    return $qb->getQuery()->getResult();
}

response from api (i.e.: admin/api/instructions?id=1):

[{"id":2,"label":"First instruction"},{"id":3,"label":"First instruction"}]

If you need any additional information please leave comments below. Thanks

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dtp19819 2018-12-13 20:16
    已采纳

    Thanks for the answer but I found out more elegant solution for my case. So,

    my formType now:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ...
            ->add('instruction', FormattedSelectType::class, ['class' => Instruction::class])
            ->add('location', FormattedSelectType::class, ['class' => Location::class])
        ;
    }
    

    FormattedSelectType:

    class FormattedSelectType extends AbstractType
    {
        /**
         * {@inheritdoc}
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'choice_label' => function (FormattedLabelInterface $entity) {
                    return $entity->getFormattedLabel();
                }
            ));
        }
    
        /**
         * {@inheritdoc}
         */
        public function getParent()
        {
            return EntityType::class;
        }
    }
    

    Etities Location and Instruction entities implement JsonSerializable and custom FormattedLabelInterface interface and have the next methods:

    /**
     * @return string
     */
    public function getFormattedLabel()
    {
        return sprintf(self::LABEL_FORMATTED, $this->zip, $this->city, $this->name, $this->address, $this->phone);
    }
    
    /**
     * @return array|mixed
     */
    public function jsonSerialize()
    {
        return [
            'id' => $this->id,
            'label' => $this->getFormattedLabel()
        ];
    }
    
    已采纳该答案
    打赏 评论
  • douluyezhen4512 2018-12-11 23:29

    Symfony's Validator expects that your submitted form will have a submitted instruction and location value that exists in the list you provided when creating your form in form type class. Since you are not providing any options for instructions and locations, you are getting a validation error.

    In order to bypass this error you should use Symfony's Form Events in your buildForm function in your form type like this:

    $builder->get('company')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) {
                $company = $event->getForm()->getData();
                $form = $event->getForm()->getParent();
                $form->add('location', EntityType::class, array(
                    'class' => Location::class,
                    'query_builder' => function (EntityRepository $repo) use ($company) {
                        return $repo->createQueryBuilder('location')
                            ->where('location.company = :company')
                            ->setParameter('company', $company->getId());
                    }
                ));
                $form->add('instruction', EntityType::class, array(
                    'class' => Instruction::class,
                    'query_builder' => function (EntityRepository $repo) use ($company) {
                        return $repo->createQueryBuilder('instruction')
                            ->where('instruction.company = :company')
                            ->setParameter('company', $company->getId());
                    }
                ));
            }
        );
    
    打赏 评论

相关推荐 更多相似问题