我想这样做:
$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',
对我来说也不起作用。
有人有想法吗?
答案 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'值的选项,则会重新选择该选项。