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="✓" /><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="✓" /></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:
- Make JavaScript refresh whole page (OK option)
- Make serverside not only return success message, but also return new list of comments (worst option)
- With JavaScript, replace your comment container, with data, you entered in edit field (best option)
If you choose 3rd option, you should:
- Add return value from server, if comment editing was successfull
- Add inside ajax success statement, check, if return value is success value, if so, run a function
- Add a function for JavaScript, that replaces comment container HTML, with value from edit (or whatever you use).
精彩评论