dousheyan0375 2013-08-13 21:35
浏览 43

Symfony2.3来自两个权限的动态表单字段

I am trying to create a Product form that has multiple attributes from AttributeSet. The attributes are assigned to the AttributeSet and when the product form is loaded all the assigned attributes will be rendered in the form, Each attribute has a type (text, choice, radio etc...)

I am not sure if this is the right way (I am sure there is a cleaner/better way to do so), but I did it like this:

First added EventSubscriber to the main Product form type

$builder->addEventSubscriber($this->buildProductAttributeFormListener)

In the EventSubscriber I have preSetData event:

public function preSetData(FormEvent $event)
{
    $product = $event->getData();
    $form = $event->getForm();

    if (null === $product->getAttributeSetId()) {
        // need to get attribute set id from request
        $request = Request::createFromGlobals()->get('rs_product_type_step');
        $attributeSetId = $request['attribute_set_id'];
        if (!$attributeSetId) {
            $request = Request::createFromGlobals()->get('rs_product');
            $attributeSetId = $request['attribute_set_id'];
        }
        // get assigned attribute set
        $attributeSet = $this->asRepository->find($attributeSetId);
    } else {
        $attributeSet = $product->getAttributeSetId();
    }

    // If product has attributes, lets add this configuration field.
    if ($attributeSet->hasAttributes()) {
        $form->add('attributes', 'rs_product_attribute_collection', array(
            'options'  => $attributeSet->getAttributes(),
            'required' => false
        ));
    }
}

Inside the 'rs_product_attribute_collection' type, I have this buildForm:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // this loop adds each attribute as a field with his type (choice, text, etc...)   
    foreach ($options['options'] as $i => $attribute) {
        if (!$attribute instanceof AttributeInterface) {
            throw new LogicException('Each object passed as attribute must implement "AttributeInterface"');
        }

        $fieldOptions = array(
            'label' => $attribute->getName(),
        );

        if ($attribute->getType() == 'choice') {
            // add custom options for choice type
            //$fieldOptions = array_merge($fieldOptions, array('mapped' => false));
        }

        if (is_array($attribute->getOptions())) {
            $fieldOptions = array_merge($fieldOptions, $attribute->getOptions());
        }

        $builder->add($attribute->getId(), $attribute->getType(), $fieldOptions);
    }
}

Now I have few issues with these... 1) I am not sure if this is the right way to do so because the form->bind isn't bind the data correctly, so I added PRE_SUBMIT event to get the attributes data from the request and manually assign the attributes to Product. 2) The validation is throwing "This value is not valid" error message for 'choice' field type.

I would like to hear ideas how to make it work.

Thanks, Ron.

  • 写回答

1条回答 默认 最新

  • doupeng3501 2013-08-14 13:47
    关注

    You would need to make the data_class dynamic as well, so that it will use the attributes set fields you adding.

    Also, check this for more details on How to Dynamically Modify Forms Using Form Events http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html.

    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号