Jackson Cunningham
Jackson Cunningham

Reputation: 5073

Rails: Simple Ajax post to filter index results

I have a checkbox on my trailers index page that, when checked, should filter the results.

trailers_controller:

class TrailersController < ApplicationController
  respond_to :html, :js

  def index
    trailers = Trailer.last(40).sort_by(&:published_at).reverse
    trailers = trailers.select { |t| t.budget == "blockbuster" } if params[:show_indie] && params[:show_indie] == "false"
    @trailers = Kaminari.paginate_array(trailers).page(params[:page]).per(6)
  end    
end

And my view:

<div class="trailers">
  <%= render @trailers %>
</div>

And my js:

<script>
$(function(){

  $('.checkbox-inline').on('change', function() {
    var show_indie = $(this).find('input').prop('checked')

      $.ajax({
        url: '/trailers/filter',
        type: "post",
        async:true,
        dataType: "html",
        data: {show_indie},
        success: function() {
          console.log ("filtered")
        },
        error: function(){
          console.log ("error with ajax")
        }

    });

    })


});

</script>

routes:

  post 'trailers/filter' => 'trailers#index'

And my index.js.erb:

console.log('index js loaded')

$('.trailers').html("<%= escape_javascript render(@trailers) %>");

Everything seems to work, the AJAX is posting okay. But the index.js.erb is not rendering. I have a feeling it's because my dataType is "html" instead of JSON or something.. But not really sure how that works, or how to fix it.

  1. What am I doing wrong?
  2. Is this the best way to handle this kind of filtering?

Upvotes: 0

Views: 831

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

To add to the answer, you need to remember not to store your javascript in your views directly. To make your application run efficiently & properly, you need to use the unobtrusive javascript pattern:

#app/assets/javascripts/application.js
$(document).on('change', '.checkbox-inline', function() {
    var show_indie = $(this).find('input').prop('checked')

      $.ajax({
        url: '/trailers/filter',
        type: "post",
        dataType: "script",
        data: {show_indie},
        success: function() {
          console.log ("filtered")
        },
        error: function(){
          console.log ("error with ajax")
        }

    });

});

This will not only free up your views, but also allow you to factor the JS into your asset pipeline, making it more efficient.

Upvotes: 0

Alexei.B
Alexei.B

Reputation: 322

You need to specify dataType as "script"

$.ajax({
  method: "GET",
  url: "test.js",
  dataType: "script"
});

Upvotes: 3

Related Questions