【symfony】collectionタイプのForm実装
久しぶりsymfonyのブログを書きます。
前から難しいと思ってたcollectionタイプFormの実装について、記事を見て、Entityが複数あってjqueryもあって、簡単に実装できないなあという感じでしたが、簡単な方法を思い出したので、今度こそやってみたいと思います。
Formの設定ファイル
複数のメールアドレスを取りたい場合、下記のようにフォームを設定します。
1 2 3 4 5 6 7 8 9 | $builder->add('emails', 'collection', array( // each item in the array will be an "email" field 'type' => 'email', // these options are passed to each "email" type 'options' => array( 'required' => false, 'attr' => array('class' => 'email-box') ), )); |
twigファイル
少々長くなりますが、大体下記のようになると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <form action="..." method="POST" {{ form_enctype(form) }}> {# ... #} {# store the prototype on the data-prototype attribute #} <ul id="email-fields-list" data-prototype="{{ form_widget(form.emails.vars.prototype) | e }}"> {% for emailField in form.emails %} <li> {{ form_errors(emailField) }} {{ form_widget(emailField) }} </li> {% endfor %} </ul> <a href="#" id="add-another-email">Add another email</a> {# ... #} </form> <script type="text/javascript"> // keep track of how many email fields have been rendered var emailCount = '{{ form.emails | length }}'; jQuery(document).ready(function() { jQuery('#add-another-email').click(function() { var emailList = jQuery('#email-fields-list'); // grab the prototype template var newWidget = emailList.attr('data-prototype'); // replace the "__name__" used in the id and name of the prototype // with a number that's unique to your emails // end name attribute looks like name="contact[emails][2]" newWidget = newWidget.replace(/__name__/g, emailCount); emailCount++; // create a new list element and add it to the list var newLi = jQuery('<li></li>').html(newWidget); newLi.appendTo(jQuery('#email-fields-list')); return false; }); }) </script> |
「Add another email」をクリックすると、
1 2 3 | {{ form_widget(form.emails.vars.prototype) | e }} (下記に変換され) <input type="email" id="form_emails_$$name$$" name="form[emails][$$name$$]" value="" /> |
が
1 | <input type="email" id="form_emails_1" name="form[emails][1]" value="" /> |
に置換され、inputboxが増えていく感じです。
symfony2.0は、prototypeでは
1 | $$name$$ |
を使ってましたが、symfony2.1からは
1 | __name__ |
を使っているらしいです。
Controllerでの処理
Entityにemailsというカラムを持たせて、serializeしてDBに記録すればいいと考えています。
本当に意味あるのか?
collectionタイプって、複数Entityを関連させてはじめて意味があると思います。
単なるデータを記録するなら、テキストエリアを使えば十分対応できるかと思います。
Author Profile
スターフィールド編集部
SHARE