Rails 3.2中的show操作模态弹出窗口

7

这个论坛上的问题似乎都没有涉及到我的具体需求。基本上,我有一个“详细信息”按钮。 我希望当它被点击时,会出现一个模态对话框,其中包含从模型的show.html.erb中提取的信息。 我有一个book.rb模型。 在索引页面中,我有:

<div class="detail_button"><%= link_to "Details", book %></div>

点击该按钮通常会将我带到书籍/ID页面,使用显示操作。但我不想离开页面,而是想要一个可以关闭的模态弹出窗口。我尝试了此论坛中相关主题的所有jQuery和JavaScript代码,但似乎都无法解决问题。大多数似乎只针对创建或自定义操作。
为避免重复,我尝试了以下内容,但均未奏效:
You could look at modal dialogs by www.jqueryui.com. Add jquery ui to your application.

Put a hidden div (display:none) in your layout page.

<div class="modal" style="display:none;">
</div>

Your link should be an ajax link:

<%= link_to 'Link', events_path(@event), :remote => true %>

Your controller should accept ajax response:

def show
  @event = Event.find(params[:id])
  respond_to do |format|
    format.js
  end
end

This is where the magic happens. After pressing the link via ajax, your show.js file will insert content into your empty hidden div and display the popup. Your views should have a javascript file: /view/events/show.js.erb

$('.modal').html(<%= escape_javascript(render(@event)) %>); //inserts content into your empty div.
$('.modal').dialog(); //jquery ui will open it as a modal popup

This:

$('a[data-popup]').live('click', function(e) { 
    window.open($(this).attr('href')); 
    e.preventDefault(); 
}); 

还有这个:

$('a[data-popup]').live('click', function(e) { window.open($(this).attr('href')); e.preventDefault(); });

= link_to( 'Create a new company', new_company_path, 'data-popup' => true )

有人可以帮忙吗?我对此一窍不通。


第一个代码示例看起来应该可以工作。当您点击第一个示例的链接时会发生什么?一定要使用Google Chrome,Firebug等调试JavaScript。 - Brandon Jernigan
2个回答

36

我不确定 @events 与你的 Book 模型有什么关系,但是假设我们只使用一个模型(Book),那么这是你的代码可以设置的一种方式:


app/views/books/index.html.erb

在循环遍历 @books 的过程中,包含链接到“查看详细信息”的链接,并将 remote: true 设置为启用 AJAX。

<table>
<% @books.each do |book| %>
<tr>
  <td><%= book.title %></td>
  <td><%= book.author %></td>
  <td><%= number_to_currency(book.price) %></td>
  <td><%= link_to 'View Details', book, remote: true %></td>
</tr>
<% end %>
</table>
在此页面上,您还应呈现您的模式/对话框,但它应该具有一个使其隐藏的类(稍后您将使用JS/jQuery切换此类)。我使用了一个部分来使代码更加模块化,但您也可以直接放置模态divs。
<%= render "layouts/modal" %>


app/views/layouts/_modal.html.erb

这是一个模态框的结构部分。我使用了Twitter Bootstrap的版本,它有预定义的样式和一些漂亮的动画触发器。

<div class="modal hide fade">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h3 class="modal-heading">Modal header</h3>
  </div>
  <div class="modal-body">
    <p>One fine body…</p>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn" data-dismiss="modal">Close</a>
    <a href="#" class="btn btn-primary">Add to Cart</a>
  </div>
</div>

如果您的控制器使用标准模板设置,您只需在show动作的respond_to代码块中添加format.js即可。这将在触发该操作时自动呈现一个名为show.js.erb(您必须手动创建)的文件。

def show
    @book = Book.find(params[:id])

    respond_to do |format|
        format.html # show.html.erb
        format.js # show.js.erb
        format.json { render json: @book }
    end
end


app/views/books/show.js.erb

正如您所说,这就是魔法发生的地方,AJAX响应被发送到您的页面。使用jQuery,我设置了一些变量,并将模态模板中的HTML替换为@book渲染的HTML(@book来自您必须创建的名为_book.html.erb的部分文件)。

$modal = $('.modal'),
$modalBody = $('.modal .modal-body'),
$modalHeading = $('.modal .modal-heading');
$modalHeading.html("<%= @book.title %>");
$modalBody.html("<%= escape_javascript(render @book) %>");
$modal.modal();


app/views/_book.html.erb

这是您为成功的AJAX响应中的模态框创建内容模板的位置。

<p><b>Title:</b> <%= @book.title %></p>

<p><b>Author:</b> <%= @book.author %></p>

<p><b>Price:</b> <%= number_to_currency(@book.price) %></p>

<p><b>Description:</b> <%= @book.description %></p>

<p><b>Publisher:</b> <%= @book.publisher %></p>

<p><b><%= @book.style %></b> <%= @book.number_of_pages %> pages</p>

<p><b>ISBN:</b><%= @book.ISBN %></p>

<%= link_to 'Edit', edit_book_path(@book) %> |
<%= link_to 'Show', @book %> |
<%= link_to 'Remove', @book, method: :delete, data: { confirm: 'Are you sure?' } %>

我使用Github上的书店示例应用程序创建了此代码。希望这可以帮到您。


非常棒的教程!谢谢。只有一个小修正,_book.html.erb 部分应该在 views/books 中。 - Amal Chaudhuri
1
非常棒的教程。非常感谢! - kchoi
精彩的例子。谢谢。 - Misha
你好,我刚刚尝试了你的代码。我得到了“缺少模板books/show”的错误。实际上,show模板现在是一个局部模板。似乎应用程序忽略了我控制器中的js渲染。 - Orsay
当我从下载的git项目执行"bundle install"时,出现错误提示:"安装json(1.8.0)时发生错误,Bundler无法继续。" - Dave

0

".live"在jQuery中已经被弃用。你尝试替换了吗?

$('a[data-popup]').live('click', function(e) ...

$('a[data-popup]').on('click', function(e) ...

祝福


很抱歉,我有点困惑。你复制粘贴的两段代码是相同的。 - Shikasan
对不起,复制/粘贴出了问题...我编辑了我的答案(将.live替换为.on - phron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接