Как заставить шаблон Twig правильно отображать модные переключатели Bootstrap 3? - PullRequest
0 голосов
/ 29 марта 2019

Я использую Symfony 4.2 и пытаюсь создать две радиокнопки Bootstrap 3.Вот HTML-код для того, что я хочу создать:

<div class="btn-group btn-group-justified" data-toggle="buttons">
    <label class="btn btn-lg btn-default">
        <input type="radio" name="inquiry[flexDates]" value="yes">YES
    </label>
    <label class="btn btn-lg btn-default">
        <input type="radio" name="inquiry[flexDates]" value="no">NO
    </label>
</div>

Это мой код конструктора форм:

$builder
    ->add('flexDates', ChoiceType::class, [
        'choices' => [
            'Yes' => 'yes',
            'No'  => 'no',
         ],
         'placeholder' => false,
         'required' => false,
         'empty_data' => '',
         'expanded' => true,  // these two options (expanded = true and
         'multiple' => false, // multiple = false) make it a radio button
     ])

У меня установлена ​​тема Bootstrap 3 (bootstrap_3_layout.html.twig) ипробовал различные комбинации form_row(), form_label() и form_widget().Я установил attr и label_attr несколькими различными способами, но я не могу понять, как генерировать HTML выше.Кажется, всегда есть лишние <div> s или HTML, которые заставляют его некорректно отображаться.

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

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

Я пытался создать свой собственный блочный виджет, но не могу понять, как заставить <label> включать <input> (вместоили после).Чтобы все заработало, метка должна обернуться вокруг ввода.

В файле bootstrap_3_layout.html.twig определено {% block checkbox_radio_label %}, которое близко к тому, что мне нужно, но я не могу заставить его работать.Он использует {{ widget|raw }}, но Symfony выдает мне ошибку variable "widget" does not exist, когда я пытаюсь его использовать.

Пока информация на https://symfony.com/doc/current/form/form_customization.html была скорее запутанной, чем полезной.Я использую Twig в течение многих лет и смог сделать почти все остальное, но эта проблема поставила меня в тупик.Я знаю, что мог бы написать свой собственный фильтр, но похоже, что должен быть более простой способ.

ОБНОВЛЕНИЕ: я смог заставить вещи работать с этим уродливым хаком, который убирает лишние теги:

 {% filter replace({
     '<div class="radio"><label':'<label',
     '</label></div>':'</label>',
     '<div id="inquiry_flexDates">':'',
     '</label></div>':'</label>',
     '</div>':'',
   })|raw %}
   {{ form_widget(form.flexDates, {label_attr:{class: 'btn btn-lg btn-default'}}) }}
{% endfilter %}

Пока работает, но должен быть лучший способ ...

1 Ответ

0 голосов
/ 30 марта 2019

Тип формы ChoiceType особенно неприятен, потому что он делает так много под капотом (в отличие от большинства других «основных» типов форм).Это каким-то образом превращает выбор в свои собственные элементы формы, в зависимости от расширенных и нескольких вариантов.Его рендеринг форм также довольно запутанный / сложный, и я трачу некоторое время на переписывание, и в конце концов я создал новый тип формы только для моего другого рендеринга (потому что я, честно говоря, не мог понять, как управлять опцией block_prefix).

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

class MychoiceType extends ChoiceType {
   function getBlockPrefix() {
       return 'mychoice';
   }
   // find a way to set the expanded option of the ChoiceType 
   // fixed to true
}

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

{% block mychoice_label %}
   {{ parent() }}
{% endblock mychoice_label %}

{% block mychoice_widget %}
   <div class="btn-group btn-group-justified" data-toggle="buttons">
   {% for child in form.children %}
       {# see checkbox_radio_label for more generic version #}
       <label class="btn btn-lg btn-default">
           <input type="radio" name="{{ id }}" value="{{ child.value }}">{{ child.label }}
       </label>
   {% endfor %}
   </div>
{% endblock mychoice_widget %}

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

вам, возможно, придется установитьпредставленный флаг для дочерних элементов формы.не совсем уверен, что чч.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...