# HG changeset patch # User Sylvain Thénault <sylvain.thenault@logilab.fr> # Date 1270655450 -7200 # Wed Apr 07 17:50:50 2010 +0200 # Branch stable # Node ID 2da4fe4c55265f096763040a3738ff7711a42113 # Parent 800f6067a053374b00cea06081c73a005fbd2c2a fix #816385 by [re]loading only new/edited comment and properly edit the DOM using js. Also: cleanup javascript, try to put form where the comment will be located (not yet finished) diff --git a/data/cubes.comment.js b/data/cubes.comment.js --- a/data/cubes.comment.js +++ b/data/cubes.comment.js @@ -19,33 +19,50 @@ } /* this function is called on inlined-comment editions - * It calls the add_comment method on the jsoncontroller and reload - * the comment's component + * It calls the [add|eid]_comment method on the jsoncontroller and [re]load + * only the view for the added or edited comment */ -function processComment(eid, funcname) { - var buttonbar = jQuery('#comment' + eid + 'bbar').hide(); - var divNode = jQuery('#comment' + eid + 'Slot'); +function processComment(eid, funcname, creation) { + var divId = 'comment' + eid + 'Slot' + var divNode = jQuery('#'+divId); var textarea = divNode.find('textarea')[0]; - var comment = _getText(textarea); if (funcname) { - // store original value for edit cancel - textarea.setAttribute('cubicweb:origval', comment); var format = 'text/html'; // no select widget if fckeditor is used var select = divNode.find('select')[0]; if (select) { format = firstSelected(select); } - d = asyncRemoteExec(funcname, eid, comment, format); - d.addCallback(function () { - var rooteid = getNode('commentsectionComponent').getAttribute('cubicweb:rooteid'); - if (rooteid == eid){ - reloadComponent('commentsection', rql_for_eid(eid), 'contentnavigation'); - } else { - reloadComponent('tree', rql_for_eid(eid), 'views', 'comment'+eid); + d = asyncRemoteExec(funcname, eid, _getText(textarea), format); + d.addCallback(function (neweid) { + if (creation) { + var commentNode = jQuery('#comment'+ eid); + var ul = null; + if (!commentNode.length) { + // we are adding a comment to the top level entity + commentNode = jQuery('#commentsectionComponent'); + klass = 'comment'; + } else { + klass = 'section'; + } + ul = commentNode.find('> ul:first'); + if (!ul.length) { + ul = jQuery(UL({'class': klass})); + commentNode.append(ul); + } + ul.append(LI({'id': 'comment'+ neweid, 'class': 'comment'}, + DIV({'id': 'comment'+ neweid + 'Div'}))); + divNode.remove(); + eid = neweid; } + replacePageChunk('comment' + eid + 'Div', rql_for_eid(eid), 'treeitem'); }); - } else { // comment cancelled, close div holding the form - jQuery('#comment' + eid + 'Slot').remove(); + } else { + // comment cancelled, close div holding the form + divNode.remove(); + // on edition, show back the comment's content + if (!creation) { + jQuery('#comment' + eid + 'Div div').show(); + } } } diff --git a/views.py b/views.py --- a/views.py +++ b/views.py @@ -27,7 +27,7 @@ from cubicweb.web.formwidgets import Button from cubicweb.web.views import primary, baseviews, xmlrss from cubicweb.web.component import EntityVComponent -from cubicweb.web.views.basecontrollers import JSonController +from cubicweb.web.views.basecontrollers import JSonController, jsonize uicfg.autoform_section.tag_subject_of(('*', 'comments', '*'), formtype='main', section='hidden') @@ -114,6 +114,9 @@ self._cw.add_css('cubes.comment.css') entity = self.cw_rset.get_entity(row, col) actions = self._cw.vreg['actions'] + # DOM id of the whole comment's content + cdivid = 'comment%sDiv' % entity.eid + self.w(u'<div id="%s">' % cdivid) self.w(u'<div class="commentInfo">') self.w(self._cw.format_date(entity.creation_date)) self.w(u' %s' % self._cw.format_time(entity.creation_date)) @@ -137,9 +140,11 @@ editaction = actions.select_or_none('edit_comment', self._cw, rset=self.cw_rset, row=row) if editaction is not None: - url = self._cw.build_ajax_replace_url( - 'comment%s' % entity.eid, rql_for_eid(entity.eid), - 'editcomment') + # split(':', 1)[1] to remove javascript: + formjs = self._cw.build_ajax_replace_url( + cdivid, rql_for_eid(entity.eid), + 'editcomment', 'append').split(':', 1)[1] + url = "javascript: jQuery('#%s div').hide(); %s" % (cdivid, formjs) self.w(u' | <span class="replyto"><a href="%s">%s</a></span>' % (xml_escape(url), self._cw._(editaction.title))) @@ -152,14 +157,12 @@ self.w(u' | <span class="replyto"><a href="%s">%s</a></span>' % (xml_escape(url), self._cw._(deleteaction.title))) - - self.w(u'</div>\n') - text = entity.printable_value('content') - if not kwargs.get('full'): - maxsize = self._cw.property_value('navigation.short-line-size') - text = safe_cut(text, maxsize) - self.w(u'<div class="commentBody">%s</div>\n' % text) + self.w(u'</div>\n') # close comment's info div + self.w(u'<div class="commentBody">%s</div>\n' + % entity.printable_value('content')) + # holder for reply form self.w(u'<div id="comment%sHolder" class="replyComment"></div>' % entity.eid) + self.w(u'</div>\n') # close comment's content div class CommentThreadView(TreeViewMixIn, baseviews.ListView): @@ -185,7 +188,7 @@ __regid__ = 'editcomment' __select__ = implements('Comment') - jsfunc = "processComment(%s, '%s')" + jsfunc = "processComment(%s, '%s', false)" jsonmeth = 'edit_comment' def cell_call(self, row, col): @@ -215,6 +218,7 @@ __regid__ = 'inlinecommentform' __select__ = match_kwargs('commented') # explicit call when it makes sense + jsfunc = "processComment(%s, '%s', true)" jsonmeth = 'add_comment' def call(self, commented): @@ -247,10 +251,17 @@ rset = req.execute(rql, {'x': eid}, 'x') if rset.rowcount: self.w(u'<h4>%s</h4>' % (req._('Comment_plural'))) + if rset.rowcount: + self.w(u'<ul class="comment">') + for i in xrange(rset.rowcount): + self.wview('tree', rset, row=i) + self.w(u'</ul>') + self.w(u'</div>') addcomment = self._cw.vreg['actions'].select_or_none('reply_comment', req, rset=self.cw_rset, row=row, col=col) if addcomment is not None: + self.w(u'<div id="comment%sHolder"></div>' % eid) url = req.build_ajax_replace_url( 'comment%sHolder' % eid, rql_for_eid(eid), 'inlinecomment') self.w(u' (<a href="%s" onclick="javascript:toggleVisibility(\'addCommentLinks\');">%s</a>)' % (url, req._(addcomment.title))) @@ -260,13 +271,6 @@ if req.cnx.anonymous_connection: self.w(u'<div id="addCommentLinks" class="hidden">%s %s</div>' % \ (_login_register_link(req), req._(u'to comment'))) - self.w(u'<div id="comment%sHolder"></div>' % eid) - if rset.rowcount: - self.w(u'<ul class="comment">') - for i in xrange(rset.rowcount): - self.wview('tree', rset, row=i, full=True) - self.w(u'</ul>') - self.w(u'</div>') # comment actions ############################################################# @@ -333,12 +337,14 @@ # add some comments related methods to the Jsoncontroller ##################### @monkeypatch(JSonController) +@jsonize def js_add_comment(self, commented, text, format): - self._cw.execute('INSERT Comment C: C comments X, C content %(text)s, ' - 'C content_format %(format)s WHERE X eid %(x)s', - {'format' : format, 'text' : text, 'x' : commented}, 'x') + return self._cw.execute('INSERT Comment C: C comments X, C content %(text)s, ' + 'C content_format %(format)s WHERE X eid %(x)s', + {'format' : format, 'text' : text, 'x' : commented}, 'x')[0][0] @monkeypatch(JSonController) +@jsonize def js_edit_comment(self, comment, text, format): self._cw.execute('SET C content %(text)s, C content_format %(format)s ' 'WHERE C eid %(x)s',