12

I'm trying to open a modal that displays a list of items. The list of items is already available in the view as a variable. How do I pass this variable to the modal?

Below is roughly how the main view looks like:

View.html.erb

<div>
  <%= @users.each do |user|%>
    <h1>user.name</h1>
    <h2>user.email</h2>
    <%= link_to remote: true, 'data-toggle' => 'modal', 'data-target' => '#taskModal do %>           
      <i><%= user.tasks.count%></i>
    <% end %>
  <% end %>
</div>

<div class="modal" id="taskModal" aria-hidden="true">
...
<%= render partial: 'list_modal' %>

list_modal is a partial with the structure of the modal.

Flip
  • 6,233
  • 7
  • 46
  • 75
sotn
  • 1,833
  • 5
  • 35
  • 65

3 Answers3

15

As opposed to having the list of items already on the view, and wanting to pass it to the modal, One thing you can do is make the button ( or link ) for opening the modal to call a controller action by ajax, and then let the action respond to JS, where you will now use the corresponding view.js file to both populate the modal as well as programmatically render it ( after populating it ).

Example:

Link to open modal:

<%= link_to "Open users list", users_open_list_modal_path, remote: true %>

Users open list modal controller action:

def open_list_modal
  @user_list = User.all
  respond_to do |format|
    format.js
  end
end

open_list_modal.js.erb:

//populate modal
$('#modal').html('#{ escape_javascript(<%= render partial: 'user_list', locals: {user_list: @user_list} %> )}');

//render modal
$('#modal').openModal();

And then on the modal itself, you can now have access to the user_list (NOT @user_list) list.

Note: In this example, I made use of both erb, js, and material-modal. If you are using something different from these ( maybe slim, haml, coffee, bootstrap...), you will have to suite the example to your case.

Hope this helps.

Muhammad Zubair
  • 466
  • 5
  • 17
x6iae
  • 4,074
  • 3
  • 29
  • 50
  • 2
    I thought about this approach, but this way isn't the controller action making a redundant call to the database for data that already exists in the view? I have updated my OP to show what the view roughly looks like. Is there an approach where I don't need a new action but can just pass the user variable to the modal. – sotn Jan 20 '16 at 16:10
  • So, is it just the count of the users' task you want to pass to the modal? If so, you can make your controller action accept it as a params, and then supply it to the modal without making any additional call to the db. – x6iae Jan 20 '16 at 16:33
  • No, the count is only displayed as a link in the main view. When the user clicks on the count link, lets say a user has 5 tasks , the modal should pop up with a list of 5 tasks and task details such as task name task date,etc. Since the User model has a one-to-many relationship with tasks, I want to just pass the 'user' (not @users) variable to the modal and call user.tasks in the modal. – sotn Jan 20 '16 at 16:36
  • In that case, what I will suggest is not to get the tasks to the view in the first place, but pass the `user.id` to the controller, and then fetch only the tasks for the particular user, and pass these tasks to the `js` file used to render the modal. – x6iae Jan 20 '16 at 16:41
  • I have all the code setup as per your sample but I am getting a 403 forbidden response when I click on the link - Processing by UsersController#users_open_list_modal as JS Rendered public/403.html within layouts/public_page_layout (0.3ms) – sotn Jan 20 '16 at 21:24
  • Here is my route setup: get '/users_open_list_modal' => 'users#users_open_list_modal', as: 'users_open_list_modal' – sotn Jan 20 '16 at 21:25
  • do you have any form of authorization? maybe even `cancancan`? – x6iae Jan 20 '16 at 21:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/101230/discussion-between-sunnyk-and-sotn). – x6iae Jan 20 '16 at 21:41
  • Thank you for a great suggestion @x6iae! How does it "use" the users_open_list_modal_path? Does it need to be added to the routes file in some way? – Spectator6 Oct 01 '18 at 18:52
1

you can just directly pass it to modal. here what i did thou, on my view i have a button that trigger my modal and then i created a partial (to DRY up my code) _modal.html.erband called that partial after my button.

<button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal"></button

<%= render 'modal' %>

make sure your modal has id <div class="modal fade" id="modal" tabindex="-1" role="dialog">...

gl mate!

mrvncaragay
  • 1,240
  • 1
  • 8
  • 15
-1

You can set it as how you would normally do for view components. Better yet, separate out your model into partial, say it's _modal.html.erb. Then you can call the modal by

<%= render 'partial_name', :variable_name => your_current_variable %>

The variable would now be available as variable_name inside the partial. Also, if it's an instance variable like @your_current_variable then it will be automatically available in your partial.

avinoth
  • 412
  • 2
  • 6
  • 22
  • The user variable is not an instance variable and is only available inside the loop so it has to somehow be passed thru the link_to tag. Please see updated post. – sotn Jan 20 '16 at 16:13