在Symfony中将Placeholder或空值添加到实体类型,其中multiple = true

时间:2017-08-07 07:17:17

标签: symfony symfony-forms placeholder

我想这样做:

 $builder->add('participants', EntityType::class, array(
        'label' => 'Teilnehmer',
        'class' => SchoolUser::class,
        'multiple' => true,
        'choices' => $this->getParticipantsOfEntry($builder),
        'empty_value'       => 'All',
        'empty_data'        => null,
        'preferred_choices' => array(null)
    ));

但是我没有选择“全部”字段。 我猜不能这么难,我想知道我的错误在哪里。

'placeholder' = 'All',

对我来说也不起作用。

有人有想法吗?

1 个答案:

答案 0 :(得分:1)

我知道这个问题是在4个月前发生的,但我遇到了类似的问题,所以我认为我会分享我的解决方案以防万一。

首先在Form对象中:

class MealFormType extends AbstractType {
  public function buildForm( FormBuilderInterface $builder, array $options ) {
    $builder->add( 'courses', EntityType::class, array(
            'class' => MealCourse::class,
            'multiple' => true,
            ) );
    $builder->addEventListener( FormEvents::PRE_SUBMIT, function( FormEvent $event ) {
        // Remove added entries here... maybe something like
        $data = $event->getData();
        if( ($key = array_search( 'all', $data['courses'] ) ) !== false ) {
            unset( $data['courses'][$key] );
            $event->setData( $data );
        }
    } );
  }
  public function configureOptions( OptionsResolver $resolver ) {
    $resolver->setDefaults( ['data_class' => Meal::class] );
  }
  public function finishView( FormView $view, FormInterface $form, array $options) {
    $newChoice = new ChoiceView( null, 'all', 'I want them all!' );
    array_unshift( $view->children['courses']->vars['choices'], $newChoice );
  }
}

这会创建包含多个膳食课程的表格,例如开胃菜,汤,沙拉,主菜,咖啡,沙漠......,使用buildForm()方法。此外,在此方法中添加了PRE_SUBMIT事件的事件侦听器,其作用是删除我们添加的任何选项,因为它们可能不是真实的(如果它们是,我们就不必以这种痛苦的方式添加它们)。

它在configureOptions()中照常设置data_class。

最后,它提供finishView()方法,创建一个值为'all'的新选项,该选项将显示为'我希望他们全部'选择,然后在“课程”表单条目的“选择”数组的开头添加它(这将$view->children['courses']->vars['choices'][] = $newChoice;放在最后)。

好的,这很好,但除了点击或取消选择其他选项外,它实际上没有任何其他功能。要使用它,我们需要一些Javascript来管理表单。我只是将这个Javascript放在我的Twig文件的底部并使用jQuery。

Twig文件:

{% block body %}
  {{ form_start(mealForm) }}
    {{ form_row(mealForm.courses,
       {'attr': {'class': 'js-meal_course-select'}}) }}
    <button type="submit">Save</button>
  {{ form_end(mealForm) }}
{% endblock %}

{% block javascripts %}
  {{ parent() }}

  <script>
    var mealCourseAllSelected = false;

    jQuery(document).ready( function() {
      // This will be called whenever an entry is selected or deselected
      $('.js-meal_course-select').change( function() {
        var selectedSet = $(this).val();
        if( mealCourseAllSelected  &&
            (selectedSet.length != $(this).get(0).options.length - 1 ||
             selectedSet.includes( 'all' )) ) {
          var opts = $(this).get(0).options;
          var len = opts.length;
          for( var i = 0; i < len; ++i ) {
            if( opts[i].value == 'all' ) opts[i].selected = false;
          }
          mealCourseAllSelected = false;
        } else if( selectedSet.includes( "all" )  ||
                   selectedSet.length == $(this).get(0).options.length - 1 ) {
          $('.js-meal_course-select option').prop( 'selected', true );
          mealCourseAllSelected = true;
        }
      }
    );
  </script>
{% endblock %}

JavaScript响应对所选内容的更改。如果值为'all'的选择选项位于所选集中,则所有选择选项都标记为已选择,并且标志设置为如此。如果选择了除'all'条目之外的所有内容,也会执行此操作,因为这是 all 的定义。

如果设置了'all are selected'标志并且有更改,则该更改必须取消选择至少一个,除非那个是select选项,其值为'all' ,它取消选择值为'all'的选项,并清除“全部被选中”标志。如果选择了所有选项并且用户尝试仅取消选择'all'值的选项,则会重新选择该选项。