私はToDoリストを作成するためにSymfony 2.7で作業しています。Symfonyフォーム - CollectionType要素の並べ替え/並べ替え
class TodoType extends AbstractType {
public function getName() {
return 'todo_list';
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\TodoList',
));
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', 'text', array(
'label' => 'Name',
...
))
->add('create', 'submit', array(
'label' => 'Save',
...
));
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$todoList = $event->getData();
$form = $event->getForm();
$form
->add('items', 'collection', array(
'type' => 'todo_list_item_type',
'allow_add' => true,
'allow_delete' => true,
//'by_reference' => false,
'data' => ($todoList != null ? $todoList->getItems() : null),
));
});
}
}
}
これは正常に動作します:Form
、リスト名とitems
の収集のための単純なテキストフィールドが含まれています。
<form ...>
...
<ul class="sortable">
<li>
<input id="todo_list_items_0_name" class="item-name form-control" type="text" value="Shopping" placeholder="Name" required="required" name="todo_list[items][0][name]">
</li>
<li>
<input id="todo_list_items_1_name" class="item-name form-control" type="text" value="Wash car" placeholder="Name" required="required" name="todo_list[items][1][name]">
</li>
...
<ul>
今、私はアイテムを並べ替えるためにjQuery Sortable Pluginを使用したい:items配列は、「アレイのスタイル」の名前を使用してフォームに含まれています。これは正常に動作します。ユーザーは、好きなように項目を並べ替えることができます。ただし、アイテムの格納順序には影響しません。
私はこの問題は明白だと思う:ソート可能なプラグインは、同じまま、その配列インデックスが含まれ、項目名ながらDOM
内のアイテムの位置を変更します。したがって、リスト内の新しい位置に関係なく、フォームが提出された時点でItem0にはまだindex = 0
が残っています。
これを解決するソリューションはありますか?私が見つけた唯一の解決策は、ソート可能なプラグイン(リオーダが完了した後にトリガされる)のstop
イベントを聞き、手動でいくつかのJavaScriptを使用してフィールド名内のインデックス番号を検索/置き換えることです。もちろん、これはうまくいくかもしれませんが、フィールド名の変更に対して非常に脆弱です。たとえば、symfonyの将来のバージョンがsome_field_0_name
の代わりにsome_field_name_0
を使用する場合、置き換えコードはそれ以上は機能しません。
別の解決策は、追加のフィールドsortOrder
でItem
クラスを拡張し、この情報をフォームの非表示フィールドとして含めることです。私はまだJSを使用して手動でこのインデックスを更新する必要がありますが、少なくとも私はフォーマットをより詳細に制御するでしょう。
しかし、もっと簡単な方法がないかと思います。コレクション型のソートは特別なものではありません。だから、おそらく箱の解決策がありますか?
ありがとうございました! '__name__'をインデックス番号を再設定するときに簡単に特定できるカスタムコンテンツに置き換えるのは良い選択です。私は既にプロトタイプを使って新しい項目をフォームに動的に追加しています。この段階で '__name__'値を簡単に変更できます。しかし、私は既に存在し、したがってフォームにロードされているアイテムのために、これがどのように機能するのか理解していません。私はこれらの価値/品目に影響を与えません。 –
あなたが見つけた解決策を見つけ、フィールドの名前を変更して正しい順序がSymfonyに "送られ"て、新しい名前を生成するためのテンプレートが得られます。したがって、あなたが言及したように、ソリューションをSymfonyのアップグレード/変更から免れることができます。 – romaricdrigon