Abram
Abram

Reputation: 41844

Is it possible to render a partial directly from application.js

I am trying to load a second select menu when the user chooses an option from the first select menu. Here is my application.js code:

$(document).ready(function(){
  $('#aidmodel_brand').change(function() {
    $("select option:selected").each(function () {
      $('#modeler').load('shared/model'); 
    });
  });
});

I know this code works because I have substituted the last line with a generic jquery event and have seen the results on the page when an option from the first select menu is selected.

The problem is that when I run the code above a GET request is performed by the browser for shared/model but I get a 404 error. Is this something I can fix via routes.rb?

Also, I have tried .html('<%= escape_javascript(render(:partial => shared/model)) %>') with single and double quotes.. single quotes just causes the exact text within .html('') to be printed inside my #modeler div. Double quotes does nothing.

I have looked at solving through the traditional method of creating a definition inside of my aidmodel controller and creating a .js.erb inside the views/aidmodels with the same name, but I can't figure out how to trigger the loading of the second select menu without hitting the form submit button.. which I don't want.

Sorry for the drawn out question, but I spent hours on this last night, and lost plenty of sleep as a result! Thanks!

UPDATE:

I have attempted to create a js.erb partial called scripto with the code from above and called it using <%= render( :partial => 'shared/scripto', :formats=>[:js] ) %>... this seems to work.. The java code is imported into my page.. However, as soon as I add any ruby code into the partial like the .html() I get a missing partial error. I should mention that I have also tried adding :handlers=>[:erb] to the partial call... still no luck. Thanks

UPDATE 2:

$(document).ready(function(){
  $('#aidmodel_brand').change(function() {
    $("select option:selected").each(function () {
      $('#modeler').html('<%= escape_javascript(render(:partial => shared/model)) %>'); 
    });
  });
});

UPDATE 3

Ok, so I have successfully called the partial as above but using double quotes around the partial name... however, now I have a real problem. I want to pass the name of the selected option to the partial... So far I have figured out how to assign the selected option to a java var:

$("select option:selected").each(function () {
  var brand = ($(this).text());

But, I must pass the variable to the partial in the form of :brand => @brand .. is there a way to assign the text within var brand to an @brand variable so this can be passed to the partial? Thanks!

UPDATE 4

Thanks again Mohamed. Unfortunately I don't see any way to access the the variable from inside the partial. I think that the $(this).text() must be converted to a rails instance variable in the form of @brand before it can be accessed from inside the partial. Also, I don't think you can put java code inside the escape_javascript method, so somehow the variable assignment to @brand must happen prior.

Upvotes: 1

Views: 868

Answers (2)

mohamagdy
mohamagdy

Reputation: 2093

No, because the js can't understand Ruby code. Only the rjs can. If you want to call a partial from js then create an .rjs file and call it from it using <%= escape_javascript(render(:partial => shared/model)

For the UPDATE 2 you added: It seems good, but double check this line $('#modeler').html('<%= escape_javascript(render(:partial => "shared/model")) %>'); the partial name in double quotes.

Upvotes: 2

ka8725
ka8725

Reputation: 2918

There is a one useful method to render partial and save it in variable: render_to_string. And yes! You are able to load partials from js:

  1. Use should write action in controller which will return partial(s) and add route to in in your routes.rb config
  2. In action you can render on partial on various like this:

    respond_to do |format|

      format.html {render :partial => 'partial1'}
    
      format.json {render :json => {:partial1 => render_to_string(:partial => 'partial1'), :partial2 => render_to_string(:partial2 => 'partial2')}}
    

    end

  3. In js you could use code like this:

    $.get('[path_to_action]', {[params are here]}, function(data) { [data is either html or json. this is a response from your action]})

Note: You able also to use js.erb or html.erb templates

Upvotes: 1

Related Questions