我正在尝试创建一个可重用的远程模态框。想法是创建一个模态框容器,并使用 yield
渲染内容,需要时再渲染内容。
注意:所有的 HTML
代码都将使用 HAML
编写。我正在使用 bootstrap-modal-rails gem 处理我的模态框。
我的模态框容器布局(不是部分):
%div(class="modal" id="mainModal ajax-modal" tabindex="-1" role="dialog"){:'aria-labelledby'=>"mainModalLabel", :'aria-hidden'=>"true"}
%div(class="c-modal__container")
%div(class="c-modal__layout modal__content")
= yield
在我的application.html.haml
文件中,我有一个定义模态框位置的div,如下所示:-# ...
%div(id="modal-holder")
- unless params[:nojs]
= javascript_include_tag 'desktop'
-# ...
这是我的问题所在。我有一个名为book controller
的控制器,用户可以在其中添加书籍。我有一个多步骤注册过程,我的new
操作必须是我的模式窗口。当用户单击New book
链接时,我正在加载一个新的模态框。
我的New book
链接:
= link_to "New book", new_book_path, class: "c-link--navbar", data: { modal: true }
使用jQuery重写的CoffeeScript代码,用于模态框(来自该文章):
$(function() {
var modal_holder_selector, modal_selector;
modal_holder_selector = '#modal-holder';
modal_selector = '.modal';
$(document).on('click', 'a[data-modal]', function() {
var location;
location = $(this).attr('href');
$.get(location, function(data) {
return $(modal_holder_selector).html(data).find(modal_selector).modal();
});
return false;
});
return $(document).on('ajax:success', 'form[data-modal]',
function(event, data, status, xhr) {
var url;
url = xhr.getResponseHeader('Location');
if (url) {
window.location = url;
} else {
$('.modal-backdrop').remove();
$(modal_holder_selector).html(data).find(modal_selector).modal();
}
return false;
});
});
现在,我的新操作
是为了yield
,它将加载到我的远程模态框中:
= form_for(@book, remote: remote, html: {role: :form}, class: "c-form") do |f|
-# Forms here...
= f.submit "Add a new book", class: "c-btn"
如果用户信息正确,我的模态框将重定向用户到“general action”,否则我希望停留在同一页上并闪现错误消息,但问题是我没有使用部分页面,并且它会自动重定向我到一个新页面,其中包含“new action”。
我的books_controller.rb
:
class BooksController < ApplicationController
respond_to :html, :json, :js
...
def index
@books = current_user.books
end
def new
@book = current_user.books.build
respond_modal_with @book
end
def create
@book = current_user.books.build(book_params)
if @book.save
redirect_to general_book_path(@book), notice: "Saved."
else
flash.now[:notice] = "Something went wrong."
render :new
end
end
...
end
模态响应器:
class ModalResponder < ActionController::Responder
cattr_accessor :modal_layout
self.modal_layout = 'modal'
def render(*args)
options = args.extract_options!
if request.xhr?
options.merge! layout: modal_layout
end
controller.render *args, options
end
def default_render(*args)
render(*args)
end
def redirect_to(options)
if request.xhr?
head :ok, location: controller.url_for(options)
else
controller.redirect_to(options)
end
end
end
我尝试添加类似以下内容:
respond_to do |format|
format.html
format.json { render json: @book }
end
我尝试在我的create
方法中添加代码,但它不起作用,并且仍然将我重定向到新页面。此外,我已经提出了一个类似的问题,我注意到我的JavaScript
代码可以在单独的页面上正常工作。只要我理解正确,问题应该出在远程模态操作页面上。请问有谁能帮助我找出如何在用户输入错误时保持在同一页上并开启我的javascript?