Well I solved this issue in some of my previous addons (XenRio and XenMedio). For instance, if you were editing/deleting a comment in XenMedio. Clicking on the link to edit/delete brings up a formOverlay. Clicking submit would then edit/delete the comment, and then alter that specific part of the page.
Looking at a media page and it's comment list, its set up as follows:
Code:
<ol class="messageSimpleList">
<li id="comment_9594" class="primaryContent messageSimple">...</li>
<li id="comment_9590" class="primaryContent messageSimple">...</li>
<li id="comment_9583" class="primaryContent messageSimple">...</li>
<li id="comment_9582" class="primaryContent messageSimple">...</li>
<li id="comment_9570" class="primaryContent messageSimple">...</li>
</ol>
As you can see, its a simple ordered list; but whats important to note is that each comment has a unique ID with the ID of that comment in the database. Within each comment list item, it has links to the overlays for editing and deleting:
Code:
<li id="comment_{$comment.comment_id}" class="primaryContent messageSimple">
...
<a href="{xen:link 'media/comment/edit', $comment}" class="OverlayTrigger item">{xen:phrase edit}</a>
<a href="{xen:link 'media/comment/delete', $comment}" class="OverlayTrigger item">{xen:phrase delete}</a>
...
</li>
Thats all thats really needed on the page you are editing. However, on the actual overlay forms, there is another piece of important information. If I use the edit form as an example:
Code:
<form action="{xen:link 'media/comment/edit', $comment}" method="post" id="CommentEditor"
class="xenForm formOverlay AutoValidator" data-comment="{$comment.comment_id}">
...
</form>
It looks the same as any formOverlay, with an AutoValidator; but you'll notice two extra pieces of information. The first being the ID of "CommentEditor" and the data-comment ID parameter being passed to AJAX. This is everything thats needed in templates; the rest are php and js edits.
----
The next thing is my actual php controller. On my software I use the same action for viewing a formOverlay and the actual process of the overlay (behind an isPost() confirmation).
Code:
public function actionCommentEdit()
{
...
if ($this->_request->isPost())
{
$comment = $this->getModelFromCache('EWRmedio_Model_Comments')->updateComment($input);
if ($this->_noRedirect())
{
$viewParams = array(
'comment' => $comment,
);
return $this->responseView('EWRmedio_ViewPublic_MediaComment', 'EWRmedio_Bit_Comment', $viewParams);
}
return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS, XenForo_Link::buildPublicLink('media/media', $comment));
}
...
}
Simple, if the action is a POSTed action, it updates the comment (otherwise it displays the update comment form). However, there is a "noRedirect()" trigger in the code. This noRedirect trigger activates when a form doesn't have a redirect; such as if it's getting fired by an AutoValidator AJAX call... basically when the responseView is JSON, instead of HTML. If it is an AJAX call, it takes the comment, and fetches the template for a comment bit. If its not an AJAX call (such as if someone has javascript disabled in their browser); it will degrade gracefully and do a standard responseRedirect.
Thats all thats really needed in the php... next up is the javascript.
-----
The first thing you gotta do is register your trigger:
Code:
XenForo.register('#CommentEditor', 'XenForo.CommentEditor');
Simple, any form with the ID of "CommentEditor" (which we set up earlier), will call the XenForo.CommentEditor function.
The CommentEditor function is just as easy:
Code:
XenForo.CommentEditor = function($form)
{
$form.bind('AutoValidationComplete', function(e)
{
if (XenForo.hasTemplateHtml(e.ajaxData))
{
new XenForo.ExtLoader(e.ajaxData, function()
{
$(e.ajaxData.templateHtml).xfInsert('replaceAll', '#comment_'+$form.data('comment'), 'xfShow');
});
}
});
}
It binds to the form. After the form finishes validating, it simply replaces the div marked with the ID of "comment_{$comment.comment_id}" (which we also set up earlier) with the parsed template returned on the JSON call. Very simple stuff once you know how it works.
For the delete function I did as follows:
Code:
XenForo.CommentDeleter = function($form)
{
$form.bind('AutoValidationComplete', function(e)
{
$('#comment_'+$form.data('comment')).xfRemove("xfFadeOut");
});
}