0

I currently have a controller which produces a report. This is the controller:

def last5days

    #@monday = (Time.now).at_beginning_of_week

    @monday = (Time.now).months_ago(1)
    #@friday = 5.days.since(@monday)-1.second
    @friday = (Time.now)
    @sent_emails = ContactEmail.all(:conditions => ['date_sent >= ? and date_sent <= ?', @monday, @friday])

    @made_calls = ContactCall.all(:conditions => ['date_sent >= ? and date_sent <= ?', @monday, @friday])

    @letters_sent = ContactLetter.all(:conditions => ['date_sent >= ? and date_sent <= ?', @monday, @friday])

    @contacts_added = Contact.all(:conditions => ['date_entered >= ? and date_entered <= ?', @monday, @friday])

    #@table = ContactEmail.report_table(:all,
     #                                   :conditions => ['date_sent >= ? and date_sent <= ?', @monday, @friday])

    #@grouping = Grouping(@table, :by => "email_id")                                    

  end

Instead of hardcoding monday and friday, I want to have an interface where someone can select the start and end dates, hit submit, and the output gets returned.

I'm having troubling finding an example or knowing exactly what to do.

I started with a new view:

<%= render :partial => 'form' %>


<div id = 'display'>

</div>

I want the output from the controller to be displayed in "display" via Ajax.

I tried to create the form as follows:

<% remote_form_for  do |f| %>

  <p>
    <%= f.label :start_date %><br />
    <%= f.date_select_tag :start_date %>
  </p>
  <p>
    <%= f.label :end_date %><br />
    <%= f.date_select_tag :end_date %>
  </p>
  <p><%= f.submit "Submit" %></p>


 <% end %>

And then my plan was to change the controller to accept params[:start_date] and params[:end_date]

But I don't think I quite know how the pieces fit together to make this work. Guidance? Help?

Here is what I am trying now:

VIEW: find_start_end.html.erg

<% form_tag('return_search') do %>
  <p>
    <label>Start Date</label> <%= date_select('start_date', 'params') %>|
     <label>End Date</label> <%= date_select :end_date, params[:end_date] %>
  </p>
  <p><%= submit_tag "Get Stats" %></p>
<% end %>

CONTROLLER:

def return_search

    @sent_emails = ContactEmail.all(:conditions => ['date_sent >= ? and date_sent <= ?', params[:start_date], params[:end_date]])

    @made_calls = ContactCall.all(:conditions => ['date_sent >= ? and date_sent <= ?', params[:start_date], params[:end_date]])

    @letters_sent = ContactLetter.all(:conditions => ['date_sent >= ? and date_sent <= ?', params[:start_date], params[:end_date]])

    @contacts_added = Contact.all(:conditions => ['date_entered >= ? and date_entered <= ?', params[:start_date], params[:end_date]])

    respond_to do |format|

      format.html #view needs to be the same name as the method

    end 

    def find_start_end

    end
Satchel
  • 16,414
  • 23
  • 106
  • 192

1 Answers1

1

1) Make sure you get a basic HTML version up first 2) Then transfer this to Ajax.

This flow gets everyone on board and keeps logic organized.

All of your logic is correct so I will just give you the code for the HTML version and once you get that up you can get the remote version going.

controller:

 def index
       @start_date = Date.strptime(params[:start_date],"%d/%m/%Y")
       @end_date = Date.strptime(params[:end_date],"%d/%m/%Y")
       @stuffs = Stuff.find(:all, :conditions => ["created_at > ? and updated_at < ?",@start_date, @end_date])
      responds_to do |format|
          format.html #view needs to be the same name as the method
      end 
 end 

view

<% form_tag(stuffs_path, :method => :get) do %>
  <p>
    <label>Start Date</label> <%= datetime_select :start_date, params[:start_date] %> |
     <label>End Date</label> <%= datetime_select :end_date, params[:end_date] %>
  </p>
  <p><%= submit_tag "Get Stats", :disable_with => "Getting stats..." %></p>
<% end %>

routes.rb

you need a line at the top like this:

map.resources :stuffs

Basically what this does is create specific routes. Now you can call stuffs_path and it will go to the index action.

If you are not using REST the search_stuff_path could be :controller => :your_controller => :action => your_action. IF you are using REST you need to add this as a member to your routes.rb in config. If you need more info let me know.

BTW - I used stuffs to be a generic term for your resource. I think what you want would be report so the controller, routes, and views would be reports_path and map.resources :reports respectively.

So now that you got the HTML version going it's easy to get remote going.

controller

