Multi step form / wizard responses for Ajax (modals) and HTML requests.
Therefor you only have to call this new method at the end of your controller action:
render_or_redirect_by_request_type
Then you can either set @path to redirect per Ajax for Ajax requests (@method is :get and @data is {} by default) or per redirect_to for other requests or set @template to render a template to a DOM element with selector @target for Ajax requests or render a template to the response body for other requests.
If you set @path for an Ajax request the targeted action should call "renderOrRedirectByRequestType" or respond with a JavaScript view to be evaluated.
Some conventions for Ajax requests if @path is present:
- The response should return a JavaScript to be evaluated: in this action you should not use renderorredirectorsettemplate but just use the default render behaviour and render actionname.js(.erb).
- @target is "#bootstrap_modal" by default.
- "@target _ is _ modal" is set to true by default and will wrap the template by a Twitter Bootstrap Modal layout with title set to @modaltitle which is I18n.t("#{controllername}.#{action_name}.title") by default. You can disable it.
- @template_format is "html" by default and you can also set it to "js" and the response will be evaluated.
Further conventions for Ajax requests:
- @path will be set to #action_name unless @path is present.
- Flash messages with key :notice or :alert will be alerted.
application_controller.rb
private
def render_or_redirect_by_request_type
if request.xhr? || request.env['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
render_javascript_response
elsif @template.present?
render @template
elsif @path.present?
redirect_to @path
end
end
def render_javascript_response
@method ||= :get
@data ||= {}
@template ||= action_name unless @path.present?
@template_format ||= 'html'
@target ||= "#bootstrap_modal"
@target_is_modal = @target_is_modal.nil? ? true : @target_is_modal
@modal_title ||= I18n.t("#{controller_name}.#{action_name}.title")
render partial: 'shared/javascript_response.js', layout: false
end
shared/ _ javascript _ response.js.erb
<% message = flash[:notice] || flash[:alert] %>
<% flash.delete(:notice); flash.delete(:alert) %>
<% alert = message.present? ? "alert('#{message}');" : '' %>
<% if @path.present? %>
$.ajax({ url: "<%= @path %>", data: <%= raw @data.to_json %>, type: "<%= @method.to_s.upcase %>", dataType: "script"}).done(function(data) {
eval(data);
<%= raw alert %>
})
.fail(function(data) {
<%= raw alert %>
alert("Failed to load <%= @path %>!");
});
<% elsif @template.present? %>
<% if @template_format == 'html' %>
<% if @target_is_modal %>
$(@target).html("<%= escape_javascript(
render(
partial: 'shared/layouts/twitter_bootstrap/modal',
locals: { title: @modal_title, body: render(template: "#{controller_name}/#{@template}.html") }
)
) %>");
<% else %>
$("<%= @target %>").html("<%= escape_javascript render(template: "#{controller_name}/#{@template}.html") %>");
<% end %>
<% elsif @template_format == 'js' %>
<%= render template: "#{controller_name}/#{@template}.js" %>
<% end %>
<%= raw alert %>
<% elsif message.present? %>
<%= raw alert %>
<% end %>
shared/layouts/ twitter_ bootstrap /_modal.html.erb
<% body ||= nil %>
<% footer ||= nil %>
<div class="modal-header">
<button type="button" id="close_bootstrap_modal_button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3><%= title %></h3>
</div>
<div class="modal-body" style="overflow-y:none;">
<%= body || yield(:modal_body) %>
</div>
<div class="modal-footer">
<%= footer || yield(:modal_footer) %>
</div>
Written by Mathias Gawlista
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Ruby
Authors
Filed Under
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#