Formにcollection type ってのがあります。このprototypeについての説明 詳しくは コチラ(How to Embed a Collection of Forms)を見てもらえればよいのですが、簡単にここでもまとめておこうかと思います。
そもそも collection type ってなんなのか
まぁ、これは名前のままなんですが、typeの集合ですね。 例えば、「あなたの好きな曲はなんですか?」って項目に、TextType(テキストフィールド)が複数ぶら下がる場合を考えれば、 そのTextTypeを集めるのがCollectionTypeとなります。もうちょっとわかりやすく説明しますと、UserにSongがぶら下がるとしましょう。これはOneToManyでUserがすきな曲は複数もてます。 こんなとき、UserTypeのEmbedでSongTypeを埋め込みたいですよね。でも1つのUserに対してSongTypeのフィールドたちをいっぱいもたなくてはならない。それってどうすんの? => ここで使うのが CollectionTypeなわけです。
EntityでもOneToManyの場合、Doctrine\Common\Collections\Collection が使用されますが、このCollectionと同じことなのかな。このCollectionを扱うためのTypeがCollectionType的な。
動的に項目増やしたい場合ってあるよね?
Collectionはなんとなくわかった。ちょっと疑問なんだけど、一般的にSongが上図のように3つしかぶら下がらないとは限らないよね? サービスによっては、Javacript とかで項目を動的に追加したりしたい場合ってあるとおもう。その場合もCollection使うと思うんだけど、どうなのよ?
このために、prototypeがあるわけです。prototypeを使えばフォームの項目のHTML内容をプロトタイプとして持ってくれるので、あとはJavascriptでそれをベースにどんどん増やしてね☆ って話。
- // src/Hoge/UserBundle/Form/Type/UserType.php
- // ...
- public function buildForm(FormBuilder $builder, array $options)
- {
- $builder->add('username');
- $builder->add('songs', 'collection', array(
- 'type' => new SongType(),
- 'allow_add' => true,
- 'allow_delete' => true,
- 'by_reference' => false,
- 'prototype' => true,
- ));
- }
- <ul class="songs" data-prototype="{{ form_widget(form.songs.get('prototype')) | e }}">
- <li></li>
- </ul>
- $(function(){
- var collectionHolder = $('ul.songs');
- var addTagForm = function() {
- // Get the data-prototype we explained earlier
- var prototype = collectionHolder.attr('data-prototype');
- // Replace '$$name$$' in the prototype's HTML to
- // instead be a number based on the current collection's length.
- var newForm = prototype.replace(/\$\$name\$\$/g, collectionHolder.children().length);
- collectionHolder.append('<li>'+newForm+'</li>');
- };
- });
0 コメント:
コメントを投稿