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();