Skip to content

Instantly share code, notes, and snippets.

@conorh
Created April 22, 2015 15:59
Show Gist options
  • Save conorh/82f65bc838aed451b78f to your computer and use it in GitHub Desktop.
Save conorh/82f65bc838aed451b78f to your computer and use it in GitHub Desktop.
WYSIWYG content previews for Ruby on Rails
<% form_for(@blog_post) do |f| %>
<%= link_to 'Preview', '#', data: {preview: true, model: @blog_post.class.to_s} %>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
<!DOCTYPE html>
<html>
<head>
<%= render partial: "layouts/partials/head" %>
</head>
<body>
<%= yield %>
<%= form_tag("/preview", style: "display: none;" id: "serialized-preview-form") do %>
<input name="model" />
<textarea name="body"></textarea>
<% end %>
<script>
// Accepts the data and submits the serialized data
function setData(model, data) {
var form = $('#serialized-preview-form');
form.find("[name=body]").val(data);
form.find("[name=model]").val(model);
form.submit();
}
window.opener.ContentPreview.previewAreaReady();
</script>
</body>
</html>
var ContentPreview = {
firstLoad: true,
previewWindow: null,
previewTimer: null,
previewDebounce: null,
form: null,
model: null,
init: function() {
var self = this;
$('[data-preview]').on("click", function(e) {
e.preventDefault();
var link = $(this);
form = link.parents("form");
form.on("keyup", function() {
clearTimeout(self.previewDebounce);
self.previewDebounce = setTimeout(function() {
self.previewBody();
}, 1000);
});
self.model = link.data('model');
self.firstLoad = true;
self.previewWindow = window.open("/preview", "Preview", "_blank", "height=600,width=690");
});
},
// When the preview window is ready it will call this function
previewAreaReady: function() {
var self = this;
if(!self.firstLoad) { return; }
self.firstLoad = false;
self.previewBody();
},
previewBody: function() {
var self = this;
if(!self.previewArea) { return }
clearTimeout(self.previewTimer);
self.previewTimer = setTimeout(function() {
var data = $(form).serialize();
self.previewWindow.setData("/preview", self.model, data);
}, 150);
}
}
class PreviewController < ApplicationController
def show
model_class = params[:model].constantize
lower = model_class.to_s.underscore
if params[:body]
values = HashWithIndifferentAccess.new(Rack::Utils.parse_nested_query(params[:body]))
values = ActionController::Parameters.new(values)
if values[:id]
model = model_class.find(values[:id])
model.attributes = values.require(lower).permit!
else
model = model_class.new(values.require(lower).permit!)
end
else
model = model_class.new
end
instance_variable_set("@" + lower, model)
@preview = true
@template = "/preview/templates/#{lower}.html.erb"
response.headers['X-XSS-Protection'] = "0"
render layout: "preview"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment