【问题标题】:Create form based on EntityType with option to add quantity基于 EntityType 创建表单,并带有添加数量的选项
【发布时间】:2020-03-01 00:10:08
【问题描述】:

我正在尝试设置一个 Symfony 表单,它允许用户选择添加所需数量的多个元素。我希望能够有一个FormType,它介于EntityTypeIntegerType 之间。这意味着我需要有一个基于query_builder 的元素列表来仅选择我的部分产品,但我不只是希望能够选择产品,而是说出我想要多少给定数量的产品。

我已经能够根据我发送的选项创建一个表单。对于我数组中的每个产品,我使用构建器将IntegerType 字段添加到我的表单中。这使我可以显示产品列表并询问客户他想要的元素数量。

现在我遇到的问题是在列表中添加产品的详细数据,因为我不知道无法与标签交互的表单字段名称。如果我可以添加一些内容让我说'label' 可以显示为原始 html,我可以在标签中连接所需的数据。

这是我目前的表格:

class OfferRequestStepMultipleHardwareType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // instead of haveing set fields I create them based on the $option['step']->getProducts() data
        foreach ($options['step']->getProducts() as $product){
            $builder->add($product->getId().'-qty', IntegerType::class, [
                'mapped' => false,
                'attr' => [
                    'value' => 0,
                    'class' => 'longlist',
                    'min' => 0
                ],
                'row_attr' => [
                    'class' => 'longlist'
                ],
                'label' => $product->getNumber() // ideally I would do some thing like '<div>'.$product->getNumber().'</div><div>'.$product->getDescription().'</div>' and then show it as raw in the form template
            ]);
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => OfferRequest::class,
            'step' => StepHardware::class,
        ]);
    }
}

问题是这样生成的代码有点像这样:

<div id="offer_request_step_multiple_hardware">
  <div class="longlist"><label for="offer_request_step_multiple_hardware_27-qty" class="required">Product 1</label><input type="number" id="offer_request_step_multiple_hardware_27-qty" name="offer_request_step_multiple_hardware[27-qty]" required="required" value="0" class="longlist"
      min="0"></div>
  <div class="longlist"><label for="offer_request_step_multiple_hardware_28-qty" class="required">Product 2</label><input type="number" id="offer_request_step_multiple_hardware_28-qty" name="offer_request_step_multiple_hardware[28-qty]" required="required" value="0" class="longlist"
      min="0"></div>
  <div class="longlist"><label for="offer_request_step_multiple_hardware_29-qty" class="required">Product 3</label><input type="number" id="offer_request_step_multiple_hardware_29-qty" name="offer_request_step_multiple_hardware[29-qty]" required="required" value="0" class="longlist"
      min="0"></div>
  <div class="longlist"><label for="offer_request_step_multiple_hardware_30-qty" class="required">Product 4</label><input type="number" id="offer_request_step_multiple_hardware_30-qty" name="offer_request_step_multiple_hardware[30-qty]" required="required" value="0" class="longlist"
      min="0"></div><input type="hidden" id="offer_request_step_multiple_hardware__token" name="offer_request_step_multiple_hardware[_token]" value="PZaPfxKNSV-TjftRgjAw1K8XCUr7Dvkrp57kWTMBJ64"></div>

我还尝试在模板中创建一个表单主题来更改 Integer 小部件的显示方式:

{% form_theme form _self %}

{% block question %}
    <h1>{{ offer.lastStep.Question }}</h1>
{% endblock %}

{% block integer_widget %}
    <div class="name_row">
        {{ form_label(form)|raw }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
        {{ form_help(form) }}
    </div>
{% endblock %}

当我连接并尝试将过滤器“原始”添加到它时没有任何成功,代码仍然自动转义。问题是我找到了有关如何为表单的特定字段设置特定标签的信息,但是我再次在旅途中生成表单并且无法知道字段名称(如here 所述)。关于如何进行这项工作的任何建议?

理想情况下,我希望能够基于 EntityType 创建一个 FormType,这将允许添加一个 Integer 而不是选择 Entity 元素...

任何帮助都会很好!

【问题讨论】:

    标签: forms symfony4


    【解决方案1】:

    Symfony 表单中的标签在模板渲染之前的某个时间点被转义,因此应用 twig raw 过滤器不会阻止 html 实体被转义。

    您可以做的是创建一个新的树枝过滤器,以应用 php 函数 html-entity-decode(以下代码未经测试):

    Twig/HtmlDecodeExtension.php

    <?php
    namespace App\Twig;
    
    use Twig\Extension\AbstractExtension;
    use Twig\TwigFilter;
    
    class HtmlDecodeExtension extends AbstractExtension
    {
        public function getFilters()
        {
            return [
                new TwigFilter('htmldecode', [$this, 'htmlDecode']),
            ];
        }
    
        public function htmlDecode($value)
        {
            return html_entity_decode($value);
        }
    }
    
    

    如果您使用带有服务自动装配的默认配置,you don't have to register the new extension;在其他情况下,请在config/services.yaml

    现在您可以在表单模板中使用过滤器而不是 raw,并将您喜欢的任何 html 放入标签中:

    {% form_theme form _self %}
    
    {% block question %}
        <h1>{{ offer.lastStep.Question }}</h1>
    {% endblock %}
    
    {% block integer_widget %}
        <div class="name_row">
            {{ form_label(form)|htmldecode }}
            {{ form_errors(form) }}
            {{ form_widget(form) }}
            {{ form_help(form) }}
        </div>
    {% endblock %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多