Rails AJAX select box - ruby-on-rails

I am trying to have an AJAX event for a <select> box that will do some action when the selection changes. The select box is embedded inside inside a table's <td> tags
<td>
<%= form_tag '', { :id => 'test_form' } do %>
<select name='repo' value="<%= session[:repo] %>" >
<option></option>
<%#repos.sort! { |a,b| a.repo <=> b.repo }
#repos.each do |r| %>
<option <%= session[:repo]==r.repo ? "selected='repo'" : '' %>>
<%=URI.escape(r.repo)%>
</option>
<% end %>
</select>
<% end %>
<%= observe_form( 'test_form', :frequency => 2,
:update => 'update_results',
:url => {:action => :update_report, :page => 0, :update => 1 },
:loading => "$('res_spin').show()", :complete => "$('res_spin').hide()" ) %>
</td>
I have embedded the select box in a form and the observe_form method to listen for a selection change. My controller function is update_report that will do something when the selection changes. For some reason, when the selection changes, the controller function is not getting called at all.
Turned on "Firebug" and seeing this error a lot of times
$(form) is null
var elements = $(form).getElementsByTagName('*'),

Try observe_field (as discussed here):
<%= observe_field(:state, :url => { :action => :update_report, :page => 0, :update => 1 },
:update => :update_results,
:with => 'repo'
) %>

Related

nil_class when using partial

