Open a rails form with Twitter Bootstrap modals
Sometimes we require to open a form or display information that opens up as modal windows, I will show you an easy way to do it using twitter bootstrap modals.
First make sure you added the bootstrap-sass gem to your gemfile and also used bundle to install the gem.
Also in your application.js include the calling to the bootstrap-modal javascript file in the following way:
//= require bootstrap-modal
Now in the routes.rb file add the route to the partial you want to show as modal, for example:
get "project/new_release" => 'project#new_release', :as => :new_release
In the controller add the respond_to block to use some ajax magic
def new_release
respond_to do |format|
format.html
format.js
end
end
In the calling view use a link_to helper in the following way:
<%= link_to 'Add release', new_release_path, {:remote => true, 'data-toggle' => "modal", 'data-_target' => '#modal-window'} %>
We need to have a DIV in the calling view that will load the partial as the modal window, so we are having something like this:
<div id="modal-window" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
We are going to put the partial form inside that div with jquery.
Make sure to have the partial, in this case should be a file named _new_release.html.erb, inside this you will have the content you want to show for example:
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Modal header</h3>
</div>
<div class="modal-body">
**here comes whatever you want to show!**
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary">Save changes</button>
</div>
Now we need some javascript to make this works, make a file named same way as the controller action but with the suffix .js.erb for this example should be:
new_release.js.erb
And inside the file add the following:
$("#modal-window").html("<%= escape_javascript(render 'project/new_release') %>");
That's it, now when you click on the link a nice modal will show up with a very clean fade effect.
Hope this little snippet can be handy for you.
I took all the information from the following sites.
Written by Eduardo Vidal
Related protips
19 Responses
Thank you. We still need to add $("modal-window).modal() in the .js.erb file for the modal to trigger.
great, Thanks.
'data_toggle' should be 'data-toggle'
Thanks, for the advice, I will correct it.
@gautham-nookala No, you don't. It get's triggered in the link_to statement with data-_target and data-toogle. See the official Bootstrap manual.
To get it working with Bootstrap 3 you have to remove all "hide" class references in your < div >
this is just what i find ,
thank you very much
got it work after having removed "hide" from the class
hi , I have tried this one , i got fade screen but no popup was displaying
How to handle with multiple modals?
I have now this:
$('.modal-service').empty().html('<%= escapejavascript(render :partial => 'serviceform', :object => @service) %>');
$('.modal-employee').empty().html('<%= escapejavascript(render :partial => 'addemployee', :object => @service) %>');
But with every click to open a modal, it loads all the modals which causing some conflicts.
I got everything to work without using the new_release.js.erb file as well as the 'require' in application.js. Why would you need that in there exactly? Great tutorial btw!
Thanks!!!
I'm really stuck in trying to get this setup.
For Rails 4 users, one thing to note is that the require bootstrap/modal needs to be / instead of -.
Also, see this post. The suggestion was to add $('#modal-window').modal('show'); to the end of the js file and to keep the js.erb file in the views folder instead of the app assets javascripts folder, so that the render action can work.
I still can't get this working though. When I click the link that is supposed to render the modal, I get a greyed out screen but no modal. No console errors and html inspector shows modal container is recognised. The network inspector does not show any path as available.
Link i was referring to is here: http://stackoverflow.com/questions/39197196/rails-4-bootstrap-modal-form-setup
@endlessly stuck - I had better luck looking at this: http://v4-alpha.getbootstrap.com/components/modal/
bootstrap was already included in my (rails 5) project so those methods were already available. I just added this to my button code: {:remote => true, 'data-toggle' => "modal", :class => 'btn btn-primary btn-small', 'data-_target' => '#myModal'}. The :remote => true asks the controller for js - so the controller respond_to stuff above is important. (as well as the routes.rb part). Then your js code for the partial above should also work.
@endlessly I had the same problem as you, I fixed it this way:
1. Your calling to render the modal must be outside <body>, <nav> or any tag, for example mine:
<nav>
<%= linkto 'Sign up', signin_path, {:remote => true, 'data-toggle' => "modal", :class => 'nav-item nav-link', 'data-_target' => '#modal-window'} %>
</nav>
<div id="modal-window" class="modal" tabindex="-1" role="dialog" aria-labelledby="gridModalLabel" aria-hidden="true">
@endlessly stuck try $("#modal-window").html("<%= j escapejavascript(render 'project/newrelease') %>");
@endlessly stuck, a buddy of mine doing frontend have just show me the trick that made it working (I was stuck too with greyed out screen but no modal):
The modal window should be declared like this:
<div id="modal-window" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content"></div>
</div>
</div>
Then, rendering should be made this way:
$("#modal-window").find(".modal-content").html("<%= j (render 'application/modal') %>");
$("#modal-window").modal();
Thanks for the important information.
Thank you so much. You're a life-saver. @texpert, thanks for the useful info. OP, you should add @texpert's info to your article to keep up-to-date.