私は質問が4ヶ月前だったと知っていますが、同様の問題に遭遇しましたので、他の人に役立つ場合には私のソリューションを共有すると思いました。これは、前菜、スープ、サラダ、前菜、コーヒー、デザート、... buildForm()
を使用するなど、選択することができ、複数の食事のコース、でフォームを作成し
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);
}
}
:Formオブジェクトの最初の
方法。また、このメソッドでは、PRE_SUBMITイベントのイベントリスナーが追加され、そのジョブは実際には実際には存在しないので追加した選択肢を削除することになります(もしそうであれば、この厄介な方法で追加する必要はありません)。
通常、data_classをconfigureOptions()
に設定します。選択中の「私はそれらすべてをしたい」として表示されます
最後に、それは「すべて」の値を持つ新しい選択肢を作成finishView()
方法を提供、その後、「選択肢」の先頭に追加します'コース'フォームエントリの配列(これは末尾に配置すると$view->children['courses']->vars['choices'][] = $newChoice;
になります)。
これは問題ありませんが、実際には、クリックするかクリックを解除するというオプションがあります。これを使用するには、フォームを管理するためにJavascriptが必要です。私はTwigファイルの最後にこのJavascriptを貼り付け、jQueryを使用しました。
小枝ファイル:
{% 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'の値を持つselectオプションでない限り、 'all are selected'フラグが設定され、変更がある場合、少なくとも1つの選択を解除する必要があります。 'all'の値を持つ選択オプションを選択し、 'all are selected'フラグをクリアします。すべてが選択され、ユーザーが'all'の値を持つ選択オプションの選択を解除しようとすると、それはただ再選択されます。
悲しいことにノップ! 'placeholder'オプションは、' multiple'オプションが 'false'に設定されている場合にのみ適用されます。 http://symfony.com/doc/current/reference/forms/types/entity.html#placeholder – yceruto
性交、そういうことをする可能性はありませんか?それを信じてはいけません:D – Slowwie
finishView()メソッドではどうでしょうか?私はそれについてのドキュメントを見つけるのに苦労していますが、https://stackoverflow.com/questions/30013719/symfony2-form-type-entity-add-extra-optionでは、選択肢の最後に新しいオプションを追加するために使用します。 – LavaSlider