开发者

Help getting AJAX to update an edited comment in Rails 3 using jQuery

When I edit a comment that already exists and press 'save' - which in my jquery is clicking the input#comment_submit, it hides my edit form, and shows the list from the original state (i.e. before the update).

But if I refresh the page, it shows the updated comment - which shows me that the comment was actually updated via Rails. So not sure what's happening.

The final product I want is:

  • Click edit. Enter updates to the comment.
  • Click save. jQuery hides edit box, and shows the updated comment - without doing a full page refresh.

Here is the HTML for the comment:

<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>    开发者_如何学Go        

Here is the JS embedded on the page:

$(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');
    });
});

Here are the related JS snippets:

   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
        }
    }
};


You need to make a serverside return some value, that represents, if editing of comment was successfull, in that case, you have three options:

  1. Make JavaScript refresh whole page (OK option)
  2. Make serverside not only return success message, but also return new list of comments (worst option)
  3. With JavaScript, replace your comment container, with data, you entered in edit field (best option)

If you choose 3rd option, you should:

  1. Add return value from server, if comment editing was successfull
  2. Add inside ajax success statement, check, if return value is success value, if so, run a function
  3. Add a function for JavaScript, that replaces comment container HTML, with value from edit (or whatever you use).
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