I have the following code:
new.html.erb
<% form_for #car,:html => {:name => 'car_form'} do |f| %>
<% time_created = Time.new %>
<%= f.hidden_field :CAR_DATE_CREATED, :value => time_created %>
<%= render :partial => "car_partial", :locals => {:object => #car } %>
<%= f.submit 'Create' %>
<% end %>
_car_partial.html.erb
<% fields_for #car do |f| %>
Origin: <%= f.select(:ORIGIN_TYPE,
[['Origin X', 'X'],
['Origin Y', 'Y'],
['Other origin', 'Other']
],{:prompt => "Please select"}
) %>
<%= observe_field("car_ORIGIN_TYPE", :frequency => 2,
:url => { :controller => 'car',
:action => :display_other_origin },
:with => "'id='+value") %>
<span id="otherOrigin" > </span>
<% end %>
controller code
def display_other_origin
origin = params[:id]
end
display_other_origin.rjs
if params[:id] == "Other"
page['otherOrigin'].replace_html :partial => 'car/other_origin_type', :locals => {:car => #car }
else
page.replace_html :otherOrigin, ''
end
_other_origin_type.html.erb
<% fields_for #car do |f| %>
If other, please state: <%= f.text_field :ORIGIN_TYPE, :size => 20%>
<% end %>
If user selects 'Other origin', the partial is displayed correctly but when i do <view source>,
Origin: <select id="car_ORIGIN_TYPE" name="car[ORIGIN_TYPE]">
<option value="X">Origin X</option>
<option value="Y">Origin Y</option>x
<option value="Other">Other origin</option>
</select>
<script type="text/javascript">
//<![CDATA[
new Form.Element.Observer('car_ORIGIN_TYPE', 2, function(element, value) {new Ajax.Request('/cars/display_other_origin', {asynchronous:true, evalScripts:true, parameters:'id='+value + '&authenticity_token=' + encodeURIComponent('+MtiIQj/KfX2huaetD1E7W7f2pu/HC2d31BhCPjcmlQ=')})})
//]]>
</script>
<span id="otherOrigin">
If other, please state: <input id="nil_class_ORIGIN_TYPE" name="nil_class[ORIGIN_TYPE]" size="20" type="text">
</span>
nil_class is displayed instead of 'car'.
Any help???
Thanks
Your controller action display_other_origin is not setting the #car variable - so it is nil when used in the display_other_origin.rjs file.
Basically, in your observe_field method you need to also set a parameter for the car id. For example:
<%= observe_field("car_ORIGIN_TYPE", :frequency => 2,
:url => { :controller => 'car',
:action => :display_other_origin },
:with => "'id='+value+'&car_id='#{#car.id}") %>
Then you can do #car = Car.find(param[:car_id]) in display_other_origin
...although I should note that convention states that params[:id] - when passed to the CarsController - should be the car id, and your origin should be params[:origin]

show/hide map, starting with a hidden map (display: none)

I haven't been able to load my page with a hidden map that I can then Show clicking on :toggle_map_button
In my view a Show/Hide button and a map:
<%= link_to_remote "Hide Map", :url =>{:action => :toggle_map}, :method => :get, :loading => visual_effect(:toggle_slide, "marketplace_map", :duration => 1, :queue => 'front'), :html => {:id => "toggle_map_button", :class => "toggle_map_button"} %>
<%= gmaps(:map_options => {:detect_location => true, :center_on_user => true, :zoom => 6, :id => "marketplace_map" }, :markers => { "data" => #json }) %>
In my CSS file:
#maketplace_map
{
width: 100%;
height: 400px;
display: none; <= this doesn't get to be set (when I check in HTML code with Bugzilla)
}
In my RJS file upon action :toggle_map:
page << "document.getElementById('toggle_map_button').innerHTML =(document.getElementById('toggle_map_button').innerHTML == 'Show Map' ? 'Hide Map' : 'Show Map')"
page.flash_msg(:notice_box, flash[:notice]) if flash[:notice]
page.flash_msg(:error_box, flash[:error]) if flash[:error]
flash.discard
The whole things works perfect when starting with a page showing the map. The toggle action does set display:none; correctly ...
The issue is comes when starting with a hidden map and be able to click and slide it down.
Any ideas?
Cheers,
Joel
Look bit closer at the html generated, I bet it's looking like:
<div class="map_container">
<div id="marketplace_map" class="gmaps4rails_map"></div>
</div>
so the adequate CSS lever is the map_container class. Put display:none on it.
since visual_effect seems to need an id, two options:
override the gmaps4rails partial
wrap the gmaps helper in a div: <div id="foo"> <%= gmaps(bar) %> </div>
I've got another solution for you, just tested.
You were right saying the map is small when hidden the visible.
so add an option to your helper: <%= gmaps(whatever, :last_map => false)%>
This will not create the map, only load it's objects.
Then add some javascript (I use jQuery but you've got the idea):
<script>
var createMap = true;
$(function(){
$("#click_me").click(function(){
if (counter == true)
{
Gmaps.loadMaps(); //this will create the map
counter = false;
}
$(".map_container").toggle(); // this hides and shows
});
});
</script>
resolved it thx to #apneadiving suggestion
added option:
:complete => 'Gmaps.loadMaps();' to visual_effect
In the view:
<%= link_to_remote "Show Map",
:url =>{:action => :toggle_map},
:method => :get,
:loading => visual_effect(:toggle_slide, "map", :duration => 1, :queue => 'front'),
:complete => 'Gmaps.loadMaps();',
:html => {:id => "toggle_map_button", :class => "toggle_map_button"} %>
<div id="map" style="display:none;" >
<%= gmaps(:map_options => {:detect_location => true, :center_on_user => true, :zoom => 6, :id => "marketplace_map", :last_map => false }, :markers => { "data" => #json }) %>
</div>

How can I use drop down box with Ajax to render a partial in Rails?

I created drop down menu layouts as follows.
<select name="search" id="search" >
<option value="0">Please select</option>
<option value="1">Name</option>
<option value="2">Trainer</option>
<option value="3">Venue</option>
<option value="4">Date</option>
</select>
<div id="div_to_be_updated" style="float:right"></div>
<%= observe_field 'search',
:update => 'div_to_be_updated',
:url => {:controller => 'events', :action=> 'find' },
:with => "'is_delivery_address=' + escape(value)" %>
Then I created find method in my controller.
def find
if params[:is_delivery_address] == "1" || "2" || "3"
render :partial => 'layouts/new_search'
else
render :partial => 'layouts/nothing'
end
end
Then I created partial called _new_search.
<span style="text-align: right">
<% form_tag "/events/find_search" do %>
<%= text_field_tag :search_string%>
<%= submit_tag "search" %>
<%end%>
</span>
Again I created find_search method in controller.
def find_search
events=Event.find(:all, :conditions=>["venue = ?", params[:search_string]])
end
Then I created view page. But when I searched somehting it will give exception.
NoMethodError in Events#find_search
Showing app/views/events/find_search.html.erb where line #10 raised:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
What should I do? Can anybody help me>
Not sure if this is it - but the following line has a bug
if params[:is_delivery_address] == "1" || "2" || "3"
this will always be true, since if params[:is_delivery_address] != "1" then the result will be "2" (non-nil - ie true).
Try irb to check:
> params = {:is_delivery_address => "0" }
> params[:is_delivery_address] == "1" || "2" || "3"
=> "2"
I have this working in Production:
<% form_for :youractionhere, :url => { :action => "youractionhere", :param1 => #market, :param2 => #param2 } do |f| %>
<%= select_tag :search, options_from_collection_for_select(#search_options, "search_option_name", :search_option_name, :search_option), { :onchange => "this.form.submit();" } %>
<% end %>
The key is to have the :url => { :action => "youractionhere"} and also the {:onchange => "this.form.submit();"} in it. The action, of course, should render the partial when called.

Rails help with select and render partial

Want to create a select that tells what info to pass to the partial in a Rails 3 App.
Currently.
Lets say default is
<% orders_date_range = #orders.closed_today %>
Then
<div id="reports">
<%= render :partial => "report_details", :locals => { :orders => orders_date_range } %>
</div>
Can I create a select tag to pass in the orders_date_range? Or is there a better way of doing this?
UPDATE
<% orders = #orders.closed_today %>
<% #options = [["this week", #orders.closed_this_week],["this year", #orders.closed_this_year]]%>
<%= select 'orders', 'order', #options.collect {|f| [f[0], f[1]]}, :remote => true %>
<div id="reports">
<%= render :partial => "report_details", :locals => { :orders => orders } %>
</div>
Don't know why, but would only work with 'orders', 'order' for select.
applicaton.js
$("#orders_order").change(function(){
$.getScript("reports");
});
reports.js.erb
$("#reports").html("<%= escape_javascript(render :partial => 'report_details', :locals => { :orders => params[:selected] } ) %>");
Probably would be cool to do this as an AJAX thing....
Form.erb:
#call this at the top of your view
<%= javascript_include_tag :defaults %>
<%= select 'orders', 'option', #options.collect {|f| [f[0], f[1]]}, :onchange => remote_function(:url => {:action => :render_my_partial}, :with => 'Form.Element.Serialize(this)' %>
Controller:
def form
#options = [["option1", option1],["option2", option2]...]
end
def render_my_partial
render update do |page|
page.replace_html 'reports', :partial => 'report_details', :orders => params[:orders][:option]
end
end

dynamic link_to_remote in rails with jquery

I'm trying to pass a string with a link_to_remote call as the :id, and the string should be collected from an input field with and id of "movie_title".
<div id="search_list">Nothing here yet</div>
<br />
<% semantic_form_for #movie do |f| %>
<% f.inputs do -%>
<%= f.input :title, :class => "movie_title" %> <%= link_to_remote( 'Search...', { :url => { :action => :imdb_search, :id => "'+$('\#movie_title').value+'" } }, { :title => "Search for this movie", :class => "imdb_search" } ) -%>
[...removed text that does not matter...]
<% end -%>
<%= f.buttons %>
<% end %>
I keep getting an javascript error, and if I remove the # from the jquery in the link, it returns "Undefined".
The link I get is:
<a class="imdb_search" href="#" onclick="jQuery.ajax({data:'authenticity_token=' + encodeURIComponent('yHPHYTZsPTQLi9JYSauUYcoie/pqPPk2uHBTN0PzNsQ='), dataType:'script', type:'post', url:'/movies/imdb_search/'+$('%23movie_title').value+''}); return false;" title="Search for this movie">Search...</a>
So I want the link updated with the contents of movie_title.
How do I do that?
I'd try something like
<%= link_to_remote( 'Search...', {
:url => { :action => :imdb_search},
:with => "'id=' + $('movie_title').value",
{:title => "Search for this movie", :class => "imdb_search"}
)
Fixed it
Used:
$('movie_title').val()
Insted of
$('movie_title').value

Resources