Reputation: 496
I'm trying to redirect un-logged-in users directly to a login window, which is a bootstrap modal window.
I wrote a method called logged_in_user
in ApplicationController
:
def logged_in_user
unless !current_user.nil?
flash[:danger] = "Please log in"
redirect_to root_url
end
end
The login_url
routes to sessions#new
, which I defined as below:
(sessions_controller.rb)
def new
respond_to do |format|
format.html
format.js
end
end
Here is the view that redirect_to root_url
points to:
<!-- Login Window -->
<div id="login-window" class="modal fade" role="dialog" aria-labelledby="login" aria-hidden="true"></div>
Here is new.js.erb
that gets executed when sessions#new
is called:
$("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");
Thus the login form, which is _new.html.erb
in app/views/sessions
, will appear as a popup window once the sessions#new
is called.
Except that it has to be processed as JS rather than HTML. So I have the following link, which is in the _header.html.erb
and available across all views, to ensure this is the case:
<%= link_to "Log in", login_path, {remote: true, 'data-toggle' => "modal", 'data-target' => '#login-window'} %>
This works fine when the link is clicked. This is why I chose to do redirect_to root_url
rather than redirect_to login_url
in logged_in_user
method as the latter approach results in "Missing Template error".
But what I really want is for users to be redirected straight to the popup window, rather than them being redirected to root_url first and having to click "Login" link to enter the form.
In other words, I need a way to somehow redirect users to the sessions#new
by issuing an Ajax request so that sessions#new
can be processed as JS.
I tried the following approaches for the desired redirect within logged_in_user
method, none of which worked:
render js: "window.location = <%= escape_javascript(render 'sessions/new') %>"
render js: "window.location = '/sessions/new'"
redirect_to login_url, format: "js"
Any suggestions will be greatly appreciated!
Upvotes: 2
Views: 1013
Reputation: 496
This issue was solved by modifying the following files:
(application_controller.rb)
def logged_in_user
unless !current_user.nil?
session[:modal] = true
redirect_to !request.referrer.nil? ? (request.referer + "#login-window") : "#login-window"
end
end
I've omitted flash[:danger]
because it was shown "behind" the faded
screen. I've added request.referer
to make sure that the login popup window appears where the user has made a request, rather than redirecting them to root_path. I thought this would be better for user experience. (The ternary was just to handle the case where request.referer
can be nil
, in which case the code rases an error.)
The motif behind session[:modal] = true
is explained below.
(at the bottom of application.html.erb)
<% if session[:modal] == true %>
<script type="text/javascript">
$(document).ready(function() {
if(window.location.href.indexOf('#login-window') != -1) {
$('#login-window').modal('show');
$("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");
}
});
</script>
<% session[:modal] = false %>
<% end %>
Here I'm using javascript directly inside the view template. Since the view template upon which the popup window appears is not limited to one particular template, I've out the script inside application.html.erb
, which applies to all view templates. The first half of it was inspired by cruncher 's answer. (Thank you cruncher!) I've then added $("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");
to make sure that the login form (``app/views/sessions/_new.html.erb) does appear.
Now, since I want the login popup window to appear only when non-logged-in users try to access pages which require login, I went ahead and added session[:modal] = true
to indicate that logged_in_user
method was indeed called, which means that the above situation indeed occurred.
Then, inside application.html.erb
I can check whether the popup window should appear by <% if session[:modal] == true %>
. If that's the case, then the script will be executed, after which I set the value of session[:modal]
to false
.
This session[:modal]
logic may not be necessary (in fact, it worked fine without it), but I've added it just in case.
That's it :)
Also, for those of you who want to implement this pop-up window functionality with bootstrap, here is a blog I've found really useful:
https://coderwall.com/p/ej0mhg/open-a-rails-form-with-twitter-bootstrap-modals
Happy coding!
Upvotes: 1
Reputation: 54
Just add this
<script type="text/javascript">
$(document).ready(function() {
if(window.location.href.indexOf('#login-window') != -1) {
$('#login-window').modal('show');
}
});
</script>
And
redirect_to root_url+"#login-window"
Upvotes: 1