Помогите AJAX обновить отредактированный комментарий в Rails 3 с помощью jQuery - PullRequest
1 голос
/ 11 апреля 2011

Когда я редактирую уже существующий комментарий и нажимаю «сохранить», который в моем jquery нажимает input#comment_submit, он скрывает мою форму редактирования и показывает список из исходного состояния (то есть до обновления).

Но если я обновлю страницу, она покажет обновленный комментарий - который показывает мне, что комментарий был фактически обновлен через Rails. Так что не уверен, что происходит.

Конечный продукт, который я хочу:

  • Нажмите изменить. Введите обновления для комментария.
  • Нажмите сохранить. jQuery скрывает поле редактирования и показывает обновленный комментарий - без полного обновления страницы.

Вот HTML-код для комментария:

<div class="comment-show"> 
   <div class="details"> 
    <span class="comment_name">Test</span> said
   </div> 
   <div class="uploads"> 
      <div class="upload-image" title="red-stripe-dark.jpg"><img alt="Red-stripe-dark" src="red-stripe-dark.jpg" /></div> 
      <div class="upload-image selected-image" title="red-stripe-original.jpg"><img alt="Red-stripe" src="red-stripe.jpg" /></div> 
      <div class="upload-image selected-image" title="red-stripe-red.jpg"><img alt="Red-stripe-red" src="red-stripe-red.jpg" /></div> 
      <div class="upload-image" title="red-stripe-bw.jpg"><img alt="Red-stripe-bw" src="red-stripe-bw.jpg" /></div> 
   </div> 
   <div class="body"> 
      This is extremely ugly. WOW.Let's see if this works any at all.<br /> 
       <span class="timestamp">about 1 hour ago</span> 
      <div class="comment-buttons"> 
        <button class="comment-edit green awesome">Edit</button> 
        <button class="red awesome" data-destroy-url="/comments/28" data-destroy-title="Delete this comment?" data-compv-mapping="comments.destroy">Delete</button> 
      </div> 
    </div> 
</div>

    <div class="comment-form" style="display:none"> 

    <form accept-charset="UTF-8" action="/comments/28" class="ajax-form" data-remote="true" id="comment-ajax-form-update" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div> 
<input id="comment_stage_id" name="comment[stage_id]" type="hidden" value="46" /> 
<input id="comment_user_id" name="comment[user_id]" type="hidden" value="1" /> 
<h3>Add a Comment</h3> 


<div> 
    <div class="uploads" > 
    <div class="hint">Select the images you are discussing</div> 

        <div class="upload-image image-selector" title="red-stripe-dark.jpg" id="image-selector-141"> 
         <img alt="Red-stripe-dark" src="red-stripe-dark.jpg" /> 
        <input autocomplete="off" id="comment[uploads_ids][141]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="141" /> 
         </div> 
        <div class="upload-image image-selector" title="red-stripe-original.jpg" id="image-selector-140"> 
         <img alt="Red-stripe" src="red-stripe.jpg" /> 
        <input autocomplete="off" checked="checked" id="comment[uploads_ids][140]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="140" /> 
         </div> 
        <div class="upload-image image-selector" title="red-stripe-red.jpg" id="image-selector-139"> 
         <img alt="Red-stripe-red" src="red-stripe-red.jpg" /> 
        <input autocomplete="off" checked="checked" id="comment[uploads_ids][139]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="139" /> 
         </div> 
        <div class="upload-image image-selector" title="red-stripe-bw.jpg" id="image-selector-138"> 
         <img alt="Red-stripe-bw" src="red-stripe-bw.jpg" /> 
        <input autocomplete="off" id="comment[uploads_ids][138]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="138" /> 
         </div> 
    </div> 

<textarea cols="40" id="comment_body" name="comment[body]" rows="10" style="width: 100%">This is extremely ugly. WOW. Let's see if this works any at all.</textarea>
    <div class="actions"> 
      <input class="green awesome" id="comment_submit" name="commit" type="submit" value="Save" /> 
       <button class="comment-form-cancel red awesome">Cancel</button> 
    </div> 
    </div> 
   <br style="clear:both" /> 
  </form> 

</div> 
   </li> 
 </ul> 
 <div id="comment-form"> 

 <form accept-charset="UTF-8" action="/comments" class="ajax-form" data-remote="true" id="comment-ajax-form-create" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div> 
<input id="comment_stage_id" name="comment[stage_id]" type="hidden" value="46" /> 
<input id="comment_user_id" name="comment[user_id]" type="hidden" value="1" /> 
<h3>Add a Comment</h3> 


<div> 
    <div class="uploads" > 
    <div class="hint">Select the images you are discussing</div> 

        <div class="upload-image image-selector" title="red-stripe-dark.jpg" id="image-selector-141"> 
         <img alt="Red-stripe-dark" src="red-stripe-dark.jpg" /> 
        <input autocomplete="off" id="comment[uploads_ids][141]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="141" /> 
         </div> 
        <div class="upload-image image-selector" title="red-stripe-original.jpg" id="image-selector-140"> 
         <img alt="Red-stripe" src="red-stripe.jpg" /> 
        <input autocomplete="off" id="comment[uploads_ids][140]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="140" /> 
         </div> 
        <div class="upload-image image-selector" title="red-stripe-red.jpg" id="image-selector-139"> 
         <img alt="Red-stripe-red" src="red-stripe-red.jpg" /> 
        <input autocomplete="off" id="comment[uploads_ids][139]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="139" /> 
         </div> 
        <div class="upload-image image-selector" title="red-stripe-bw.jpg" id="image-selector-138"> 
         <img alt="Red-stripe-bw" src="red-stripe-bw.jpg" /> 
        <input autocomplete="off" id="comment[uploads_ids][138]" name="comment[upload_ids][]" style="display:none;" type="checkbox" value="138" /> 
         </div> 
    </div> 

