1

I have ajaxified my site using the ajaxify_rails GEM. Now all the request are of type JS, the only request that can be of type html is page refresh. I want to display a conformation box asking user "Whether he wants to continue or not" for every html request only. For the code to be generic, I want it to be present in base_controller. Is it possible to achieve this?

If I try the following:

BaseController < ApplicationController
  def some_method
    if !request.xhr?
      render :template => "conform_dialog" #using jQuery way of showing confirmation box
    end
  end    
end

OtherControllers

before_filter :some_method

I will get a double render error. What is the best possible way to achieve this?

EDIT

conform_dialog.html.haml

:javascript
  jQuery(window).on("beforeunload", function(){
    return "This will reload the page.";
  });
Abhi
  • 4,123
  • 6
  • 45
  • 77
  • Rails has a built-in helper for this kind of thing, but only when posting forms. If you want to enable this on posted forms, see this answer: http://stackoverflow.com/a/15771639/3270759 . – Sam Oct 31 '15 at 13:03
  • @SamDavies Hey thanks for the suggestion. I want the conformation to appear on reloading every page and every page may not have a form. – Abhi Nov 02 '15 at 04:31

1 Answers1

1

You'll not be able to pull a "confirmation box" out of a controller, and besides you'll be best putting your code directly into ApplicationController:

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   before_filter :some_method

   private

   def some_method
       ...
   end
end

The issue you have is that the HTML request has to load a new page. The browser expects the response to be formatted HTML, which it will use to populate the new view.

If you try and show a "confirmation box" through this flow, you'll either need to use Javascript/JQuery (before refresh), or you'll have to render an entire "confirmation" page:

-

If you wanted to use the JS confirmation method, you'd have to use the onbeforeunload call:

Displaying a confirm dialog box when the user tries to refresh/close/navigate to another web page

window.onbeforeunload = function (e) {
  e = e || window.event;

  // For IE and Firefox prior to version 4
  if (e) {
    e.returnValue = confirm("Really?");
  }

  // For others
  return confirm("Really?");
};

This will show a simple JS "confiramtion" box (ok/cancel) which allows you to determine the growth.

-

If you wanted to use the controller action, you'd have to render the confirmation page as a separate HTML request:

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   before_filter :confirmation, if: Proc.new{ |c| !c.request.xhr? }

   private

   def confirmation
      if request.get?
        @page = request.referrer
      elsif request.post?
        render request.referrer
      end
   end 
end

#app/views/application/confirmation.html.erb
<%= button_to "Really?", confirmation_path %>

I've not used ajaxify_rails before, but I'm sure Turbolinks does exactly the same thing...

Turbolinks makes following links in your web application faster. Instead of letting the browser recompile the JavaScript and CSS between each page change, it keeps the current page instance alive and replaces only the body (or parts of) and the title in the head. Think CGI vs persistent process.

By default, all Rails apps come bundled with turbolinks (it can get annoying if you don't know how to code with it).

Thus, if you ever have problems with your approach, you may wish to revert back to Turbolinks, removing much of the problem for you.

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • Thank you for the answer. I'm also trying the jQuery way of showing conformation. I have moved my code to Application Controller. But, it shows me a blank page whether I **Leave Page** or **Stay On Page**. – Abhi Oct 31 '15 at 11:09