Symfony: one entity class with multiple instances each with its own form all on one page -
use case:
a user makes public and/or private notes expertise record. these notes displayed in sidebar of page shows expertise record. notes grouped 2 sets: current user's notes (both public , private) , public notes other users. current user's notes editable , deletable. each delete icon link route. each edit icon javascript toggle display form particular note (the edit form looks add form except it's populated). 1 note should added/edited or deleted per submit action. submission not through ajax. page looks this:
problem
how can display , process independent form both 'new note' , each of notes in 'my notes' section?
if embed collection of notetype forms in expertisetype form, processing correct cannot seem group forms 'add note', 'my notes' , 'public notes' sections. , worse, public notes editable. i've abandoned approach since there not easy way filter notes have forms.
if subset notes in controller , create form each one, every note processed though new note unless use named forms. named forms, new notes correctly created. edits applied recent note, and other notes have privacy , text fields set column default. how can around this?
twig template of sidebar:
{% block sidebar %} <div id='sidebar'><h2>profile notes</h2> {% flashmessage in app.session.flashbag.get('note_success') %} <div class="flash-success"> {{ flashmessage }} </div> {% endfor %} <fieldset class='wrapper'><legend>add note</legend> {{ form(form) }} </fieldset> {% if usernotes|length > 0 %} <fieldset><legend>my notes</legend> <dl> {% note in usernotes%} <dt>{{ note.moddate|date("y-m-d h:i") }} <a class='actionlink' href='{{ path('exp_delnote', {'id':note.id}) }}' title="delete"><img src="{{ asset('images/silk_icons/delete.png') }}" alt="delete note"></a> <a class='actionlink inlineedit' href='#' data-editform="{{ form(note.myform)|e }}" title="edit note"><img src="{{ asset('images/silk_icons/pencil.png') }}" alt="edit note"></a> </dt> <dd class='note_{{ note.private ? 'priv' : 'pub' }}' title='{{ note.private ? 'private note' : 'public note'}}'>{{ note.note }}</dd> {% endfor %} </dl> </fieldset> {% endif %} {% if publicnotes|length > 0 %} <fieldset><legend>public notes</legend> <dl> {% note in publicnotes%} <dt>{{ note.moddate|date("y-m-d h:i") }}, {{ note.person|expadinfo("fullname") }}</dt> <dd>{{ note.note }}</dd> {% endfor %} </dl> </fieldset> {% endif %} </div> {% endblock %}
entities
there 3 entity classes in play: expertise
, note
, person
. expertise
entity has collection of notes
. each note
associated person
(its "owner") , expertise
record. entities managed doctrine.
my current controller method
this creates new notes. no matter note edit, changes applied recent note , other editable notes have text , privacy fields set column default.
public function profileaction($uname){ $request = $this->get('request'); $adsearcher = $this->get('exp_adsearcher'); $userrecord = $adsearcher->getrecordbyusername($uname); if(!$userrecord) throw $this->createnotfoundexception('no such person exists.'); $userrecord->setlocale($request->get('_locale')); $person = $adsearcher->getpersonbyrecord($userrecord); $expertise = $this->getexpertiseentity($person); $curuser = $adsearcher->getpersonbyusername($this->getuser()->getusername()); //add new note, , trying use named form $newnote = $this->getnewnote($expertise, $curuser); $addnoteform = $this->get('form.factory')->createnamedbuilder('newnote', new notetype(), $newnote)->getform(); $addnoteform->handlerequest($request); if($addnoteform->isvalid()){ $em = $this->getdoctrine()->getmanager(); $em->persist($newnote); $em->flush(); $this->get('session')->getflashbag()->add( 'note_success', $this->get('translator')->trans('message.note.add.success') ); $addnoteform = $this->createform(new notetype, $this->getnewnote($expertise, $curuser)); //so add form empty } //get editable notes $usernotes = $expertise->getusernotes($curuser); foreach($usernotes $note){ $form = $this->get('form.factory')->createnamedbuilder('note'.$note->getid(), new notetype(), $note)->getform(); $form->handlerequest($request); if($form->isvalid()){ $msg = 'message.note.edit.success'; $em = $this->getdoctrine()->getmanager(); $em->persist($expertise); $em->flush(); $this->get('session')->getflashbag()->add( 'note_success', $this->get('translator')->trans('message.note.edit.success') ); return $this->redirect($this->generateurl('exp_profile', array('uname'=>$uname))); } $note->myform = $form->createview(); } //get public notes, not editable $publicnotes = $expertise->getpublicnotes($curuser, $adsearcher); return array('userrecord'=> $userrecord, 'expertise'=>$expertise,'usernotes'=>$usernotes, 'publicnotes'=>$publicnotes, 'form'=>$addnoteform->createview()); }
lets see if can more helpful time.
make notestype hold 0 or more notes.
class notestype extends abstracttype public function buildform(formbuilderinterface $builder, array $options) { $builder->add('notes', 'collection', array('type' => new notetype());
your controller needs make 2 forms, 1 new note , 1 existing notes
public function profileaction($uname) { // 1 form new note $newnote = $this->getnewnote($expertise, $curuser); $newnoteform = $this->createform(new notetype(), $newnote); // 1 form existing notes $usernotes = $expertise->getusernotes($curuser); $usernotesdata = array('notes' => $usernotes); $usernotesform = $this->createform(new notestype(), $usernotesdata); // not attempt process forms here // pass onto template $tpldata = array(); $tpldata['newnoteform'] = $newnoteform->createview(); $tpldata['usernotesform'] = $usernotesform->createview(); return $tpldata;
so have 2 independent forms, 1 new note , 1 list of existing notes. adjust template accordingly. want newnoteform post different action usernotesform. allow process each form independently. after processing form redirect profileaction.
public function postusernotesaction() { // 1 form existing notes $usernotes = $expertise->getusernotes($curuser); $usernotesdata = array('notes' => $usernotes); $usernotesform = $this->createform(new notestype(), $usernotesdata); $usernotesform->handlerequest($request); if($usernotesform->isvalid()) { $usernotesdata = $usernotesform->getdata(); $usernotes = $usernotesdata['notes']; $em->flush(); // redirect
Comments
Post a Comment