lundi 30 mars 2015

Controller method using JS doesn't return/render data when called within modal popup

I've been stuck with this problem a couple of days, and I didn't find anything that could help me.


The idea is to get price_scenarios index view rendered in a modal popup. For each price_scenario shown in the table, a controller method, "price" is called. This method gets some info from the model and render it formated using JSON. This way of getting the prices was coded for a previous developer who is no longer in the project, and is necessary becouse price values can take a while to be calculated, so a small wheel gif is rendered when page loads.


The problem: price_scenarios "price" method doesn't render any value. This only happens if "price" is called within the index view rendered in a modal popup, I've tried doing this rendering price_scenarios index and it works fine. Also, this method is succesfully used in many other views of the app. I think it must be a problem with format responses, due to call the method from a popup, but everything I've tried haven't improved the results.


product show.html.haml a button displaying price_scenarios index as a modal popup:



%h3
= model_class.human_attribute_name(:price)
= link_to PriceScenario.model_name.human(count: 2), formula_product_price_scenarios_path(@formula, @product), remote: true, data: {toggle: "modal", target: "#price_scenarios"}, class: "btn"

#price_scenarios(class="modal hide fade" role="dialog" aria-labelledby="Delta" aria-hidden="true")


price_scenarios_controller.rb definition of index and price methods



class PriceScenariosController < ApplicationController
before_filter :require_client
load_and_authorize_resource :formula
load_and_authorize_resource :product, :through => :formula
before_filter :get_tuple, only: :price

def index
@price_scenarios = @product.price_scenarios
respond_to :js
end

def price
@price_scenario = PriceScenario.find(params[:id])
@price = @price_scenario.shifted_price(@tuple)
@price_units = @product.price_units

respond_to do |format|
format.html { render partial: 'price'}
format.json { render json: {price: @price, units: @price_units}}
end
end


price_scenario index.js.haml view renders index view in the modal:



$("#price_scenarios").html("#{escape_javascript(render partial: 'modal_price_scenarios')}");


_modal_price_scenarios.html.haml view rendered in the modal, "price" is called within it.



#modal_price_scenarios(class="modal" role="dialog" aria-labelledby="Delta" aria-hidden="true")

- model_class = PriceScenario

.modal-body
%table.table.table-striped
%thead
%tr
%th= model_class.model_name.human
%th= model_class.human_attribute_name(:price)
%th= model_class.human_attribute_name(:references)
%tbody
- @price_scenarios.each do |scenario|
%tr
%td= scenario.name
%td.price{:"data-product-price" => price_formula_product_price_scenario_path(@formula, @product, scenario)}
= image_tag('ajax-loader.gif')


-Price.html.haml partial rendered by price_scenarios price method.



= "#{@price} #{@price_units}"


product_price.js



$(function(){
$('[data-product-price]').each(function(){
var url = $(this).data('product-price')
$.ajax({
url: url,
cache: false,
dataType: "json"
}).done(function( data ) {
var priceWithUnits = data['price'] + ' ' + data['units']
$('[data-product-price="' + url + '"]').html(priceWithUnits);
});
});
});

Aucun commentaire:

Enregistrer un commentaire