After watching RailsCast #296 about Mercury Editor, I am trying to get the editor to redirect to a newly created resource.
I can already redirect on the client-side using JS and window.location.href=
. But for a new resource, I cannot "guess" its URL on the client-side. I need it to be in the server response.
However, the problem is that I don't see the possibility of using the server response in the editor. No matter what the controller renders, the server response is discarded by Mercury instead of used as an argument to my function for mercury:saved
.
Is there a way to get around this?
I was able to do this on update by sending a valid JSON string back. I would assume create works the same way. check firebug to make sure you're not getting an error in the jQuery.ajax call that Mercury uses.
posts_controller.rb
def mercury_update
post = Post.find(params[:id])
post.title = params[:content][:post_title][:value]
post.body = params[:content][:post_body][:value]
post.save!
render text: '{"url":"'+ post_path(post.slug) +'"}'
end
mercury.js:
jQuery(window).on('mercury:ready', function() {
Mercury.on('saved', function() {
window.location.href = arguments[1].url
});
});
note: I'm using friendly_id to slug my posts
Redirecting on the server side doesn't work because the save button is just an jQuery.ajax
call:
// page_editor.js
PageEditor.prototype.save = function(callback) {
var data, method, options, url, _ref, _ref1,
_this = this;
url = (_ref = (_ref1 = this.saveUrl) != null ? _ref1 : Mercury.saveUrl) != null ? _ref : this.iframeSrc();
data = this.serialize();
data = {
content: data
};
if (this.options.saveMethod === 'POST') {
method = 'POST';
} else {
method = 'PUT';
data['_method'] = method;
}
Mercury.log('saving', data);
options = {
headers: Mercury.ajaxHeaders(),
type: method,
dataType: this.options.saveDataType,
data: data,
success: function(response) {
Mercury.changes = false;
Mercury.trigger('saved', response);
if (typeof callback === 'function') {
return callback();
}
},
error: function(response) {
Mercury.trigger('save_failed', response);
return Mercury.notify('Mercury was unable to save to the url: %s', url);
}
};
if (this.options.saveStyle !== 'form') {
options['data'] = jQuery.toJSON(data);
options['contentType'] = 'application/json';
}
return jQuery.ajax(url, options);
};
So your redirect is sent to the success
callback, but the page doesn't actually re-render, as with any successful AJAX request. The author discusses overriding this very function here. It also looks like there might be some room to maneuver here by passing a callback function to save
.
Btw, another way to do what @corneliusk suggests is:
render { json: {url: post_path(post.slug)} }
Either way, the response body is passed as an argument to the function in the mercury:saved
callback.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With