Темы форм - добавьте код при совпадении n block_name

У меня есть переднее приложение Symfony, которое принимает сериализованную форму Symfony из API, анализирует ее и, наконец, отображает ее.

Это приложение должно быть глупым и не должно каким-либо образом знать логику какого-либо удаленного приложения. Он просто принимает форму json и отображает ее после анализа.

Поля в сериализованной форме имеют настраиваемые (определенные удаленным приложением) имена блоков, которые затем используются в темах форм переднего приложения для построения структур полей.

Указанный пример поля:

"field_1": {
    "options": {
        "block_name": "block_name_example",
        "label": "Example",
        "required": true,
        "disabled": false,
        "choices": {
            "Choice 1": "1",
            "Choice 2": "2"
        },
        "help_description": "",
        "attr": {
            "name": "field_name_1",
            "short_name": "fieldName1"
        }
    },
    "type": "Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType"
}

Я хотел бы в блоке form_theme добавить что-то «при первом совпадении этого имени блока» (например), без какой-либо логики, добавленной на стороне удаленного приложения, что-то вроде:

{% block _form_block_name_example %}
    {% if match_occurrence = 1 %}
        {# do something here #}
    {% endif %}
    {{ form_widget(form) }}
{% endblock %}

Я знаю, что есть много способов (дополнительная опция поля формы, обернуть его в поле типа коллекции ...), чтобы решить эту проблему с помощью удаленного редактирования кода приложения, но я не хочу этого по разным причинам, основная из которых заключается в том, чтобы избежать каких-либо дополнительная сложность кода удаленного приложения.

Не удалось найти чистый способ решить эту проблему. Ты будешь моим героем?

JS - События опций формы
JS - События опций формы
В продолжение предыдущей статьи CSS - стили, связанные с вводом формы , в этой статье мы будем использовать JS для взаимодействия с формами, на этот...
CSS - Стили, связанные с вводом формы
CSS - Стили, связанные с вводом формы
Общими стилями ввода для форм являются Input (включая Text, Radio, checkbox), Select и Textarea, из которых Input относительно прост, поэтому в этой...
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Наличие на корпоративном сайте форм заявлений о приеме на работу, или "трудовых анкет", экономит время и деньги как для соискателей, так и для...
0
0
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я придумал довольно простой способ справиться с этим только на лицевой стороне приложения. Максимально убрал классы из несвязанного кода и переименовал некоторые вещи, чтобы сделать его как можно более универсальным для вас.

Я добавил новую дополнительную опцию first_of_type в свои поля через расширение формы, которое я установил при создании формы. Затем я использую его как случайный вариант в блоке моей темы формы. Код ниже.

Расширение формы:

class ExtraOptionsExtension extends AbstractTypeExtension
{
    /**
     * Add the width option.
     *
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefined([
            /* ... */
            'first_of_type'
        ]);
    }

    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        /* ... */
        $view->vars['first_of_type'] = false;
        if (!empty($options['first_of_type'])) {
            $view->vars['first_of_type'] = true;
        }
    }

    /**
     * Returns the name of the type being extended.
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return FormType::class;
    }
}

Тип формы:

abstract class AbstractType extends BaseAbstractType
{
    /* ... */

    /**
     * {@inheritdoc}
     *
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $blockNames = [];
        if (is_array($this->fields)) {
            foreach ($this->fields as $property => $data) {
                $type = $data['type'] ?? null;
                $opts = $data['options'] ?? [];
                if (!in_array($type, $this::TYPES_WITHOUT_EXTRA) &&
                    isset($data['options']['block_name']) &&
                    !in_array($data['options']['block_name'], $blockNames)) {
                    $blockNames[] = $data['options']['block_name'];
                    $opts['first_of_type'] = true;
                }
                $builder->add($property, $type, $opts);
            }
        }
    }

    /* ... */
}

Блок темы формы:

{% block custom_block %}
    <div class = "form-group form-inline {% if not first_of_type %} hide {% else %}">
        {{ form_label(form, null, {'label_attr': {'class': 'control-label'}}) }}
        {{ form_widget(form) }}
    </div>
{% endblock %}

Все еще можно улучшить, чтобы предоставить больше информации о положении элемента по сравнению с его парами (не только тем, что он первый).

Другие вопросы по теме