euisblue
[RoR] Updating a section with AJAX
Learn how to render section of a page using AJAX  

    I was implementing a search feature for my toy-project. The logic itself was simple enough.

    1search_value = FROM_THE_SEARCH_INPUT 2posts = Post.all.select{ |post| post.include? search_value }

    From here, however, I didin't know how to render the page to show filtered posts. I can redirect the page but who wants to use a page that refreshes every time when you search something?

    I figured AJAX (asynchronous javascript and xml) is what I need.


    First, I'm going to modify my search.js file in /app/javascript/packs/ to call ajax.

    1/* file: /app/javascript/packs/search.js */ 2 3document.addEventListener("turbolinks:load", function() { 4 $(".search-input").on('change', (e) => { 5 const param = (e.target.value).trimStart().trimEnd(); 6 const URL = "/index/" + encodeURIComponent(param); 7 8 $.ajax({ 9 url: URL, 10 success: function(data) { 11 console.log('success') 12 error: function() { 13 console.log('failure') 14 } 15 }); 16 }) 17});

    param contains the value from the search input, and I'm going to send this value as a query parameter to the route /index/:search. Then from the controller I can use params[:search] to access this value.


    We need to tell our controller to respond to javascript with the partial that we're going to update the section. Since I'll be updating a section from the index, I'll modify the index action.

    1def index 2 @posts = Post.all.order(id: desc) 3 4 if params[:search] 5 @posts = Post.all.order(id: :desc).select{ |post| post.title.downcase.include? params[:search].downcase} 6 end 7 8 respond_to do |format| 9 format.js { render layout: false } 10 format.html { render 'index' } 11 end 12end

    Line #4 determines whether the page should display all posts or only those from the search results.


    I need to create {action_name}.js.erb (index.js.erb in my case) in the view folder where my partial exists.

    1$('ul[role="list"]').html("<%= j (render partial: 'post/index', :locals => {:posts => @posts}) %>")

    And voilà!

    Ajax rendering demo

    Now whenever I search for a value, it will make an AJAX call to /index/:search with a search value, and the controller will call index.js.erb to render the specific section of a page without refreshing it.

    Reference