Skip to content

Instantly share code, notes, and snippets.

@cwise
Created June 7, 2012 19:00
Show Gist options
  • Save cwise/2890831 to your computer and use it in GitHub Desktop.
Save cwise/2890831 to your computer and use it in GitHub Desktop.
Calling a server method to calculate something via Ajax...
Imaging you have a form that represents a Wall.
<%= content_tag :h2, t(:wall).capitalize %>
<%= simple_form_for @wall do |f| %>
<%= f.hidden_field :current_units %>
<%= f.input :direction, :as => :select, :collection => @directions, :value_method => :code, :label_method => label_method, :include_blank => false %>
<%= field_set_tag t(:construction).capitalize do %>
<%= f.input :wall_type, :as => :select, :collection => @wall_types, :value_method => :code, :label_method => label_method, :include_blank => false, :input_html => {:class => 'initial_field'} %>
<%= f.input :lintel_type, :as => :select, :collection => @lintel_types, :value_method => :code, :label_method => label_method, :include_blank => false %>
<%= f.input :corners, :input_html => {:size => 10, :class => 'number_field'} %>
<%= f.input :intersections, :input_html => {:size => 10, :class => 'number_field'} %>
<% end %>
<%= field_set_tag t(:measurement).capitalize.pluralize do %>
<%= f.input :height, :input_html => {:size => 10, :class => 'number_field'}, :hint => u(@wall.height_as_current.units) %>
<%= f.input :perimeter, :input_html => {:size => 10, :class => 'number_field'}, :hint => u(@wall.perimeter_as_current.units) %>
<%= f.input :gross_area, :input_html => {:size => 10, :disabled => 'disabled', :class => 'number_field'}, :hint => u(@wall.gross_area_as_current.units) %>
<% end %>
<%= f.input :rvalue, :input_html => {:size => 10, :disabled => 'disabled', :class => 'number_field'}, :hint => u(@wall.rvalue_as_current.units) %>
<%= f.button :submit, @wall.new_record? ? t(:create).capitalize : t(:update).capitalize, :class => 'button' %>
<% end %>
Walls have a gross_area that is calculated by function of the height and perimeter:
class Wall
def gross_area
height * perimeter
end
end
We will call a remote function when the user changes the height or perimeter:
$('#wall_perimeter, #wall_height').change(function() {
calculate_area(false);
});
function calculate_area() {
$.getJSON('/walls/calculate_area', $('form').serialize(),
function(data, textStatus, jqXHR) {
if(textStatus=="success") {
$('#wall_gross_area').attr("value", data.gross_area);
}
});
};
In the above, we simply serialize the entire form as a Wall object and pass it as a parameter to a calculate_area method in the WallsController. Then we pull the return value from data (in this case, data.gross_area).
The controller looks like this:
def calculate_area
@wall=Wall.new(params[:wall])
respond_to do |format|
format.json {render :json => {:gross_area => @wall.gross_area}}
format.xml {render :xml => {:gross_area => @wall.gross_area}}
end
end
It builds a wall object from the parameters (the form contents) and then send back a hash with the values we want, in this case the gross area as calculated by the model itself.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment