Respostas de formulário / assistente de várias etapas para solicitações Ajax (modais) e HTML.

Portanto, você só precisa chamar este novo método no final da ação do controlador:

render_or_redirect_by_request_type

Em seguida, você pode definir @path para redirecionar por Ajax para solicitações Ajax (@method é: get e @data é {} por padrão) ou por redirect_to para outras solicitações ou definir @template para renderizar um modelo para um elemento DOM com o seletor @ destino para solicitações Ajax ou renderize um modelo para o corpo de resposta para outras solicitações.

Se você definir @path para uma solicitação Ajax, a ação direcionada deve chamar “renderOrRedirectByRequestType” ou responder com uma visualização JavaScript para ser avaliada.

Algumas convenções para solicitações Ajax se @path estiver presente:

  • A resposta deve retornar um JavaScript a ser avaliado: nesta ação você não deve usar renderizar ou redirecionar ou definir modelo, mas apenas usar o comportamento de renderização padrão e renderizar a ação name.js (.erb).
  • @target é “#bootstrap_modal” por padrão.
  • “@target _ is _ modal” é definido como verdadeiro por padrão e envolverá o modelo por um layout modal do Twitter Bootstrap com o título definido como @modal title que é I18n.t (“# { nome do controlador }. # {action_name}. título “) por padrão. Você pode desativá-lo.
  • @template_format é “html” por padrão e você também pode defini-lo como “js” e a resposta será avaliada.

Outras convenções para solicitações Ajax:

  • @path será definido como #action_name, a menos que @path esteja presente.
  • Mensagens flash com tecla: aviso ou: alerta serão alertadas.

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">&times;</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>