用户提供有关专业知识记录的公开和/或私人说明。这些注释显示在页面的侧栏中,显示专业知识记录。这些笔记分为两组:当前用户的笔记(公共和私人)和其他用户的公共笔记。所有当前用户的笔记都是可编辑和可删除的。每个删除图标都是指向路径的链接。每个编辑图标都是一个javascript切换,以显示特定注释的表单(编辑表单看起来像添加表单,除了它已填充)。每个提交操作只应添加/编辑或删除一个注释。提交不通过ajax。该页面看起来像这样:
如何为“新笔记”和“我的笔记”部分中的每个笔记显示和处理独立表单?
如果我在ExpertiseType表单中嵌入了一组NoteType表单,处理是正确的,但我似乎无法将表单分组为“添加注释”,“我的注释”和“公共注释”部分。更糟糕的是,公共笔记是可编辑的。我已经放弃了这种方法,因为没有简单的方法来过滤哪些笔记有形式。
如果我将控件中的音符分组并为每个音符创建一个表单,则每个音符都会被处理,就像它是一个新音符一样,除非我使用命名表格。使用命名表单,可以正确创建新注释。但是所有编辑都应用于最新的注释,和所有其他注释的隐私和文本字段都设置为默认列。我怎么能绕过这个?
{% block sidebar %}
<div id='sidebar'><h2>Profile Notes</h2>
{% for flashMessage in app.session.flashbag.get('note_success') %}
<div class="flash-success">
{{ flashMessage }}
</div>
{% endfor %}
<fieldset class='wrapper'><legend>Add a note</legend>
{{ form(form) }}
</fieldset>
{% if usernotes|length > 0 %}
<fieldset><legend>My notes</legend>
<dl>
{% for 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>
{% for 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 %}
有3个实体类:Expertise
,Note
和Person
。 Expertise
实体的集合为Notes
。每个Note
都与Person
(其“所有者”)和Expertise
记录相关联。实体由Doctrine管理。
这成功创建了新笔记。但无论我编辑哪个音符,更改都会应用于最近的音符,而其他可编辑的音符会将其文本和隐私字段设置为默认列。
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 a new note, and trying to use a 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 that add form is always empty
}
//get all the editable notes
$usernotes = $expertise->getUserNotes($curuser);
foreach($usernotes as $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 all the public notes, not editable
$publicnotes = $expertise->getPublicNotes($curuser, $adsearcher);
return array('userrecord'=> $userrecord, 'expertise'=>$expertise,'usernotes'=>$usernotes, 'publicnotes'=>$publicnotes, 'form'=>$addnoteform->createView());
}
答案 0 :(得分:1)
让我们看看这次我是否可以提供更多帮助。
让自己成为一个NotesType,它将包含零个或多个音符。
class NotesType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('notes', 'collection', array('type' => new NoteType());
您的控制器需要制作两个表单,一个用于新笔记,另一个用于现有笔记
public function profileAction($uname)
{
// One form for a new note
$newNote = $this->getNewNote($expertise, $curuser);
$newNoteForm = $this->createForm(new NoteType(), $newNote);
// One form for existing notes
$userNotes = $expertise->getUserNotes($curuser);
$userNotesData = array('notes' => $userNotes);
$userNotesForm = $this->createForm(new NotesType(), $userNotesData);
// Do NOT attempt to process the forms here
// Just pass onto the template
$tplData = array();
$tplData['newNoteForm'] = $newNoteForm->createView();
$tplData['userNotesForm'] = $userNotesForm->createView();
return $tplData;
所以现在我们有两个独立的表格,一个用于新笔记,另一个用于现有笔记列表。相应地调整模板。您将希望newNoteForm发布到与userNotesForm不同的操作。这将允许您独立处理每个表单。处理完表单后,您将重定向回profileAction。
public function postUserNotesAction()
{
// One form for 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