rails4使用bootstrap的模态框插件,组合ajax做出从弹出框选取内容返回给原页面的效果

rails4使用bootstrap的模态框插件,结合ajax做出从弹出框选取内容返回给原页面的效果

1、首先新建一个rails项目,取名为example_modal吧

rails new example_modal
为了使用bootstrap,需要下载bootstrap编译后的CSS、JS和字体文件,中文网地址http://v3.bootcss.com/getting-started/,解压后把bootstrap.min.js放到example_modal\vendor\assets\javascripts下,把bootstrap.min.css放到example_modal\vendor\assets\stylesheets下,把整个fonts文件夹放到example_modal\vendor\assets下。

然后修改application.js和application.css文件

example_modal\app\assets\javascripts\application.js

......

// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap.min
//= require turbolinks
//= require_tree .
example_modal\app\assets\stylesheets\application.css

...... 

 * file per style scope.
 *
 *= require bootstrap.min
 *= require_self
 *= require_tree .
 */

@font-face {
    font-family: 'Glyphicons Halflings';
    src: url('../assets/glyphicons-halflings-regular.eot');
    src: url('../assets/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
    url('../assets/glyphicons-halflings-regular.woff') format('woff'),
    url('../assets/glyphicons-halflings-regular.ttf') format('truetype'),
    url('../assets/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}

2、创建控制器users,带有index页面

rails g controller users index
现在可以看到example_modal\app\views\users\index.html.erb和example_modal\app\controllers\users_controller.rb两个文件了。

3、设置项目启动默认页面为这个index页面

打开example_modal\config\routes.rb,可以看到

Rails.application.routes.draw do
  get 'users/index'
  ...
end
添加一行

root 'users#index'
最终看到的example_modal\config\routes.rb如下

Rails.application.routes.draw do
  root 'users#index'
  get 'users/index'
  
  ...

end
这时候可以输入启动服务器命令

rails s
启动成功后,在浏览器中输入http://localhost:3000/,应该能看到以下页面

rails4使用bootstrap的模态框插件,组合ajax做出从弹出框选取内容返回给原页面的效果

好了,在修改这个页面之前,确定一下目标:做出从弹出框选取内容返回给原页面的效果,那就需要有数据,我决定创建一个名为users的表,并创建一个初始化数据库数据的task任务。

4、新开一个命令窗口,建users表

rails g model user name:string age:integer
生成example_modal\app\models\user.rb文件,继续执行迁移命令

rake db:migrate
迁移完成后,users表就建成了。

5、建task任务,初始化数据库

在example_modal\lib\tasks下新建一个文件,取名 sample_data.rake

namespace :db do
  desc "Fill database with sample data"
  task populate: :environment do
    10.times do |index|
      User.create!(name:"user#{index}",age:"#{index+1}")
    end
  end
end
执行此任务

rake db:populate
此时数据库users表应该有10条数据。

6、数据有了,下面修改index页面,做出基本样式,实现如下效果

rails4使用bootstrap的模态框插件,组合ajax做出从弹出框选取内容返回给原页面的效果


点击【选择】后效果

rails4使用bootstrap的模态框插件,组合ajax做出从弹出框选取内容返回给原页面的效果


example_modal\app\controllers

class UsersController < ApplicationController
  def index
    @users = User.all
  end
end


example_modal\app\views\users\index.html.erb

<div class="container">
<h1>rails4使用bootstrap的模态框插件,结合ajax做出从弹出框选取内容返回给原页面的效果</h1>
<br/>
<br/>
<br/>
<br/>
<br/>
<div class="row">
  <div class="col-md-1 text-right">姓名</div>
  <div class="col-md-2">
    <%= text_field_tag :name %>
  </div>
</div>
<div class="row">
  <div class="col-md-1 col-md-offset-3">
    <%= link_to "选择", "#", class: "btn btn-sm btn-primary","data-toggle" => "modal", "data-target" => "#myModal" %>
  </div>
</div>
<div class="row">
  <div class="col-md-1 text-right">年龄</div>
  <div class="col-md-2">
    <%= text_field_tag :age %>
  </div>
</div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        <table class="table table-bordered">
          <thead>
          <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>年龄</th>
          </tr>
          </thead>
          <tbody>
            <% @users.each do |user| %>
            <tr class="select" data-user_id="<%= user.id %>" >
              <td><%= user.id %></td>
              <td><%= user.name %></td>
              <td><%= user.age %></td>
            </tr>
            <% end %>
          </tbody>
        </table>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">选择</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

7、弹出的选择框中,点击table的行是没效果的,下面实现,点击任意一行,改变该行背景颜色,其他行背景颜色变为默认颜色。

注意这几行代码

<tr class="select" data-user_id="<%= user.id %>" >
              <td><%= user.id %></td>
              <td><%= user.name %></td>
              <td><%= user.age %></td>
            </tr>
现在就是要做到点击这里,这个js代码写在

example_modal\app\assets\javascripts\users.js.coffee

$ ->

  $("tr.select").click ->
    $("tr.select").css("backgroundColor","white");
    this.style.backgroundColor = "#357ebd"
这里需要特别要注意的是,js.coffee 每行代码的缩进,不能不缩进。

效果图如下

rails4使用bootstrap的模态框插件,组合ajax做出从弹出框选取内容返回给原页面的效果


8、下一步实现,点击弹出框的【选择】,将当前选中的user的id传给控制器,在控制器中处理,通过传来的id找到user的名字和年龄,然后调用js.erb文件,将值写入index页面。传送id思路是弹出框中添加一个隐藏文本框,位于一个表单中,当点击页面上不同的user行时,会触发js,将user的id值写入隐藏文本框中。点击【选择】时,会提交表单,将隐藏文本框中的值提交。

(1) 将example_modal\app\views\users\index.html.erb中的

<div class="modal-footer">
  <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
  <button type="button" class="btn btn-primary">选择</button>
</div>  

替换为

      <%= form_tag users_choose_path , remote: true do %>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <%= hidden_field_tag :user_id,params[:user_id] %>
        <%= submit_tag "选择", class: "btn btn-primary" %>
      </div>
      <% end %>

(2)  增添choose的路由,root.rb文件中添一行

post 'users/choose'

(3) 控制器中添加action

  def choose
    user = User.find(params[:user_id])
    @name = user.name
    @age = user.age
    render 'choose_user.js.erb'
  end

(4) 添加点击user行,给隐藏文本框写入id的js代码

$("#user_id").val($(this).data("user_id"));


(5) 添加choose_user.js.erb文件

example_modal\app\views\users\choose_user.js.erb

$("#name").val("<%= @name %>") //写入名称
$("#age").val("<%= @age %>")   //写入年龄
$('#myModal').modal('hide'); //关闭弹出框


完成了,当我选择user6后,index页面出现画面

rails4使用bootstrap的模态框插件,组合ajax做出从弹出框选取内容返回给原页面的效果



附附附附附附附附附文件

下面我整理一下各个文件

1、 \example_modal\app\controllers\users_controller.rb

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def choose
    user = User.find(params[:user_id])
    @name = user.name
    @age = user.age
    render 'choose_user.js.erb'
  end
end
2、 \example_modal\app\views\users\index.html.erb
<div class="container">
<h1>rails4使用bootstrap的模态框插件,结合ajax做出从弹出框选取内容返回给原页面的效果</h1>
<br/>
<br/>
<br/>
<br/>
<br/>
<div class="row">
  <div class="col-md-1 text-right">姓名</div>
  <div class="col-md-2">
    <%= text_field_tag :name %>
  </div>
</div>
<div class="row">
  <div class="col-md-1 col-md-offset-3">
    <%= link_to "选择", "#", class: "btn btn-sm btn-primary","data-toggle" => "modal", "data-target" => "#myModal" %>
  </div>
</div>
<div class="row">
  <div class="col-md-1 text-right">年龄</div>
  <div class="col-md-2">
    <%= text_field_tag :age %>
  </div>
</div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        <table class="table table-bordered">
          <thead>
          <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>年龄</th>
          </tr>
          </thead>
          <tbody>
            <% @users.each do |user| %>
            <tr class="select" data-user_id="<%= user.id %>" >
              <td><%= user.id %></td>
              <td><%= user.name %></td>
              <td><%= user.age %></td>
            </tr>
            <% end %>
          </tbody>
        </table>
      </div>
      <%= form_tag users_choose_path , remote: true do %>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <%= hidden_field_tag :user_id,params[:user_id] %>
        <%= submit_tag "选择", class: "btn btn-primary" %>
      </div>
      <% end %>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

3、 \example_modal\app\views\users\choose_user.js.erb

$("#name").val("<%= @name %>")
$("#age").val("<%= @age %>")
$('#myModal').modal('hide');

4、 \example_modal\config\routes.rb

Rails.application.routes.draw do
  root 'users#index'
  get 'users/index'
  post 'users/choose'
end


5、 \example_modal\app\assets\javascripts\users.js.coffee

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
$ ->

  $("tr.select").click ->
    $("tr.select").css("backgroundColor","white");
    this.style.backgroundColor = "#357ebd"
    $("#user_id").val($(this).data("user_id"));
注意行首的缩进

6、 \example_modal\lib\tasks\sample_data.rake

namespace :db do
  desc "Fill database with sample data"
  task populate: :environment do
    10.times do |index|
      User.create!(name:"user#{index}",age:"#{index+1}")
    end
  end
end