Inline Editing Records

Episode #191 by Teacher's Avatar David Kimura

Summary

Using Rails UJS, we create an interactive row editing solution without using any kind of Javascript frameworks.
view rails javascript ujs 13:08

Resources

Summary

# Terminal
rails g scaffold user first_name last_name email
rails db:migrate

# users/index.html.erb
<div class="divTable paleBlueRows">
  <div class="divTableHeading">
    <div class="divTableRow">
      <div class="divTableHead">First Name</div>
      <div class="divTableHead">Last Name</div>
      <div class="divTableHead">Email</div>
      <div class="divTableHead">Actions</div>
    </div>
  </div>
  <div class="divTableBody">
    <% @users.each do |user| %>
      <%= content_tag :div, class: 'divTableRow', id: dom_id(user) do %>
        <%= render user %>
      <% end %>
    <% end %>
  </div>
</div>

# edit.js.erb
document.getElementById('<%= dom_id(@user) %>').insertAdjacentHTML('afterend', "<%= j render 'inline_form', user: @user %>")
document.getElementById('<%= dom_id(@user) %>').style.display = 'none'

# _inline_form.html.erb
<%= form_with model: user, class: 'divTableRow', id: dom_id(user, 'inline_form') do |form| %>
  <div class="divTableCell">
    <%= form.text_field :first_name %>
  </div>

  <div class="divTableCell">
    <%= form.text_field :last_name %>
  </div>

  <div class="divTableCell">
    <%= form.text_field :email %>
  </div>

  <div class="divTableCell">
    <%= form.submit %>
  </div>
<% end %>

# users_controller.rb
def update
  respond_to do |format|
    if @user.update(user_params)
      format.js {}
      format.html { redirect_to @user, notice: 'User was successfully updated.' }
    else
      format.js {}
      format.html { render :edit }
    end
  end
end

# update.js.erb
document.getElementById('<%= dom_id(@user, 'inline_form') %>').remove()
document.getElementById('<%= dom_id(@user) %>').innerHTML = "<%= j render @user %>"
document.getElementById('<%= dom_id(@user) %>').style.display = 'table-row'

# views/users/_user.html.erb
<div class="divTableCell"><%= user.first_name %></div>
<div class="divTableCell"><%= user.last_name %></div>
<div class="divTableCell"><%= user.email %></div>
<div class="divTableCell">
  <%= link_to 'Show', user %>
  <%= link_to 'Edit', edit_user_path(user), remote: true %>
  <%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %>
</div>