1

I have a form that the user will use to enter in the title of a book, that I will pass into an external book search API, then I want to display the book results right underneath without reloading the page.

new.html.haml

(the form to enter the title)

= form_tag book_search_path, :method => :get, :remote => true do
    = label_tag "Title: (#{@title})"
    = text_field_tag "title", ""
    = submit_tag "Search!"

#results // results should be updated here

books_controller.rb

(book_search_path goes here, to the 'search' action)

class BooksController < ApplicationController

def index
    @books = Book.find :all
    render :action => 'list'
end 

def new 
    @books = Book.find :all
end 

def search
    Rails.logger.info("DOSEARCH!!!")
    # HIT THE API
    @results = search_keywords params[:title]
    # implicit render search.js.erb
end

search.js.erb

(gets rendered at the end of the books#search action)

m = $('#results');    
m.innerHTML = "<%= escape_javascript(render :partial => 'results.html.haml') %>";

_results.html.haml

(this is what I want to be inserted into the results div via ajax)

- @results.each do |b| 
  %tr 
    %td 
      - Rails.logger.info("Got title...#{b.title}")
      = b.title
    %td 
      = b.isbn

I know that _results.html.haml is getting run, since I see the "Got title" logs, but it is not showing up on the new.html.haml inside the results div. Any idea what's going on?

EDIT: updated books_controller. with full code. Book.rb is an empty model, except the :attr_accessible fields

EDIT: Ajax response:

m = $('#results');    
m.innerHTML = "<table id=\'results_table\'>\n  <tbody><\/tbody>\n  <th>Title<\/th>\n  <th>ISBN<\/th>\n  <tr>\n    <td>\n      The Odyssey\n    <\/td>\n    <td>\n      \n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey of Homer\n    <\/td>\n    <td>\n      1604240687\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey\n    <\/td>\n    <td>\n      1613821166\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey of Homer\n    <\/td>\n    <td>\n      1437818080\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      Odyssey\n    <\/td>\n    <td>\n      0872204847\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey (Penguin Classics)\n    <\/td>\n    <td>\n      0143039954\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey: The Fitzgerald Translation\n    <\/td>\n    <td>\n      0374525749\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey\n    <\/td>\n    <td>\n      1613823398\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey\n    <\/td>\n    <td>\n      0763642681\n    <\/td>\n  <\/tr>\n  <tr>\n    <td>\n      The Odyssey (Penguin Classics)\n    <\/td>\n    <td>\n      0140449116\n    <\/td>\n  <\/tr>\n<\/table>\n";

EDIT: this is Rails 3.2.8

prusswan
  • 6,853
  • 4
  • 40
  • 61
Tim
  • 6,079
  • 8
  • 35
  • 41
  • It looks like all the pieces are there. What exactly happens in the DOM? Are there NO changes, unexpected changes, an error code in the response, or NO response (in the browser's dev tools)? – jefflunt Sep 07 '12 at 22:11
  • @normalocity No changes in the DOM. The Chrome dev tool inspector shows that the 'search' request actually went through when I clicked the "Search!" button, but the page itself isn't changing. The rails log shows _results.html.haml executing, but when I view source after clicking the button, the "response" div remains empty. – Tim Sep 07 '12 at 22:15
  • Would help to post the full model and controller as well. – prusswan Sep 07 '12 at 22:30
  • @prusswan I added the full Book controller and model, but I'm not even doing any ActiveRecord saving at this point; just querying an external API with the user's parameters. In fact, the Book model is empty except for its :attr_accessible line. – Tim Sep 07 '12 at 22:36
  • Reason for having the model/controller is that sometimes there are unusual model definitions and filters used which can lead to unintended results – prusswan Sep 07 '12 at 22:43
  • @prusswan I see. In this case, my controller and model (as you can see above) are rather bare. – Tim Sep 07 '12 at 22:45
  • If the request "went through" then there must be something in the "response" tab - even if it's just blank. It should be JavaScript though if things are working. If the response doesn't contain JavaScript then you know that the response is broken as opposed to the JavaScript being there but being wrong. Also, make sure you don't have any syntax errors in your JavaScript - if so it can come back in the response, hit a syntax error, and basically fail silently. – jefflunt Sep 07 '12 at 22:57
  • @normalocity There is indeed something in the "response" tab: m = $('#results'); m.innerHTML = "
    – Tim Sep 07 '12 at 23:06
  • btw, which version of rails is this? – prusswan Sep 07 '12 at 23:14

1 Answers1

2

Try adding the following block to your search action:

respond_to do |format|
  format.js
end

Also, replace the line in search.js.erb to look like:

$('#results').html("<%= escape_javascript(render :partial => 'results') %>");

Update:

It looks like the real problem (assuming there are no other syntax issues) is that innerHTML is not supported by all browsers (See this)

Community
  • 1
  • 1
prusswan
  • 6,853
  • 4
  • 40
  • 61
  • I did both of these and unfortunately, didn't work. If it's useful, I added an example of the ajax response in the original question. – Tim Sep 07 '12 at 23:11
  • @Tim I have updated the answer considering http://stackoverflow.com/questions/8797692/how-to-render-the-ajax-response-in-rails – prusswan Sep 07 '12 at 23:19
  • shouldn't the js.erb be (note the extra quotes inside html()): `$('#results').html("<%= escape_javascript(render :partial => "results.html.haml") %>");` EDIT: this worked! the API was actually just being slow. Thanks @prusswan! PS: why do I need the respond_to block? – Tim Sep 07 '12 at 23:22
  • I removed the respond_to block (only retaining your second suggestion) and it seems to still work. I'm not sure why this is the case. – Tim Sep 07 '12 at 23:28