Reputation: 1351
I am building out an app in Rails 5 and using Bootstrap 3 for the framework.
I have created a custom user controller ect to allow admins to create / edit and destroy users. I am setting up modals for the create user form, the modal its self works, however I want it to automatically place and render the table row.
So far when I create a user the modal hangs, it creates the user but dose not close the modal window and if I reopen the modal from the button it still holds the previous users email and details.
I will say that I have placed format.js in the Create, Update and Destroy Controller Actions under format.
My Modal and Its Button
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#userCreate">
Add New User
</button>
<!-- Modal -->
<%= form_for(@user, remote: true) do |f| %>
<div class="modal fade bs-example-modal-lg" id="userCreate" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel"><i class="fa fa-user-plus" aria-hidden="true"></i> User Creation</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-xs-12">
<div class="field">
<%= f.label :email, "Email Address - Password Will Be Sent To This Address" %><br />
<%= f.email_field :email, autofocus: true, :class => 'form-control email' %>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6">
<div class="field">
<%= f.label :f_name, "First Name" %>
<%= f.text_field :f_name, :class => 'form-control f_name' %>
</div>
</div>
<div class="">
</div>
<div class="col-xs-12 col-sm-6">
<div class="field">
<%= f.label :l_name, "Last Name" %>
<%= f.text_field :l_name, :class => 'form-control l_name' %>
</div>
</div>
</div>
<div class="row">
<div class="">
</div>
<div class="col-xs-12">
<div class="field">
<%= f.label :primary_tel, "Primary Telephone" %>
<%= f.text_field :primary_tel, :class => 'form-control primary_tel' %>
</div>
</div>
<div class="">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<%= f.submit "Create User", :class => 'btn btn-primary' %>
</div>
</div>
</div>
</div>
<% end %>
Index Page where the _user_row.html.erb Partial is to be rendered
<table>
<thead>
<tr>
<th>User ident</th>
<th>F name</th>
<th>L name</th>
<th>Primary tel</th>
<th>Role</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<div class="row" id="user_table_row">
<%= render partial: 'user_row', locals: {user: user} %>
</div>
<% end %>
</tbody>
</table>
Now this partial is displaying, but only after I manually reload the page
And finally the create.js.erb file (located in views/users)
$('#userCreate').modal('hide'); <-- close the Modal On Submit
$(".email").val(''); <-- Reset Email Field
$(".f_name").val(''); <-- Reset F_name Field
$(".l_name").val(''); <-- Reset L_name Field
$(".primary_tel").val(''); <-- Reset Telephone Field
$('#user_table_row').prepend('<%= j render @user %>'); <-- Render User
$('#user_row_<%= user.user_ident %>').hide().fadeIn(1000); <-- Display Row
I am newish to jquery but im stumped here.. Any help would be greatly appreciated! Please let me know if you need to see anything else. Thanks.
also the <-- is not present in my app code i placed these there so you know what i am trying to do.
Upvotes: 1
Views: 1147
Reputation: 11915
I assume that your user_row
partial looks something like this.
<tr id="<%= "user_row_#{user.id}" %>">
<td><%=user.email%></td>
<td><%=user.f_name %></td>
<td><%=user.l_name %></td>
<td><%=user.primary_tel %></td>
</tr>
There are a couple of issues with your code in create.js.erb
. You should actually render the partial user_row
not just @user
.
If you look at the server logs, you can find that it looks for a partial users/_user
if you have render @user.
So, replace that with
$('#user_table_row').prepend('<%= j render partial: 'user_row', locals: {user: @user} %>');
And in the following line of code,
$('#user_row_<%= user.user_ident %>').hide().fadeIn(1000);
user
is nil
. From the create action, you have access to an instance variable @user
, not user
. And I am not sure what user_ident
is. Replace that with
$('#user_row_<%= @user.id %>').hide().fadeIn(1000);
Now, your AJAX form submission should work. But the new row will be rendered outside the table. To understand it better have a look at this.
So, where is the problem? In your view, you have the following block of code.
<% @users.each do |user| %>
<div class="row" id="user_table_row">
<%= render partial: 'user_row', locals: {user: user} %>
</div>
<% end %>
For every user, you're wrapping the row(from partial) inside a div with class row
and id user_table_row
. Don't you see something wrong?
IDs should be unique throughout the page but you're creating multiple div
s with the same id
. Whenever a new user record is created, you've to prepend it to the table body. So, it would make sense to add the id
to tbody
rather than a wrapper div
. So, modify your view as
<tbody id="table_body">
<% @users.each do |user| %>
<%= render partial: 'user_row', locals: {user: user} %>
<% end %>
Now, you can prepend the new row to #table_body
using Jquery like
$('#table_body').prepend('<%= j render partial: 'user_row', locals: {user: @user} %>');
Thats it!
Hope this helps!
Upvotes: 3