<textarea cols="40" id="comment_body" name="comment[body]" rows="10" style="width: 100%"></textarea> 
    <div class="actions"> 
       <input class="green awesome" id="comment_submit" name="commit" type="submit" value="Add Comment" /> 
     </div> 
      </div> 
     <br style="clear:both" /> 
     </form>            

Вот JS, встроенный в страницу:

$(document).ready(function(){

$('button.comment-edit').live('click', compv.comments.edit);
$('button.comment-form-cancel').live('click', compv.comments.editCancel);

$('div.actions input#comment_submit.green.awesome').live('click', compv.comments.updated);

$('#comment-ajax-form-update')
    .bind("ajax:success", function(evt, data, status, xhr){
    //console.log("Updated comment");

});

$('#comment-ajax-form-create')
    .bind("ajax:success", function(evt, data, status, xhr){
    compv.comments.updateView('comments', xhr);
    $('div.image-selector').each(function(){
        var element = $(this);
        element.children('input').attr('checked', false);
        element.removeClass('selected-image');
    });
});

Вот соответствующие фрагменты JS:

   compv.comments.updated = function(event){
    var parentElement = $(this).parents("li");
    parentElement.find('div.comment-show').fadeIn("slow");
    parentElement.find('div.comment-form').fadeOut("slow");
}; 

    compv.comments.edit = function(event){
console.log("Clicked Edit");
var parentElement = $(this).parents("li");
parentElement.find('div.comment-show').hide();
parentElement.find('div.comment-form').show();
};

compv.comments.editCancel = function(event){
    console.log("Clicked Cancel");
    var parentElement = $(this).parents("li");
    parentElement.find('div.comment-show').show();
    parentElement.find('div.comment-form').hide();
};

compv.comments.updated = function(xhr){
    var parentElement = $(this).parents("li");
    parentElement.find('div.comment-show').fadeIn("slow");
    parentElement.find('div.comment-form').fadeOut("slow");
};

compv.comments.updateView = function(divPrefix, xhr){
var dataDiv = 'div#'+divPrefix;
if(xhr.responseText.length > 1){ 
    $(dataDiv + ' ul').append(xhr.responseText);
    $(dataDiv + ' ul li:last').effect('highlight', {}, 3000);
}
};

var compv = {
    exists: true,
    tools: {
        exists: true,
        csrf_param: null,
        csrf_token: function() { },
        clientError: function() { }
    },
    comments: {
        exists: true,
        updateView: null,
        selectImage: null,
        upvote: null,
        edit: null,
        cancelEdit:null,
        downvote: null,
        showVotes: null,
        destroy: {
            success: null,
            error: null,
            dialog: 'comment-destroy-dialog'
        },
        getUploadID: function(element) {
            return $(element).parents("li").attr("data-upload-id");
        }
    },
    steps: {
        exists: true,
        selectFn: {},
        selectedClass: "selected-step",
        selectableClass: "selectable-step",
        selectedClient: {
            element: null,
            id: null,
            stepType: "client",
            ajaxSuccess: null
        },
        selectedProject: {
            element: null,
            id: null,
            stepType: "project",
            ajaxSuccess: null
        },
        selectedStage: {
            element: null,
            id: null,
            stepType: "stage",
            ajaxSuccess: null,
            getID: function() {
                return compv.steps.selectedStage.id;
            },
            displayCompare: function() {
                window.open($(this).attr('data-url'), "_blank");
            }
        },
        selectedUpload: {
            element: null,
            id: null,
            stepType: "image",
            primeUploadDisplay: null,
            ajaxSuccess: null,
            uploader: null,
            noCloseDialog: false
        }
    }
};

1 Ответ

2 голосов
/ 11 апреля 2011

Вам нужно заставить сервер возвращать какое-то значение, которое представляет, если редактирование комментария прошло успешно, в этом случае у вас есть три варианта:

  1. Заставить JavaScript обновлять всю страницу (опция ОК)
  2. Заставить сервер не только возвращать сообщение об успехе, но и возвращать новый список комментариев (наихудший вариант)
  3. С помощью JavaScript замените контейнер для комментариев данными, которые вы ввели в поле редактирования (лучший вариант))

Если вы выберете 3-й вариант, вам следует:

  1. Добавить возвращаемое значение с сервера, если редактирование комментария прошло успешно
  2. Добавить в оператор успеха ajax, проверьте, является ли возвращаемое значение успешным, если это так, запустите функцию
  3. Добавьте функцию для JavaScript, которая заменяет HTML-контейнер комментария на значение из правки (или что вы используете).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...