blazeP
blazeP

Reputation: 91

Rails - unsuccessful edit in modal on index site

I have a list of group and I want to edit a single group name via modal. I use edit.js.erb file and bootstrap modal.

There are two cases, both wrong.

First: Using "remote: true" in Partial and link_to(in single row file) Then modal is displaying, but after SAVE button clicked always is rendering again and never close. (I don't know why)

Second: Delete remote:true from partial. Then modal is displaying, I can even save the changes. But when I type wrong name (blank or too long), line "render 'edit'" from Controller crash. (error: "Missing template groups/edit, application/edit...". I think rails doesn't know about edit.js.erb then, but how to repair it?

Have you got any ideas about this situation ?

Controller

def edit
 @group = current_user.groups.find_by(id: params[:id])
 respond_to do |format|
   format.js # actually means: if the client ask for js -> return file.js
 end
end

def update
 @group = current_user.groups.find_by(id: params[:id])
 if @group.update_attributes(group_params)
  flash[:success] = "Nazwa grupy została zmieniona"
  redirect_to groups_path
 else
   render 'edit'
 end
end

Partial for displaying form_for in modal

<%= form_for(@group, remote: true) do |f| %>
<div>
    <%= render 'shared/error2_messages', object: f.object%>
    <p>
        <%= f.label :name, "Nazwa" %>
        <%= f.text_field :name, class: 'form-control'%>
    </p>
</div>
<%= f.submit yield(:button_name), class: "btn btn-primary" %>
<% end %>

edit.js.erb file

<% provide(:button_name, 'Zapisz zmiany') %>
$('.modal-title').html("Edytuj nazwę grupy");
$('.modal-body').html("<%= escape_javascript( render partial: 'layouts/group_data_form', locals: {group: @group} ) %>");
$('#myModal').modal();

Single row in a list

<li id="group-<%= group.id %>" class="list-group-item">
<span class="group-name"><%= group.name %></span>

<%= link_to edit_group_path(group.id), remote: true, :class => "edit-option btn" do %>
    <i class="fa fa-pencil-square-o fa-2x" ></i>
<% end %>
<%= link_to group, method: :delete, data: { confirm: "Na pewno chcesz usunąć tę grupę?" }, :class => "delete-option btn btn-danger" do %>
    <i class="fa fa-trash-o" > usuń</i>
<% end %>
<!-- Modal -->
<div class="modal fade" id="myModal" 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">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Zmień nazwę grupy</h4>
            </div>
                <div class="modal-body">
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
                </div>
        </div>
    </div>
</div>

Upvotes: 0

Views: 530

Answers (1)

x6iae
x6iae

Reputation: 4164

This looks like a follow-up to your question of yesterday.

I won't say both your approaches are wrong, I'll say you are conbining two right approaches in such a way...

(1) since you used js to send save (with the use of remote: true on your form), all you need to do is to close the modal on successful save as will be defined from update.js.erb (just like you defined an edit.js.erb for the format.js in edit) as follow:

#update.js.erb
<% if @group.errors.empty? %>
  $('.modal-body').html("");
  $('#myModal').modal('hide');
  $("#notice").html("Group was successfully updated.");
<% else %>
  $("#notice").html("Error! Group not updated.");
<% end %>

#controller update action
def update
  @group = current_user.groups.find_by(id: params[:id])
  @group.update_attributes(group_params)
  respond_to do |format|
    format.html
    format.js
  end
end

What you essentially did here is to check if there is no error in the @group object(this will be true if @group got saved), then emptied your Modal and then hid it from view.

(2) When you removed remote: true you are no longer using js, so when you have a wrong name, the update does not work, and the render :edit portion of your update method kicks in. However, your edit action only specifies format.js, So what you may have to do in this case is to add format.html if you want to call with html.

def edit
 @group = current_user.groups.find_by(id: params[:id])
 respond_to do |format|
   format.js # actually means: if the client ask for js -> return file.js
   format.html
 end
end

Note however that this may not open your modal, it will go to the edit_group_path of your app, which is the /groups/:id/edit

Upvotes: 0

Related Questions