def index
    responds_to do |format|
        format.js render :partial => "remote_report"
        # you can use RJS or a partial. 
        # If it's one place you want to update just use a partial.
        # Create a file _remote_report.html.erb as a partial.
        # Put this in the views folder of course
    end 
end 

In your view:

 <div id="div_id_to_update">
 <% remote_form_tag(stuffs_path, :method => :get, :update => "div_id_to_update") do %>
   <p>
     your form methods here
   </p>
   <p>your submit tag here</p>
 <% end %>
 </div>

Those are the parts you need to change to make it remote based.

thenengah
  • 42,557
  • 33
  • 113
  • 157
  • thanks...I *should* be using rest :) but does that mean I create a custom route called search_stuff_path ? – Satchel Aug 14 '10 at 04:25
  • Yeah, if your using rails is more of a pain not to use rest. I didn't use it for a long time because it's a strange concept but once you use it it sticks with rails DRY and Convention over configuration which helps productivity – thenengah Aug 14 '10 at 04:43
  • I will edit the code and be more specific about what needs to be done with rest – thenengah Aug 14 '10 at 04:44
  • Let me know if you have more questions :) – thenengah Aug 14 '10 at 04:47
  • is there a way that I can have the inputs formatted as dates rather than using text_fields? – Satchel Aug 14 '10 at 04:55
  • cool, thanks -- this is what did in the routes: map.connect 'reports/find_start_end', :controller => 'reports', :action => 'find_start_end' is that right? – Satchel Aug 14 '10 at 04:56
  • Yeah, you need to use datetime_select. I will check it out and post what i get. – thenengah Aug 14 '10 at 04:56
  • I don't know exactly how this will work in the controller. I assume it should be OK. If you don't want the datetime_select as a helper then it will be more work but its still possible to create your own datetime_select options. – thenengah Aug 14 '10 at 05:00
  • cool, I used date_select and it looks like it will post the value....so I guess I need to figure out what the controller is to display the actual output – Satchel Aug 14 '10 at 05:03
  • oh wait, i see -- actually the find stuffs is what is posted to...so it posts to itself? – Satchel Aug 14 '10 at 05:06
  • I don't know what you mean. I forgot to put something important in the search form so check that out. – thenengah Aug 14 '10 at 05:13
  • I added the method to the search form this is for http requests and informs the server what you want. Get means find – thenengah Aug 14 '10 at 05:14
  • Hi, why do you wrap the params with #{ }? does that create the string value for the date? – Satchel Aug 14 '10 at 05:14
  • actually you don't need that. You can just do params[:start_date] – thenengah Aug 14 '10 at 05:15
  • okay -- hmmm I am getting a funky sql I have a slight modification from what you have but not significant. Let me post it – Satchel Aug 14 '10 at 05:23
  • it seems like it posts the date as month, day, and year as a hash in params...so I get this: - (2i) - "6" ' and date_sent <= '--- - (3i) - "13" ','--- - (1i) - "2010" ','--- - (2i) - "8" ') ): – Satchel Aug 14 '10 at 05:24
  • ah, date_select passes as multiparameter...but how do you convert multiparameter into something that can be passed into a sql statement for :conditions? – Satchel Aug 14 '10 at 05:30
  • too much work to convert and who needs seconds anyways. Try the code I added and then you will need to create custom drop downs for the dates – thenengah Aug 14 '10 at 05:33
  • yeah I am using date_select instead of datetime...this creates drop-down for the dates which works. The multi-parameter thingy is what's funky...if I could just have a .to_s type method that would fix it...but not sure... – Satchel Aug 14 '10 at 05:42
  • probably gave you lots of error with the last code. The latest might work. – thenengah Aug 14 '10 at 05:44
  • phew! okay, based on what you did, I got something working...not using ajax, but it's working. I used another stackoverflow to help with the multiparameter conversion: http://stackoverflow.com/questions/138496/generating-a-report-by-date-range-in-rails – Satchel Aug 14 '10 at 06:03
  • so...let me post onto a gist the latest of stuff I got...I *think* I am ready to make it work with ajax remote_forms.! – Satchel Aug 14 '10 at 06:04
  • cool, it works as desired as separate html forms (I use post insetad of get): http://gist.github.com/524049 – Satchel Aug 14 '10 at 06:06
  • great! Don't use post though. Post is for creating records. 'get' is for finding records. huge difference – thenengah Aug 14 '10 at 06:12
  • ah, okay, let me add that...tomorrow will tackle the remote_for unless you have a suggestion :) – Satchel Aug 14 '10 at 06:17