Skip to content

Instantly share code, notes, and snippets.

@coreyward
Last active September 7, 2018 17:14
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save coreyward/1456815 to your computer and use it in GitHub Desktop.
Save coreyward/1456815 to your computer and use it in GitHub Desktop.
<div id="modal">
<div class="content"></div>
</div>
// This partial should be @imported into your layout Sass file, or included via the Asset Pipeline
//
#modal {
width: 100%;
padding: 0 20px;
position: absolute;
left: 0;
right: 0;
opacity: 0;
display: none;
@include transition(opacity 0.3s);
&:before {
display: block;
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 50;
}
.content {
background: #fff;
box-shadow: 0 2px 25px rgba(#111, 0.3);
padding: 30px;
margin: 0 auto;
max-width: 600px;
position: relative;
z-index: 51;
border-radius: 3px;
}
}
//= jquery
//= jquery_ujs
//= modals
# in your app controller, you'll want to set the layout to nil for XHR (ajax) requests
class ApplicationController < ActionController::Base
layout -> do
request.xhr? ? false : 'application'
end
end
<%= link_to 'New Post', new_post_path, remote: true %>
# This file should be "required" into your `application.js` via the Asset Pipeline.
#
$ ->
$modal = $('#modal')
$content = $modal.find('.content')
$window = $(window)
$(document).on 'click', (e) ->
if $(e.target).is $modal
$modal.hide()
$(document).on 'ajax:success', 'a[data-remote]', (xhr, data, status) ->
$content.html(data)
$modal.css opacity: 0, display: 'block'
docW = $window.width()
docH = $window.height()
mW = $modal.outerWidth()
mH = $modal.outerHeight()
x = (docW - mW) / 2
y = ((docH - mH) / 2) + $window.scrollTop()
$modal.css left: x, top: y, opacity: 1
@pjmorse
Copy link

pjmorse commented Nov 9, 2012

@coreyward - thanks for the update, and for being willing to push up an update when random people turn up and start asking questions about code you wrote ten months ago. :) That does indeed make the error message go away.

Now, though, the on-ajax-success function simply isn't getting called at all, and I'm not sure how to debug why. No error messages. I can see that the action called by the xhr is returning the right markup (albeit with a 304 Not Modified response, not a 200 OK - maybe that's the problem?) it's just not tripping the function. Baffling. I'm going to chase it a bit longer and then I'll do the SO thing and come back here with any response I get.

@pjmorse
Copy link

pjmorse commented Nov 13, 2012

Just to update the above in case someone comes back to it: this is the Stack Overflow question about my latest bug. I don't think it's related to Corey's gist specifically; the ajax:success event doesn't seem to get tripped, which other SO question/answers I've found suggest may be more of an issue with the Ajax response than with anything included here.

@pjmorse
Copy link

pjmorse commented Nov 13, 2012

Aha. The answer is that Rails' rails.js doesn't trigger ajax:success if the response to the ajax request isn't text/json. This meant I had to adjust my controller to respond properly, from

format.js

to

format.js { render :json => { :html => render_to_string('templatename')}, :content_type => 'text/json' }

...and then alter modals.js.coffee to use .html(data.html) instead of just .html(data).

@boomer
Copy link

boomer commented Jan 30, 2013

Corey - this was super helpful. Have you thought about adding a function to close the modal if the user clicks outside it?

@mvandeloo
Copy link

In Rails 4 this line:

layout Proc.new { |controller| controller.request.xhr? ? nil : 'application' }

should be

layout Proc.new { |controller| controller.request.xhr? ? false : 'application' }

@coreyward
Copy link
Author

coreyward commented Jan 31, 2017

I've updated this Gist to work with Rails 5.

@crondaemon
Copy link

Hi, and thanks for the tutorial, it helped me a lot!

I'm having a problem on the very last step of the ajax stuff. In this line

https://gist.github.com/coreyward/1456815#file-modals-js-coffee-L13

data and status are undefined. Do I need to do something special in my method? I have

def new
  @model = Model.new
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment