javascriptjqueryruby-on-railsrubylink-to-remote

Ruby on Rails: Open Modal Box Link doesn't work Update: link_to_remote


I want my page to open a Modal Popup Box, so I added this link to my view file:

  <%= link_to_remote '+ Add Discount', :url => {:controller => "parent_wise_fee_payments", :action => "new_instant_discount", :id => @financefee.id, :current_action => @target_action, :current_controller => @target_controller} %>

and in the controller:

def new_instant_discount
    @financefee=FinanceFee.find(params[:id])
    @target_action=params[:current_action]
    @target_controller=params[:current_controller]
    @finance_fee_category=@financefee.finance_fee_collection.fee_category
    respond_to do |format|
      format.js { render :action => 'create_instant_discount' }
    end
  end

Then I created create_instant_discount action and create_instant_dicount.rjs with this code:

page.replace_html 'modal-box', :partial => 'instant_discount_form'
page << "Modalbox.show($('modal-box'),  {title: ''});"

And created the partial view _instant_discount_form that I want to open.

The problem here is that when i click on the link to open the Modal box, nothing happens and no errors appear.

Could you please help me find out what I'm missing?

UPDATE: Link_to_remote Problem

It seems that the problem is in the link_to_remote, because I tried rendering a partial view and it didn't work, I also tried using a direct view but it gave same result. So I don't know why this link isn't working, note that I included it in the controller:

  include LinkPrivilege

  helper_method('link_to','link_to_remote','link_present')

Solution

  • Could you please help me find out what I'm missing?

    If you're not seeing any results, the problem is likely with your client-side JS.

    Rails cannot open the model for you, it has to be appended to the DOM with the returned data from the server. It seems that you're sending the request to the server okay, it's just a case of getting that returned and appended to the DOM.


    Code

    The current code is pretty haphazard, this is what I'd do with what you've provided:

    #app/views/controller/action.js.erb
    $modalbox = $('modal-box');
    $modalbox.html("<%=j render 'instant_discount_form' %>");
    $('body').append(Modalbox.show($modalbox,  {title: ''}));
    

    This may or may not work. There are several dependencies I'd need access to, including your routes, controller and Modalbox code.

    The best way to debug whether a) the request is being fired & b) the request is being processed is to use the developer console and console.log outputs:

    #app/views/controller/action.js.erb
    $modalbox = $('modal-box');
    $modalbox.html("<%=j render 'instant_discount_form' %>");
    $('body').append(Modalbox.show($modalbox,  {title: ''}));
    
    console.log($modalbox); //checks if $('modal-box') is valid
    console.log(Modalbox.show($modalbox,  {title: ''})); // checks if Modal being called correctly.
    

    --

    System

    Your problem is deeper than just not receiving direct returns on your data, you need to appreciate the structure of your code (which is almost there).

    <%= link_to_remote '+ Add Discount', :url => {:controller =>  "parent_wise_fee_payments", :action => "new_instant_discount", :id =>  @financefee.id, :current_action => @target_action, :current_controller => @target_controller} %>
    

    Firstly, your link_to_remote has so many dependent attributes - if you changed just one part of your app, you'd have to change many of these. Rails is heavy on DRY (Don't Repeat Yourself), and as such, calling specifics like controller and action are not advised.

    You're better with one of your routing helpers (specifically, the polymorphic path helper):

    <%= link_to_remote '+ Add Discount', parent_wise_fee_payements_new_instant_discount_path(id: @financefee.id, current_action: @target_action, current_controller: @target_controller) %>
    

    Now, from the ridiculousness of the path helper, I'm sure you can appreciate how you need to be able to resolve some of the deeper issues within the system. Namely, you're being to specific with your controller/actions; it needs to be CRUD for data objects:

    #config/routes.rb 
    resources :finance_fees do
       resources :discounts
    end
    
    #app/controllers/discounts_controller.rb
    class DiscountsController < ApplicationController
       def new
          @finance_fee = FinanceFee.find params[:finance_fee_id]
          @discount = @finance_fee.discounts.new
       end
       def create
          @finance_fee = FinanceFee.find params[:finance_fee_id]
          @discount = @finance_fee.discounts.new create_params          
       end
       private
       def create_params
          params.require(:discount).permit(:x, :y, :z)
       end
    end
    

    The big problem I can see is you're calling new_instant_discount as an action, with a bunch of other highly tuned attributes. Whilst there's nothing wrong with this, it negates one of the core aspects of Ruby/Rails - object orientation.

    You're meant to work with objects inside Rails - IE they are created inside your model, which can be then manipulated in your controller etc...

    Your controller actions seem very sketchy to me.

    --

    In regards your update, link_to_remote appears to be deprecated in favour of the remote RailsUJS functionality:

    <%= link_to "link", link_path, remote: true %>
    

    This will send the data asynchronously to your server, it will not handle a response. If you use the following, it should work:

    <%= link_to '+ Add Discount', :url => {:controller => "parent_wise_fee_payments", :action => "new_instant_discount", :id => @financefee.id, :current_action => @target_action, :current_controller => @target_controller}, remote: true %>