【问题标题】:Open a Bootstrap Modal to edit a record in Ruby on Rails打开引导模式以在 Ruby on Rails 中编辑记录
【发布时间】:2013-12-31 04:59:13
【问题描述】:

我有一个“用户”模型。我在用户索引页面上有一个用户列表,每个用户旁边都有一个编辑按钮。我想为每个用户单击编辑按钮,这将打开一个引导模式。

在引导模式上,我想显示可以编辑的用户记录。编辑表单将来自 _form.html.erb 部分,它将用于新的和编辑用户控制器方法。

当我点击更新按钮时,我希望模态表单更新记录,关闭模态并使用更新的记录更新索引页面。

问题

  1. 每次我单击编辑链接时,模式都会打开并显示部分 _forms,但它是针对新记录的,而不是我要编辑的记录。我认为这是因为 rails 运行 @user.persisted? helper 以 false 响应,因此它使用用户控制器中的“create”方法而不是“edit”方法。

  2. 保存记录时引导模式没有关闭。

你能告诉我如何让它工作吗?

user/_form.html.erb

<%= form_for(@user, remote: true) do |f| %>
    <% if @user.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>

          <ul>
            <% @user.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
          </ul>
        </div>
    <% end %>

    <div class="field">
      <%= f.label :name %>
      <br>
      <%= f.text_field :name %>
    </div>
    <div class="field">
      <%= f.label :company %>
      <br>
      <%= f.text_field :company %>
    </div>
    <div class="field">
      <%= f.label :email %>
      <br>
      <%= f.text_field :email %>
    </div>

    <div class="actions">
      <%= f.submit %>
    </div>
<% end %>

users/create.js.erb

$(".usersTable").replaceWith("<%=j render :partial=> 'users/update_user', :locals => {users: @users }%>");
$("input[type=text]").val("");

$('#myModal').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();

users/index.html.erb

<h1>Listing users</h1>

<table class="usersAll">
  <thead>
    <tr>
      <th>Name</th>
      <th>Company</th>
      <th>Email</th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>

  <tbody class="usersTable">
    <% @users.each do |user| %>
      <tr>
        <td><%= user.name %></td>
        <td><%= user.company %></td>
        <td><%= user.email %></td>
        <td><%= link_to 'Show', user %></td>
        <td><%= link_to 'Edit',  '#', 'data-target' => '#myModal', 'data-toggle' => 'modal'  %></td>
        <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<!-- Button trigger modal -->
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
  Add User
</button>

<!-- 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">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        <%= render 'users/form' %>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  # GET /users
  # GET /users.json
  def index
    @users = User.all
    @user = User.new
  end

  # GET /users/1
  # GET /users/1.json
  def show
  end

  # GET /users/new
  def new
    @user = User.new
  end

  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end


  # PATCH/PUT /users/1
  # PATCH/PUT /users/1.json
  def update
    respond_to do |format|
      if @user.update(user_params)

        format.js {}
      else
        format.html { render action: 'edit' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

【问题讨论】:

    标签: jquery ruby-on-rails twitter-bootstrap


    【解决方案1】:

    当前表格不用于编辑记录,改为:

    users/index.html.erb

    <h1>Listing users</h1>
    
    <table class="usersAll">
      <thead>
      <tr>
        <th>Name</th>
        <th>Company</th>
        <th>Email</th>
        <th></th>
        <th></th>
        <th></th>
      </tr>
      </thead>
    
      <tbody class="usersTable">
      <% @users.each do |user| %>
          <tr>
            <td><%= user.name %></td>
            <td><%= user.company %></td>
            <td><%= user.email %></td>
            <td><%= link_to 'Show', user %></td>
            <td>
              <%= link_to 'Edit',  '#', 'data-target' => "#myModal_#{user.id}", 'data-toggle' => 'modal'  %>
              <div class="modal fade" id='<%= "myModal_#{user.id}" %>' 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">&times;</button>
                      <h4 class="modal-title" id="myModalLabel">Modal title</h4>
                    </div>
                    <div class="modal-body">
                      <%= render 'users/form', user: user %>
                    </div>
                    <div class="modal-footer">
                      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                      <button type="button" class="btn btn-primary">Save changes</button>
                    </div>
                  </div><!-- /.modal-content -->
                </div><!-- /.modal-dialog -->
              </div><!-- /.modal -->
            </td>
            <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
          </tr>
      <% end %>
      </tbody>
    </table>
    
    <!-- Button trigger modal -->
    <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
      Add User
    </button>
    

    user/_form.html.erb

    <%= form_for(user, remote: true) do |f| %>
        <% if @user.errors.any? %>
            <div id="error_explanation">
              <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
    
              <ul>
                <% @user.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
              </ul>
            </div>
        <% end %>
    
        <div class="field">
          <%= f.label :name %>
          <br>
          <%= f.text_field :name %>
        </div>
        <div class="field">
          <%= f.label :company %>
          <br>
          <%= f.text_field :company %>
        </div>
        <div class="field">
          <%= f.label :email %>
          <br>
          <%= f.text_field :email %>
        </div>
    
        <div class="actions">
          <%= f.submit %>
        </div>
    <% end %>
    

    如果你想点击提交刷新整个页面,只需从 _form.html.erb 中删除 remote: true

    【讨论】:

    • 嗨 Aquajach,我尝试了代码。它适用于下面 UKatz 推荐的更改以添加 data-sismiss="modal" 但它不会保存我所做的更改。 “添加用户”按钮现在也不起作用。
    【解决方案2】:

    @aquajach 为您提供了解决第一个问题的正确代码。请注意,您的问题出现是因为您没有将“用户”参数发送到表单部分,而是使用@user 构建表单,这是您在索引操作中使用new 初始化的变量(所以它是空的)。正如@aquajach 所做的那样发送正确的参数,您需要将模态代码放在“.each”循环中,否则无法告诉您希望每个模态显示哪个用户的信息。

    另请注意,Edit link_to 使用“#”作为其 url。这意味着它将无处链接,并且绝对不会回到服务器上的控制器(既不编辑也不创建)。

    关于你的第二个问题。请注意,关闭按钮有data-dismiss="modal",但保存更改按钮没有。附加该代码,以使其也隐藏模式。

    【讨论】:

    • 感谢您的澄清。似乎有很多重复的代码,每个项目都重复了模态。有没有办法重构这段代码,避免重复?
    • JavaScript 可以做到这一点,但在这种情况下是不必要的。你正在做的事情和从一开始就在屏幕上显示所有信息之间的唯一区别是你的 UI 看起来更好。如果我从一开始就不知道有多少模态,我会使用 JavaScript,我必须从服务器检索新信息以显示在模态中,或者对信息进行一些其他的渲染后操作。立即呈现所有这些 html 几乎没有缺点。如果因为用户太多而导致加载时间很慢,请使用分页或类似的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    相关资源
    最近更新 更多