Создать форму на основе EntityType с возможностью добавления количества - PullRequest
0 голосов
/ 04 ноября 2019

Я пытаюсь настроить форму Symfony, которая позволит пользователю выбирать количество элементов, добавляя желаемое количество. Я хотел бы иметь возможность иметь FormType, который был бы где-то между EntityType и IntegerType. Это означает, что мне нужен список элементов на основе 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 %}

Без каких-либоУспех, когда я конкатенирую и пытаюсь добавить фильтр «raw» к нему, код все равно автоматически изменяется. Проблема в том, что я нашел информацию о том, как установить конкретную метку для определенного поля формы, но снова я генерирую форму на ходу и не могу узнать имена полей (как описано здесь ). Любые предложения о том, как сделать эту работу?

В идеале я хотел бы иметь возможность создать FormType на основе EntityType, который позволил бы добавить Integer вместо выбора элементов Entity ...

Любая помощь была бы хороша!

1 Ответ

0 голосов
/ 05 ноября 2019

Метки в формах Symfony экранируются в какой-то момент перед отображением шаблона, поэтому применение фильтра ветки 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);
    }
}

Если вы используете конфигурацию по умолчанию со службами автопроводки, вам не нужно регистрировать новое расширение ;в другом случае сделайте это в 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 %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...