diff --git a/apps/reviews/forms.py b/apps/reviews/forms.py
index cd26564b826..7c9e37d6c80 100644
--- a/apps/reviews/forms.py
+++ b/apps/reviews/forms.py
@@ -18,8 +18,19 @@
class ReviewReplyForm(forms.Form):
- title = forms.CharField(required=False)
- body = forms.CharField(widget=forms.Textarea(attrs={'rows': 3}))
+ title = forms.CharField(
+ required=False,
+ label="Title",
+ widget=forms.TextInput(
+ attrs={'id':'id_review_reply_title'},
+ ),
+ )
+ body = forms.CharField(
+ widget=forms.Textarea(
+ attrs={'rows': 3, 'id':'id_review_reply_body'},
+ ),
+ label="Review",
+ )
def clean_body(self):
body = self.cleaned_data.get('body', '')
@@ -28,9 +39,25 @@ def clean_body(self):
raise_required()
return body
+ def form_id(self):
+ return "review-reply-edit"
+
class ReviewForm(ReviewReplyForm):
- rating = forms.ChoiceField(zip(range(1, 6), range(1, 6)))
+ title = forms.CharField(
+ required=False,
+ label="Title",
+ widget=forms.TextInput(
+ attrs={'id':'id_review_title'},
+ ),
+ )
+ body = forms.CharField(
+ widget=forms.Textarea(
+ attrs={'rows': 3, 'id':'id_review_body'},
+ ),
+ label="Review",
+ )
+ rating = forms.ChoiceField(zip(range(1, 6), range(1, 6)), label="Rating")
flags = re.I | re.L | re.U | re.M
# This matches the following three types of patterns:
# http://... or https://..., generic domain names, and IPv4
@@ -50,6 +77,9 @@ def _post_clean(self):
self.cleaned_data['flag'] = True
self.cleaned_data['editorreview'] = True
+ def form_id(self):
+ return "review-edit"
+
class ReviewFlagForm(forms.ModelForm):
diff --git a/apps/reviews/helpers.py b/apps/reviews/helpers.py
index 0af283a60b0..cfc0bee7ccf 100644
--- a/apps/reviews/helpers.py
+++ b/apps/reviews/helpers.py
@@ -61,6 +61,15 @@ def edit_review_form(context):
return c
+@jingo.register.inclusion_tag('reviews/edit_review.html')
+@jinja2.contextfunction
+def edit_review_reply_form(context):
+ c = dict(context.items())
+ c.update(form=forms.ReviewReplyForm())
+ return c
+
+
+
def user_can_delete_review(request, review):
"""Return whether or not the request.user can delete reviews.
diff --git a/apps/reviews/templates/reviews/edit_review.html b/apps/reviews/templates/reviews/edit_review.html
index b2110932281..6aa3e62a25a 100644
--- a/apps/reviews/templates/reviews/edit_review.html
+++ b/apps/reviews/templates/reviews/edit_review.html
@@ -1,19 +1,19 @@
{% from "includes/forms.html" import pretty_field, required_note %}
diff --git a/apps/reviews/templates/reviews/review.html b/apps/reviews/templates/reviews/review.html
index dde3369a4ff..3786bd5f2bb 100644
--- a/apps/reviews/templates/reviews/review.html
+++ b/apps/reviews/templates/reviews/review.html
@@ -85,7 +85,7 @@ {{ addon.name }}
{% if review.user_id == request.user.id %}
{% if is_reply %}
-
+
{{ _('Edit reply') }}
{% else %}
diff --git a/apps/reviews/templates/reviews/review_list.html b/apps/reviews/templates/reviews/review_list.html
index 329b4943d48..057a5bf473c 100644
--- a/apps/reviews/templates/reviews/review_list.html
+++ b/apps/reviews/templates/reviews/review_list.html
@@ -95,6 +95,7 @@ {{ _('No reviews found.') }}
{{ reviews|impala_paginator }}
{% endblock review_list %}
{{ edit_review_form() }}
+ {{ edit_review_reply_form() }}
{{ report_review_popup() }}
{% endblock content %}
diff --git a/static/js/impala/reviews.js b/static/js/impala/reviews.js
index cfd22c6f599..2b51970a438 100644
--- a/static/js/impala/reviews.js
+++ b/static/js/impala/reviews.js
@@ -56,75 +56,93 @@ $(document).ready(function() {
}
});
- $('.primary').delegate('.review-edit', 'click', function(e) {
- e.preventDefault();
- var $form = $('#review-edit-form'),
- $review = $(this).closest('.review'),
- rating = $review.attr('data-rating'),
- edit_url = $('a.permalink', $review).attr('href') + 'edit',
- $cancel = $('#review-edit-cancel'),
- title_selector;
-
- clearErrors($form);
- $form.unbind().hide();
- $('.review').not($review).show();
- $form.detach().insertAfter($review);
-
- if ($review.find('h4').length) {
- $form.find('fieldset h3').remove();
- title_selector = 'h4 > b';
- $form.find('fieldset').prepend($review.find('h3').clone());
- } else {
- title_selector = 'h3 > b';
- }
-
- $form.find('#id_title').val($review.find(title_selector).text());
- $form.find('.ratingwidget input:radio[value=' + rating + ']').click();
- $form.find('#id_body').val($review.children('p.description').html().replace(/
/g, '\n'));
- $review.hide();
- $form.show();
- $window.resize();
- location.hash = '#review-edit-form';
+ // A review comment can either be a review or a review reply
+ function review_comment_edit_click(comment_form_id, comment_title_widget_id, comment_body_widget_id, comment_cancel_btn_id) {
+ return function(e) {
+ e.preventDefault();
+ var $form = $('#' + comment_form_id),
+ $review = $(this).closest('.review'),
+ edit_url = $('a.permalink', $review).attr('href') + 'edit',
+ $cancel = $('#' + comment_cancel_btn_id),
+ title_selector;
- function done_edit() {
clearErrors($form);
$form.unbind().hide();
- $review.show();
- $cancel.unbind();
+ $('.review').not($review).show();
+ $form.detach().insertAfter($review);
+
+ if ($review.find('h4').length) {
+ $form.find('fieldset h3').remove();
+ title_selector = 'h4 > b';
+ $form.find('fieldset').prepend($review.find('h3').clone());
+ } else {
+ title_selector = 'h3 > b';
+ }
+
+ $form.find('#' + comment_title_widget_id).val($review.find(title_selector).text());
+ $form.find('#' + comment_body_widget_id).val($review.children('p.description').html().replace(/
/g, '\n'));
+ $review.hide();
+ $form.show();
$window.resize();
- }
+ location.hash = '#' + comment_form_id;
- $cancel.click(_pd(done_edit));
+ function done_edit() {
+ clearErrors($form);
+ $form.unbind().hide();
+ $review.show();
+ $cancel.unbind();
+ $window.resize();
+ }
- $form.submit(function (e) {
- e.preventDefault();
- $.ajax({type: 'POST',
- url: edit_url,
- data: $form.serialize(),
- success: function(response, status) {
- clearErrors($form);
- $review.find(title_selector).text($form.find('#id_title').val());
- var rating = $form.find('.ratingwidget input:radio:checked').val();
- $('.stars', $review).removeClass('stars-0 stars-1 stars-2 stars-3 stars-4 stars-5').addClass('stars-' + rating);
- rating = $review.attr('data-rating', rating);
- $review.children('p.description').html(
- $form.find('#id_body').val()
- .replace(/&/g,'&')
- .replace(//g,'>')
- .replace(/\n/g, '
'));
- done_edit();
- },
- error: function(xhr) {
- var errors = $.parseJSON(xhr.responseText);
- populateErrors($form, errors);
- },
- dataType: 'json'
- });
- return false;
- });
- });
+ $cancel.click(_pd(done_edit));
+ $form.submit(function (e) {
+ e.preventDefault();
+ $.ajax({type: 'POST',
+ url: edit_url,
+ data: $form.serialize(),
+ success: function(response, status) {
+ clearErrors($form);
+ $review.find(title_selector).text($form.find('#' + comment_title_widget_id).val());
+ var rating = $form.find('.ratingwidget input:radio:checked').val();
+ $('.stars', $review).removeClass('stars-0 stars-1 stars-2 stars-3 stars-4 stars-5').addClass('stars-' + rating);
+ rating = $review.attr('data-rating', rating);
+ $review.children('p.description').html(
+ $form.find('#' + comment_body_widget_id).val()
+ .replace(/&/g,'&')
+ .replace(//g,'>')
+ .replace(/\n/g, '
'));
+ done_edit();
+ },
+ error: function(xhr) {
+ var errors = $.parseJSON(xhr.responseText);
+ populateErrors($form, errors);
+ },
+ dataType: 'json'
+ });
+ return false;
+ });
+ }
+ }
+
+ $('.primary').delegate('.review-reply-edit', 'click',
+ review_comment_edit_click(
+ 'review-reply-edit-form',
+ 'id_review_reply_title',
+ 'id_review_reply_body',
+ 'review-reply-edit-cancel'
+ )
+ );
+
+ $('.primary').delegate('.review-edit', 'click',
+ review_comment_edit_click(
+ 'review-edit-form',
+ 'id_review_title',
+ 'id_review_body',
+ 'review-edit-cancel'
+ )
+ );
$('.delete-review').click(function(e) {
e.preventDefault();