Cannot both disable entity field and retain its value

后端 未结 1 619
予麋鹿
予麋鹿 2021-01-21 22:13

In a form event, setting a field \'attr\' => array(\'readonly\' => \'readonly\') is rendered as \"disabled\" = \"1\". This is not the desired ef

相关标签:
1条回答
  • 2021-01-21 22:39

    The eventual solution: a service using Doctrine metadata to get disabled entity fields, form class modifications, and, for ManyToMany relationships, some jquery and invisible template entry.

    Service functions:

    /**
     * Create array of disabled fields of an entity object
     * 
     * @param type $object
     * @return array
     */
    public function getDisabledOptions($object) {
        $values = [];
        $className = get_class($object);
        $metaData = $this->em->getClassMetadata($className);
        foreach ($metaData->associationMappings as $field => $mapping) {
            if (8 > $mapping['type']) {
                $fieldName = ucfirst($field);
                $method = 'get' . $fieldName;
                if (method_exists($object->$method(), 'getEnabled') && false === $object->$method()->getEnabled()) {
                    $values[] = $fieldName;
                }
            }
        }
        $manyToMany = json_decode($this->getMetaData($object), true);
        foreach(array_keys($manyToMany) as $key) {
            $values[] = $key;
        }
    
        return $values;
    }
    
    /**
     * Get array of disabled ManyToMany options
     *
     * @param Object $object
     * @return array
     */
    public function getMetaData($object) {
        $data = array();
        $className = get_class($object);
        $metaData = $this->em->getClassMetadata($className);
        foreach ($metaData->associationMappings as $field => $mapping) {
            if (8 === $mapping['type']) {
                $data[$field] = $this->extractOptions($object, $field);
            }
        }
    
        return json_encode($data);
    }
    

    Controller use of service:

        $searches = $this->get('mana.searches');
        $disabledOptions = $searches->getDisabledOptions($household);
        $metadata = $searches->getMetadata($household);
        ...
        $form = $this->createForm(HouseholdType::class, $household, $formOptions);
        ...
        return $this->render('Household/edit.html.twig',
                array(
                'form' => $form->createView(),
                ....
                'metadata' => $metadata,
        ));
    

    Example of form class field:

            ->add('housing', EntityType::class,
                array(
                'class' => 'TruckeeProjectmanaBundle:Housing',
                'choice_label' => 'housing',
                'placeholder' => '',
                'attr' => (in_array('Housing', $options['disabledOptions']) ? ['disabled' => 'disabled'] : []),
                'label' => 'Housing: ',
                'query_builder' => function (EntityRepository $er) use ($options) {
                if (false === in_array('Housing', $options['disabledOptions'])) {
                    return $er->createQueryBuilder('alias')
                        ->orderBy('alias.housing', 'ASC')
                        ->where('alias.enabled=1');
                } else {
                    return $er->createQueryBuilder('alias')
                        ->orderBy('alias.housing', 'ASC');
                }
            },
            ))
            ...
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Truckee\ProjectmanaBundle\Entity\Household',
            'required' => false,
            'disabledOptions' => [],
        ));
    }
    

    Jquery to remove disabled attribute:

    $("input[type=Submit]").click(function () {
        $("input").removeAttr("disabled");
        $("select").removeAttr("disabled");
    });
    

    Example of template & jquery for ManyToMany relationship:

    <div id="household_options" style="display:none;">{{ metadata }}</div>
    

    jquery:

    if (0 < $("#household_options").length) {
        var house_options = JSON.parse($("#household_options").text());
        $.each(house_options, function (index, item) {
            $.each(item, function (k, v) {
                var formAttr = 'household_' + index + '_' + v.id;
                $("#" + formAttr).attr('disabled', 'disabled');
            });
        });
    }
    
    0 讨论(0)
提交回复
热议问题