代码之家  ›  专栏  ›  技术社区  ›  curuba

在Symfony中有条件地隐藏一些嵌入的表单字段(集合)

  •  0
  • curuba  · 技术社区  · 6 年前

    我用的是symfony3.4。

    我有国家和实体的问题。 然后我有一个答案实体,它与国家和问题都有联系。

    在问题中,我定义了期望的答案类型(布尔值、字符串等…)。

    我想显示一个给定国家的表格,以便编辑对应于不同问题的答案。

    我正在使用collectionType from country表单来执行此操作。

    但我的两个问题是:

    • 如何在嵌入式窗体中显示问题本身

    在处理一个问题时看似很简单的事情,在处理某个国家的所有问题/答案时却显得晦涩难懂。

    国家实体

        <?php
    
    namespace cwt\psmdbBundle\Entity;
    
    use APY\DataGridBundle\Grid\Mapping as GRID;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * countries
     *
     * @ORM\Table()
     * @ORM\Entity(repositoryClass="cwt\psmdbBundle\Entity\Repository\countriesRepository")
     */
    class countries
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\Column(name="name", type="string", length=100)
         */
        private $name;
    
        /**
         * @ORM\OneToMany(targetEntity="cwt\psmdbBundle\Entity\CcdbServicesAnswers", mappedBy="country", cascade={"persist", "remove"})
         */
        private $ccdbServicesAnswers;
    

        <?php
    
    namespace cwt\psmdbBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use APY\DataGridBundle\Grid\Mapping as GRID;
    
    /**
     * CcdbServicesQuestions
     *
     * @ORM\Table(name="ccdb_services_questions")
     * @ORM\Entity(repositoryClass="cwt\psmdbBundle\Repository\CcdbServicesQuestionsRepository")
     */
    class CcdbServicesQuestions
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\Column(name="question", type="string", length=255)
         */
        private $question;
    
        /**
         * @ORM\ManyToOne(targetEntity="cwt\psmdbBundle\Entity\CcdbServicesCategories")
         * @ORM\JoinColumn(nullable=false)
         * @GRID\Column(field="category.name", title="Category")
         */
        private $category;
    
        /**
         * @ORM\ManyToOne(targetEntity="cwt\psmdbBundle\Entity\FieldTypes")
         * @ORM\JoinColumn(nullable=false)
         * @GRID\Column(field="fieldType.name", title="Field Type")
         */
        private $fieldType;
    
        /**
         * @ORM\OneToMany(targetEntity="cwt\psmdbBundle\Entity\CcdbServicesAnswers", mappedBy="question", cascade={"persist", "remove"})
         */
        private $ccdbServicesAnswers;
    

    答案实体:

        <?php
    
    namespace cwt\psmdbBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Gedmo\Mapping\Annotation as Gedmo;
    
    /**
     * CcdbServicesAnswers
     *
     * @ORM\Table(name="ccdb_services_answers")
     * @ORM\Entity(repositoryClass="cwt\psmdbBundle\Repository\CcdbServicesAnswersRepository")
     */
    class CcdbServicesAnswers
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string|null
         *
         * @ORM\Column(name="stringField", type="string", length=255, nullable=true)
         */
        private $stringField;
    
        /**
         * @var string|null
         *
         * @ORM\Column(name="textField", type="text", nullable=true)
         */
        private $textField;
    
        /**
         * @var bool|null
         *
         * @ORM\Column(name="booleanField", type="boolean", nullable=true)
         */
        private $booleanField;
    
        /**
         * @var int|null
         *
         * @ORM\Column(name="integerField", type="integer", nullable=true)
         */
        private $integerField;
    
        /**
         * @var float|null
         *
         * @ORM\Column(name="floatField", type="float", nullable=true)
         */
        private $floatField;
    
        /**
         * @var float|null
         *
         * @ORM\Column(name="percentageField", type="float", nullable=true)
         */
        private $percentageField;
    
        /**
         * @var string|null
         *
         * @ORM\Column(name="comment", type="string", length=255, nullable=true)
         */
        private $comment;
    
        /**
         * @ORM\ManyToOne(targetEntity="countries", inversedBy="ccdbServicesAnswers")
         * @ORM\JoinColumn(nullable=false)
         */
        private $country;
    
        /**
         * @ORM\ManyToOne(targetEntity="cwt\psmdbBundle\Entity\CcdbServicesQuestions", inversedBy="ccdbServicesAnswers")
         * @ORM\JoinColumn(nullable=false)
         */
        private $question;
    

    这是我的国家表格:

    <?php
    
    namespace cwt\psmdbBundle\Form;
    
    use cwt\psmdbBundle\Entity\countries;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    use Symfony\Component\Form\Extension\Core\Type\CollectionType;
    
    class countriesCCDBServicesAnswersType extends AbstractType
    {
    
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('ccdbServicesAnswers', CollectionType::class, array(
                    'entry_type' => CcdbServicesAnswersType::class,
                    'entry_options' => array('label' => false),
                ))
            ;
    
        }
    
        /**
         * @param OptionsResolver $resolver
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'cwt\psmdbBundle\Entity\countries'
            ));
        }
    
        /**
         * @return string
         */
        public function getBlockPrefix()
        {
            return 'cwt_psmdbbundle_countries';
        }
    }
    

    这是我的答案表:

    <?php
    
    namespace cwt\psmdbBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    //use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    
    class CcdbServicesAnswersType extends AbstractType
    {
            /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('stringField')
                ->add('textField')
                ->add('booleanField')
                ->add('integerField')
                ->add('floatField')
                ->add('percentageField')
                ->add('comment')
    //            ->add('country')
    //            ->add('question')
            ;
        }
    
        /**
         * @param OptionsResolver $resolver
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'cwt\psmdbBundle\Entity\CcdbServicesAnswers'
            ));
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'cwt_psmdbbundle_ccdbservicesanswers';
        }
    }
    

        /**
         * Show answers for a given country.
         * @Route("/countries/{countryID}/edit", name="editCountryCcdbServicesAnswers", methods={"GET"})
         * @Security("has_role('ROLE_USER')")
         *
         */
        public function editCountriesCcdbServicesAnswers($countryID)
        {
    
    
    //        // Get categories
            $em = $this->getDoctrine()->getManager();
            $categories = $em->getRepository('psmdbBundle:CcdbServicesCategories')->findAll();
    
            // $questions = $em->getRepository('psmdbBundle:CcdbServicesQuestions')->findAll();
    
            // Get all answers for this country
            $country = $em->getRepository('psmdbBundle:countries')->find($countryID);
    
            $form = $this->createCountryEditForm($country);
    
            foreach ($form as $field) {
    
                $fieldClass = get_class($field);
    
                if(get_class($field)=='Symfony\Component\Form\Form') {
                    foreach ($field as $answerForm) {
    
                        foreach ($answerForm as $answerField) {
    
                        }
    
                    }
                }
    
            }
    
    
    
            return $this->render('psmdbBundle:ccdb_services_answers:edit_country.html.twig', array(
                'categories' => $categories,
                'form' => $form->createView(),
                'entity' => $country,
    //            'delete_form' => $deleteForm->createView(),
                'show' => 'ccdbservicesanswers_show',
                'cancel' => 'ccdbservicesanswers_show',
                'title' => 'CCDB Services',
            ));
    
        }
    

    下面是模板(非常无用,因为它显示每个答案的所有字段,而不显示问题……):

    {% extends 'psmdbBundle:templates:edit.html.twig' %}
    
        {% block form_body -%}
            <div class="col-lg-5">
    
                {{ form(form) }}
    
            </div>
        {% endblock form_body %}
    

    另一种解决方案是在show视图中使用ajax调用,以便在单击特定问题的“编辑”时动态构建表单,但我不相信用户体验!

    1 回复  |  直到 6 年前
        1
  •  0
  •   curuba    6 年前

    然后,为了只显示我需要的答案字段,我使用了表单事件,如下所示。我从问题中检索fieldType并有条件地添加必需的字段。

    这是我的最终表格:

    <?php
    
    namespace cwt\psmdbBundle\Form;
    
    use FOS\CKEditorBundle\Form\Type\CKEditorType;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\Extension\Core\Type\PercentType;
    use Symfony\Component\Form\Extension\Core\Type\TextareaType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Form\FormEvent;
    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    //use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use cwt\psmdbBundle\Form\GpscSwitchType;
    
    class CcdbServicesAnswersType extends AbstractType
    {
            /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
    
                ->add('question', textType::class, array(
                        'disabled' => true,
                        'label'     => false,
                        'attr' => array('class' => 'ccdb-form-question'),
                    )
                );
            $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
                $answer = $event->getData();
                $question = $answer->getQuestion();
                $fieldType = $question->getFieldType()->getName();
                $form = $event->getForm();
    
    
                switch ($fieldType) {
                    case 'boolean':
                        $form->add('booleanField', GpscSwitchType::class, array(
                            'label' => false,
                            'horizontal_label_class' => 'col-lg-12',
                            'horizontal_input_wrapper_class' => 'col-lg-3',
                            'attr' => array('class' => 'ccdb-form-answer boolean-type'),
                            'required'  => false,
                        ));
                        break;
                    case 'string':
                        $form->add('stringField', textAreaType::class, array(
                            'label' => false,
                            'horizontal_label_class' => 'col-lg-12',
                            'horizontal_input_wrapper_class' => 'col-lg-12',
                            'attr' => array('class' => 'ccdb-form-answer'),
                            'required'  => false,
                            ));
                        break;
                    case 'integer':
                        $form->add('integerField', null, array(
                            'label' => false,
                            'horizontal_label_class' => 'col-lg-12',
                            'horizontal_input_wrapper_class' => 'col-lg-2',
                            'attr' => array('class' => 'ccdb-form-answer'),
                            'required'  => false,
                            ));
                        break;
                    case 'percentage':
                        $form->add('percentageField', percentType::class, array(
                            'label' => false,
                            'scale' => 2,
                            'horizontal_label_class' => 'col-lg-12',
                            'horizontal_input_wrapper_class' => 'col-lg-2',
                            'attr' => array('class' => 'ccdb-form-answer'),
                            'required'  => false,
                            ));
                        break;
                    case 'float':
                        $form->add('floatField', null, array(
                            'label' => false,
                            'horizontal_label_class' => 'col-lg-12',
                            'horizontal_input_wrapper_class' => 'col-lg-2',
                            'attr' => array('class' => 'ccdb-form-answer'),
                            'required'  => false,
                            ));
                        break;
                    case 'text':
                        $form->add('textField', CKEditorType::class, array(
                            'label' => false,
                            'horizontal_label_class' => 'col-lg-12',
                            'horizontal_input_wrapper_class' => 'col-lg-12',
                            'attr' => array('class' => 'ccdb-form-answer'),
                            'required'  => false,
                            ));
                        break;
                }
    
                $form->add('comment', textAreaType::class, array(
                    'label' => 'Comment:',
                    'horizontal_label_class' => 'col-lg-12',
                    'horizontal_input_wrapper_class' => 'col-lg-12',
                    'attr' => array('class' => 'ccdb-form-answer ccdb-form-comment'),
                    'required'  => false,
                    ));
    
    
            });
        }
    
        /**
         * @param OptionsResolver $resolver
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'cwt\psmdbBundle\Entity\CcdbServicesAnswers'
            ));
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'cwt_psmdbbundle_ccdbservicesanswers';
        }
    }