简体   繁体   中英

Displaying dynamic content using javascript and Rails partials

I have a list of movie categories displayed on my home page. Along with this, I have displayed the list of ALL the movies currently available in the db. When the user clicks on one of the categories, I would like to re-render the containing the list of ALL movies to show ONLY the list of movies that belong to the category that the user selected.

I use link_to to display the list of categories. The link_to would be routed to a controller function which loads the movies that belong Only to the category selected by the user. Then a js.erb would be invoked with this generated list which would in-turn invoke a Rails partial.

The Rails partial would re-render the complete movie list to display ONLY the movies that belong to the selected category. The javascript and partial are getting invoked all right but the partial fails to re-render the list. Am not sure what I'm missing here.

app/views/movies/index.html.erb

    <% @categories.each do |category| %>
  <tr><td>


    <%= link_to category, show_category_url(:genre => category), :remote => true %> <%end%>    


    <%if false %>
    <%= link_to show_category_url, :remote => true do %>
     category
    <%end %>

  </td></tr>
<% end %>

<div id="#movies_list">
<% @movies.each do |movie| %>
  <tr>
    <td><%= movie.title %></td>
    <td><%= movie.category %> </td>
    <td><%= movie.rating %></td>

    <% if !current_user.nil? %>
      <% if movie.user.email == current_user.email %>
        <td><%= link_to 'Show', movie, :class => "btn btn-primary"%></td>
        <td><%= link_to 'Edit', edit_movie_path(movie), :class => "btn btn-primary" %></td>
        <td><%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-primary" %></td>
      <% end %>
    <% end %>
  </tr>
<% end %>
</div>


app/views/movies/show.js.erb

$("#movies_list").html("<%= escape_javascript(render("show_category")) %>");

app/views/movies/_show_categories.html.erb

      <% @movies_in_category.each do |movie| %>
    <tr>
      <td><%= movie.title %></td>
      <td><%= movie.rating %></td>
     <% puts "************** movies/show_category"%>
     <% puts movie.title %>
      <% if false %>
      <td>
        <%= form_for @rating do |rating_form| %>
          <%= rating_form.number_field :rating, class: 'rating', 'data-size' => 'xs'%>
          <%= rating_form.submit 'Add', class: 'btn btn-primary btn-success' %>
        <% end %>
      </td>
      <% end %>

      <% if !current_user.nil? %>
        <% if movie.user.email == current_user.email %>
            <td><%= link_to 'Show', movie, :class => "btn btn-primary"%></td>
            <td><%= link_to 'Edit', edit_movie_path(movie), :class => "btn btn-primary" %></td>
            <td><%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-primary" %></td>
        <% end %>
      <% end %>
    </tr>
  <% end%>

My partial is getting invoked all right but the re-rendering of div movies_list does not happen.

This is my controller code:

class MoviesController < ApplicationController
before_action :set_movie, only: [:show, :edit, :update, :destroy]
#before_action :authenticate_user!

# GET /movies
# GET /movies.json
def index
@movies = Movie.all
$all_movies = @movies

@categories = @movies.uniq.pluck(:category)
@movies_by_category = Hash.new

@categories.each do |category|
  @movies_by_category[category] = Movie.where(:category => category).length
end     
end

# GET /movies/1
# GET /movies/1.json
def show
    respond_to do |format|
  format.js {render layout: false}
  puts "@@@@@@@@@@@@@@ moviescontroller/show_category"
end
end

# GET /movies/new
def new
@movie = current_user.movies.new
end

# GET /movies/1/edit
def edit
end

# POST /movies
# POST /movies.json
def create
@movie = current_user.movies.new(movie_params)

respond_to do |format|
  if @movie.save
    format.html { redirect_to @movie, notice: 'Movie was successfully created.' }
    format.json { render :show, status: :created, location: @movie }
  else
    format.html { render :new }
    format.json { render json: @movie.errors, status: :unprocessable_entity }
  end
end
end

# PATCH/PUT /movies/1
# PATCH/PUT /movies/1.json
def update
respond_to do |format|
  if @movie.update(movie_params)
    format.html { redirect_to @movie, notice: 'Movie was successfully updated.' }
    format.json { render :show, status: :ok, location: @movie }
  else
    format.html { render :edit }
    format.json { render json: @movie.errors, status: :unprocessable_entity }
  end
end
end

# DELETE /movies/1
# DELETE /movies/1.json
def destroy
@movie.destroy
respond_to do |format|
  format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
  format.json { head :no_content }
end
end

def show_category
category_selected = params[:genre]
#all_movies = Movie.all
@movies_in_category = Movie.where(category: category_selected)
puts "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
puts category_selected
puts @movies_in_category.length
end

def login
end

private
# Use callbacks to share common setup or constraints between actions.
def set_movie
  @movie = Movie.find(params[:id])     
end

# Never trust parameters from the scary internet, only allow the white list through.
def movie_params
  params.require(:movie).permit(:title, :category, :rating)
end
end

The reason is,

<div id="#movies_list">
contents goes here..
</div>

You shouldn't add # when defining id attribute for an element, That will be used when selecting an HTML element based on the selector. So remove #

<div id="movies_list">
contents goes here..
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM