8

When foo method of MyController is called via Ajax, it may return Javascript code like this:

class MyController < ApplicationController
  def foo
    render :js => "alert('Hello');"
  end
end

Is that possible to do something similar to return a Javascript code when foo is called normally (not via Ajax) ? I would to do something like this:

class Job < ApplicationController
  def edit
    if user_type == 'demo'
      [Here I would like to display a Javascript alert saying that 
       the job cannot be edited in demo mode. How would you do this?]
    else
      @job = Job.find(params[:id])
    end
  end
end
1
  • You are going against standart usage of Rails and HTTP Commented Mar 29, 2011 at 14:19

3 Answers 3

5

short answer is : You can't.

When you render for :js, the calling code is a javascript framework which is aware that it requested js and will execute the returned code to make it take effect when the asychronous call executes it's onSuccess action.

When rendering for the default, the calling code is the browser which expects html it won't execute pure js.

What you can do is make your view return html with some javascript at the beginning with a window.onload() handler defined to make it display the alert. But you still have to return the html (if you don't want to display the data, make it redirect to the previous view template with a specific argument so the view will have the event handler) (https://stackoverflow.com/questions/1033398/execute-javascript-when-page-has-fully-loaded)

You could also change the event handler which calls the edit action to display the alert even before the action is executed. to prevent a user from disabling js and getting over the alert, you need to still make the check on user_type and maybe simply redirect to the previous page.

Sign up to request clarification or add additional context in comments.

2 Comments

as I understand it the format of his request is not :js. it's html. in which case :update is useless for him as I don't think he can render :update for format :html, hence my answer ...
Oh, I got it. I've missed main idea of the question. +1. He can't :)
3

I recommend that you keep your controller clean and place any JavaScript code in a rjs template:

Controller

class MyController < ApplicationController
   def edit
      render do |page|
        page.html {}
        page.js {}
      end
   end
 end

edit.js.erb

alert("hello");

Whenever /my/edit/1.js is called (via: edit_my_path(1, :format => :js)) the edit.js.erb would be rendered displaying a alert.

Whenever /my/edit/1.js is called (via: edit_my_path(1)) the edit.html.erb would be rendered displaying normal html.

If you would need to check whether the request is ajax (and thus not just a normal .js call) you could, in your controller do: request.xhr?

Hope that helps!

3 Comments

@jean Works both ways doesn't it.
from what he wants, it will always call the normal html (he said : not xhr) thus it would always display normal html whether user_type is demo or not. He could possibly use a condition check in the "show" template page and use js format for user_type demo but this is not clear from your answer ...
I might have read the entire question wrong. And even so if he would use a condition check inside the template it's pretty much exploitable.
1

You can simply render the javascript as text when the js format is requested

class MyController < ApplicationController
   def update
      respond_to do |format|
        format.html {}
        format.js { render text: 'alert();' }
      end
   end
 end

1 Comment

This seems to give a ActionView::MissingTemplate: Missing template resource_name/alert();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.