blazeP
blazeP

Reputation: 91

Rails - Editing item from list by bootstrap modal

I'm new in Rails. I try to make a list of groups (/groups) where I want to have edit and delete option in each row. Editing should be implemented by modal because Group has only one attribute - name. So I don't want to open /groups/number/edit.

My problem is: I don't know how to bind chosen group with form_for. Maybe it isn't good approach indeed. Modal is displayed, but the name field is blank. When I used debug for @group is blank too. I don't know why.

Here is my code(single group row):

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

<%= link_to edit_group_path(group.id), "data-toggle" => "modal", "data-target" => "#myModal", :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>
            <%= form_for(@group) do |f| %>
                <div class="modal-body">
                    <%= debug @group %>
                    <p>
                        <%= f.label :name, "Nazwa" %>
                        <%= f.text_field :name, class: 'form-control'%>
                    </p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
                    <%= f.submit "Zapisz zmiany", class: "btn btn-primary" %>
                </div>
            <% end %>
        </div>
    </div>
</div>

Controller

def edit
@group = current_user.groups.find_by(id: params[:id])
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
   redirect_to groups_path
 end
end

Upvotes: 1

Views: 1977

Answers (1)

x6iae
x6iae

Reputation: 4164

I will assume that the answer to my question above is a yes, and so, I'll just continue to answer.

First thing: You don't want to be repeating different Modals for each group, you want only a single Modal to be used by all the groups.

Second thing: You are very correct with the idea of wanting to send the group.id to the edit method in your controller, for it to return that group back into your Modal

However, what is wrong is how you are trying to achieve this.

<%= link_to edit_group_path(group.id), "data-toggle" => "modal", "data-target" => "#myModal", :class => "edit-option btn" do %>

You are telling your link to do two things when clicked: (1) go to edit path (2) open modal. Which one will take more importance? Right now, it is the modal that is opening, and not the edit path working, which means that you are not getting to the controller at all, so accounting for why your @group is blank.

To achieve this, you will have to tell your link to do only one thing, and when that is successful, do the other.

What I'll advice is to use Ajax (by setting remote: true) on your link to go to the controller, and then open the modal on response.

Here is a breakdown of the steps:

1.Set remote: true to make the call with Ajax

<%= link_to edit_group_path(group.id), remote: true %>

2.Tell controller action (in this case, the edit action) to respond to js

def edit
  @group = current_user.groups.find_by(id: params[:id])
  format.js
end
  1. Prepare an edit.js.erb file to handle the response (this will be in the same directory which your other view files are)

  2. Populate the form with the @group from inside the response

  3. Put the populated form in the modal
  4. Use Javascript to show the modal

    $('.modal-title').html("Edit Group")
    $('.modal-body').html("<%= escape_javascript( render partial: 'form', locals: {group: @group} ) %>")
    
    $('#myModal').modal()
    

As simple and as direct as that. Hope this helps a lot.

Upvotes: 3

Related Questions