RoR Class vs Instance variables, and relaying a value to partial - ruby-on-rails

I have a controller "mainpage", with a correspondingly named view. The controller creates a #myLocalSuites variable, and the view includes the following line:
<li class="active"><%= link_to "Perforce", :action => 'renderp4', :remote => true, :localSuites => #myLocalSuites %></a></li>
Routing is defined such that clicking this link_to calls renderp4.js.erb to render a partial within the mainpage view:
$('#MainPage').replaceWith('<%= escape_javascript render "perforce_sync/perforceSync" %>')
where _perforceSync partial includes:
<%= select_tag "perforceSuites", options_for_select(*MYOPTIONSVARIABLE*), {:class => 'form-control', :size => "20", :multiple => true} %>
Where *MYOPTIONSVARIABLE* needs to be myLocalSuites as cascaded down from the mainpage view/controller.
Having tried everything I can think of, and failed - can someone please show how to modify the above snippets to use the required variable in the PerforceSync partial? Everything I've tried seems to produce something along the lines of:
ActionView::Template::Error (undefined method `map' for nil:NilClass):
An example of what I've tried. I don't think I'm a million miles off, but...
<li class="active"><%= link_to "Perforce", :action => 'renderp4', :remote => true, :localSuites => #myLocalSuites %></a></li>
$('#MainPage').replaceWith('<%= escape_javascript render "perforce_sync/perforceSync", :suitesLocally => params[:localSuites]%>')
<%= select_tag "perforceSuites", options_for_select(params[:suitesLocally]), {:class => 'form-control', :size => "20", :multiple => true} %>
Thanks! :)

In response to your comment, there are two things you can do here. One way is to simply render some dynamic JS on page load, and then use javascript to show that data at a later point.
If this data however is to depend on user actions after the page has loaded, you must make another request to the server using AJAX.
The first way might look like this:
<script>
var my_data = "<%= #some_data %>";
//#some_data could be set by the controller action for example
$('button').click(function() {
$('div.content_container').text(my_data);
});
</script>
The second way would look like this:
<script>
$('button').click(function() {
$.ajax({
url: '/some_resource/id.json',
data: {param1: 'some_user_data'}
}).done(function(data) {
$('div.content_container').text(data);
});
});
</script>
The data option for the ajax call allows you to pass parameters back to the server, so you can send some data provided by the client. Documentation for jquery ajax is here if you want to see other options.
The .done callback gets fired when the client receives a response from the server, and the function parameter is the data returned.

Related

Displaying validation errors with Ruby

I'm having some trouble rendering validation messages using "remote => true"
I have a partially rendered form for saving an address
<%= render :partial => "registrations/address", :locals => {:address => #user.customer_addresses.build, :is_new => true, :checked => false} %>
In this form, the user clicks this button to create a new address
<%= link_to "Save Address", "javascript://", :remote => true, :data => "new", "data-target" => create_user_address_url, "data-method" => "Post" %>
I have the 'create_address' function set up in the controller (which returns the validation errors), as well as a create_address.js.erb file. However, it doesnt seem like the browser is executing anything in the js file.
It would be great to see the code of js.erb file
But I assume you have escape javascript issue.
Just use j in your render partial method. E.g.
<%= j render('partial_name') %>
You might have forgot to reload the partial which show the error message. After using remote => true you need to reload the partial so that the changes will reflect on that partial.

Rails + Bootstrap: Render partial with locals in Bootstrap popover

I want to pass a local variable to my partial when I render it in a Bootstrap popover. Here's what I've got, though I'm pretty sure I'm not rendering the partial correctly in the content_tag.
<%= content_tag :button, type: "button", class: "btn btn-default",
:data => { container: "body", toggle: "popover", placement: "bottom",
content: "#{render 'layouts/quick_add_form', :locals => {:code => item1.code}}"} do %>
button
<% end %>
Any help is much appreciated!
EDIT
Currently the local variable is not being passed to the partial, and so the :code attribute is not saved on form submit.
I don't believe you can use #{} except in HAML (oh wait, I see #{} is used as regular Ruby string interpolation - I think it will work). Not only that, but when you call render on a partial and you want to pass additional values, for some reason (for some versions of Rails), you have to explicitely declare it a partial:
render partial: 'layouts/quick_add_form', :locals => {:code => item1.code}
That will work, at least in an ERB or HAML.
You should also verify the generated HTML is escaped properly in the data attribute by viewing CTRL-U source in the browser.

Ruby on Rails 3: AJAX call not refreshing div with link_to

I am new to Ruby on Rails and i am working through a few example applications in the O'Reilly Head First Rails book. In one of the examples there is a page made up of three partials. The middle partial is a list of items. There is a link right below this section that, when clicked, should refresh the div containing that partial. The book is running examples based off of Rails 2.3 i believe and i am using Rails 3.1. This is the example that the book is giving me:
routes.rb:
map.connect '/flights/:flight_id/seats', :action=>'flight_seats', :controller=>'seats'
seats_controller.rb:
def flight_seats
#flight = Flight.find(params[:flight_id])
render :partial => "flights/seat_list", :locals => {:seats => #flight.seats}
end
show.html.erb:
<div id="seats">
<%= render :partial=>"seat_list". :locals=>{:seats=>#flight.seats} %>
</div>
<$= link_to_remote("Refresh Seats", :url=>"/flights/#{#flight.id}/seats", method=>"get", :update=>"seats") %>
This example is also using prototype.js since that's what Rails 2.3 came with built in. Rails 3 has jQuery as the default JavaScript library. (not sure if that makes a big difference)
Here is what i have so far. This is getting the contents of the partial correctly, it's just not updating the "seats" div after the AJAX call gets the partial. My code:
routes.rb:
match 'flights/:flight_id/seats' => 'seats#flights_seats'
seats_controller.rb:
def flights_seats
#flight = Flight.find(params[:flight_id])
render :partial => "flights/seat_list", :locals => { :seats => #flight.seats }
end
show.html.erb:
<div id="seats">
<%= render :partial => 'seat_list', :locals => { :seats => #flight.seats } %>
</div>
<%= link_to "Refresh Seats", "/flights/#{#flight.id}/seats", :remote => true %>
Any idea why my <div id="seats"> won't refresh with the updated partial? I'm betting there is but i'll ask anyway, is something wrong with my code?
The :remote => true option is a bit weird if you aren't returning JSON data. You can wrap your HTML in a JSON object, though, which is what I typically do. Or if you want something closer to your existing code something like this should work for you:
<%= link_to "Refresh Seats", "/flights/#{#flight.id}/seats", :class => "refresh-seats" %>
In your javascript somewhere:
$(document).delegate(".refresh-seats", "click", function(e){
e.preventDefault();
$("#seats").load(this.href);
});

Replace will_paginate links after ajax call

I'm working on a Ruby on Rails aplicattion, my problem is that I have all the comments of a post paginated and showed perfectly, but when an user saves a new comment via ajax, and I replace all the content with the partial with the new content(including the will_paginate #comments), the urls of the links change to the url of the action that saves the comments and i don't know how to do to make them link correctly.
I tried with <%= will_paginate #comments, :params => {:controller => 'posts', :action => 'show_outside_comments' %>
But I get the same results.
Thank you very much for your help!
Have you looked into the ajax methods described here?
http://railscasts.com/episodes/174-pagination-with-ajax
you can execute javascript code to update the links,
something like:
<div class="paging_links" >
<%= will_paginate #comments, :params => {:controller => 'posts', :action => 'show_outside_comments' %>
</div>
<script type="text/javascript">
jQuery('.paging_links a').click(function(event){
href = jQuery(this).attr('href');
event.preventDefault();
// update href here
})
</script>
$('.pagination a').attr('href', function() {
$(this).prop('href').replace('/comments', location.pathname);
});
Assuming you want to replace `/comments' with the current pathname.

Rails: How to pass value from textfield to a partial

How can I easily pass the value I get from the auto_complete textfield to a partial.
<%= text_field_with_auto_complete :participant, :name, {}, {:url => {:controller => "contentcom/discussions", :action => :get_users_for_auto_complete}, :method => :get, :param_name => 'search'} %>
<%= button_to_function(:OK) do |page|
page.insert_html :top, :participants, :partial => 'participant', :locals => end %>
Bye,
Nico
First of all you need to know that the helpers text_field_with_auto_complete and button_to_function not really handle user actions, but only generate HTML and javascript code. Only generated javascript code can interact with the user. In this case text_field_with_auto_complete generates the following (approximately):
<input type="text" id="participant_name" name="participant[name]" size="15" />
<div id="participant_name_auto_complete" class="auto_complete"> </div>
<script type="text/javascript">
var participant_auto_completer = new Ajax.Autocompleter (
'Participant',
'Name',
'/contentcom/discussions/get_users_for_auto_complete',
{method: 'GET', param_name: 'search'}
);
</script>
The above code is that the user gets in his browser.
If you read the documentation for text_field_with_auto_complete, then you will see that we can use the option :after_update_element. This option allows us to specify the name of the JavaScript function that will be called when the user selects one of the proposed values.
What we need to do:
write a JavaScript function that
will display anywhere user-selected
value from autocomplete field.
call text_field_with_auto_complete
with :after_update_element
That's how the template will look like:
<ul id="selected_participant_container"></ul>
<%= text_field_with_auto_complete :participant, :name, {}, {
:url => {:controller => "contentcom/discussions", :action => :get_users_for_auto_complete},
:method => :get,
:param_name => 'search',
:after_update_element => 'afterParticipantSelected'
}%>
<script type="text/javascript">
function afterParticipantSelected (el, value) {
var container = document.getElementById ('selected_participant_container');
container.innerHTML = value;
}
</ Script>
Now, when a user selects a value in the autocomplete field, it will be displayed in the element with id = selected_participant_container
Of course, you can use methods that are proposed by tokland.
But I would Recommend you first learn the basics of HTML and Javascript.
Note first that the block of button_to_function (and its partial, of course) is generated server-side, so it has no way to know the value of the autocomplete in the client. You have 2 ways to accomplish what you want: create a RJS action for the auto_complete (if that's possible) or 2) use Javascript/AJAX and connect to the auto_complete URL, get the value and modify the DOM accordingly (also in JS).

Resources