Open a Bootstrap Modal to edit a record in Ruby on Rails

Viewed 8044

I have a "user" model. I have a list of users on the user index page with an edit button beside each. I want to click on the edit button for each user which will open a bootstrap modal.

On the bootstrap modal I want to display the user record which I can edit. The edit form will be from a _form.html.erb partial which will be used for the new and edit user controller methods.

When I click the update button, I want the modal form to update the record, close the modal and update the index page with the updated record.

Issues

  1. Every time I click on the edit link the modal opens and displays the _forms partial but it is for a new record, not the record I want to edit. I think this is because rails runs the @user.persisted? helper which responds with false so it uses the "create" method in the user controller instead of the "edit" method.

  2. The bootstrap modal does not close when I save the record.

Can you tell me how to get this to work?

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
2 Answers
Related