I'm following https://github.com/amatsuda/kaminari_example/commits/ajax. I'm using kaminari 0.12.4. (I had check with 0.13.0 and and does not work). Without ajax does works fine.
I have in users_helper.rb
module UsersHelper
def link_to_next_page(scope, name, options = {}, &block)
param_name = options.delete(:param_name) || Kaminari.config.param_name
link_to_unless scope.last_page?, name, {param_name => (scope.current_page + 1)}, options.merge(:rel => 'next') do
block.call if block
end
end
end
I have in my users_controller the next method:
def followers
#user = User.find(params[:user])
#followers = #user.followers_by_type("user")
#followers = Kaminari.paginate_array(#followers).page(params[:page]).per(1)
respond_to do |format|
format.js
format.html { render :layout => 'panel'}# followers.html.erb
format.json { render json: #followers }
end
I have in my follower.index.html.erb the next:
<%= render 'followers' %>
<div id="paginator">
<%= link_to_next_page #followers, 'Next Page', :remote => true, :url => { :controller => "users", :action => "followers"} do %>
<span>No More Pages</span>
<% end %>
</div>
I have in partial _followers.html.erb
<% for followers in #followers%>
<div class="followers">
<%= followers.username %>
</div>
<% end %>
I have in followers.js.erb
//$('#box').html('<%= escape_javascript render(:partial => 'followers') %>');
//$('#box #paginator').html('<%= escape_javascript(paginate(#followers, :remote => true).to_s) %>');
alert ('I am follower.js.erb file');
I have to see a one alert but not seen. Where is the alert? :O. The file index.js.erb does not gets nothing. Where is the problem?
In my log appear working fine the js.erb:
Started GET "/maserranocaceres/followers?page=2" for 127.0.0.1 at 2012-01-31 05:26:44 -0800
Processing by UsersController#followers as JS
Parameters: {"page"=>"2", "user_id"=>"maserranocaceres"}
Rendered users/_followers.html.erb (1.1ms)
Rendered users/followers.html.erb (28.7ms)
Completed 200 OK in 38ms (Views: 34.5ms | Solr: 0.0ms)
it might sound a silly suggestion, but i have had issues like this in the past where changing the order of the formats helps, try:
respond_to do |format|
format.html { render :layout => 'panel'}# followers.html.erb
format.json { render json: #followers }
format.js
end
Related
I'm having trouble rendering a particle on a button click. I'm getting the error
HelpController#FAQ_help is missing a template for this request format
and variant. request.formats: ["text/html"] request.variant: []
main_page.html.erb
<%= link_to "FAQ", FAQ_help_path %>
<div id="content">
</div>
help_controller.rb
def FAQ_help
respond_to do |format|
format.html {}
format.js
end
end
FAQ_help.js.erb
$('#content').html("<%= render :partial => 'FAQ_help' %>");
_FAQ_help.html.erb
<div>
<h1> This is the FAQ </h1>
</div>
routes.rb
get 'FAQ_help', to: 'help#FAQ_help'
How about this:
# main_page.html.erb
<%= link_to "FAQ", FAQ_help_path, remote: true %>
And
# faq_help.js.erb
$('#content').html("<%= escape_javascript(render :partial => 'FAQ_help')%>")
#fixed syntax
Cheers!
Since you have created a method for this request I would define it a little more for clarity:
def FAQ_help
respond_to do |format|
format.html {}
format.js {render: FAQ_help}
end
end
If you want to keep your controllers clean I would pass a param with the link and check if the pram is present if it is render FAQ partial:
View:
<link_to "Your FAQ" your_path, data: {method: :get, :remote => true, params: { faq: "#{current.user_name}" }.to_param }, :class =>"button" %>
Controller:
if params[:faq].present?
respond_to do |format|
format.html {}
format.js {render: FAQ_help}
end
else
respond_to do |format|
format.html {}
format.js {} #your default view for this method
end
end
This is handy to display IE:different content as per the request
ie: parms =bob # displays bobs FAQ
ie: parms =ted # displays teds FAQ
This technique is similar to what you would implement to create a search.
Hi I am currently making an app with users, albums, and photos. I managed to make the AJAX work for the create action when I upload pics, but I can't get AJAX to work for the delete. Instead, it redirects me to an empty show page for the pic. Can anyone give me some guidance?
photos controller:
def destroy
#user = User.find(params[:user_id])
#album = #user.albums.find(params[:album_id])
#photo = #album.photos.find(params[:id])
# #photo.destroy
flash[:success] = "Photo successfully deleted."
respond_to do |format|
if #photo.destroy
format.js
# format.json { render json: #photo, status: :created, location: #photo}
# redirect_to user_album_path(#user, #album)
end
end
end
destroy.js.erb (I'm supposed to have this right?)
$('.destroypicswrapper').remove(".<%= #photo.avatar.url %>");
_photodestroy.html.erb partial:
<div class="picthumb <%= photo.avatar.url %>">
<%= link_to image_tag(photo.avatar.url ? photo.avatar.url(:small) : #album.name), root_url %>
<br>
<%= link_to "Delete", user_album_photo_path(#user, #album, photo), :remote => true, method: :delete, data: { confirm: "Are you sure? "} %>
</div>
and finally the albums/edit.html.erb page where the delete is initially happening:
<% provide(:title, "Edit album") %>
<%= render 'form' %>
<div class="destroypicswrapper">
<% if #album.photos.any? %>
<%= render :partial => 'photodestroy', :collection => #album.photos, :as => :photo %>
<% end %>
</div>
I don't think you want to render the full url of an image as a class of a div. Also, your Jquery is wrong. Try something like this:
destroy.js.erb
$('.destroypicswrapper > #photo_<%= #photo.id %>').remove();
Adjust your _photodestroy.html.erb to:
<div class="picthumb" id="photo_<%= photo.id %>">
I have a page called /add that you can add a Dog on and the form is in its own partial. I'm using Simple Form and Twitter Bootstrap. I added the files for the main Bootstrap but use a gem for simple_form to work with it just so you know.
DogsController
# new.js.erb (deleted new.html.erb)
def new
#dog = Dog.new
respond_to do |format|
format.js
end
end
# create.js.erb
def create
#dog = current_user.dogs.new(params[:dog])
respond_to do |format|
if #dog.save
format.html { redirect_to add_url, notice: 'Dog was successfully added.' }
format.json { render json: #dog, status: :created, location: #dog}
format.js
else
format.html { render 'pages/add' }
format.json { render json: #dog.errors, status: :unprocessable_entity }
end
end
end
dogs/_form.html.erb
<%= simple_form_for(#dog, :remote => true) do |f| %>
<%= render :partial => "shared/error_message", :locals => { :f => f } %>
<%= f.input :name %>
<%= f.button :submit, 'Done' %>
<% end %>
This line: <%= render :partial => "shared/error_message", :locals => { :f => f } %>
Is for bootstrap so it renders the errors html correctly.
PagesController
def add
respond_to do |format|
format.html
end
end
pages/add.html.erb
<div id="generate-form">
</div>
dogs/new.js.erb
$("#generate-form").html("<%= escape_javascript(render(:partial => 'dogs/form', locals: { dog: #dog })) %>");
Now how would I get this to render the error partial as if it was still on my dogs/new.html.erb since its being created through AJAX? I don't need client side validations do I?
EDIT
shared/_error_message.html.erb
<% if f.error_notification %>
<div class="alert alert-error fade in">
<a class="close" data-dismiss="alert" href="#">×</a>
<%= f.error_notification %>
</div>
<% end %>
Through our chat you mentioned you also had a create.js.erb and that file was clearing out the form.
making the the create.js the same as new.js.erb :
$("#generate-form").html("<%= escape_javascript(render(:partial => 'dogs/form', locals: { dog: #dog })) %>");
made it work.
You don't have to do client side validations. But should,it is common to disable the submit button via js until client side validation is met.
also I would not delete the new.html.erb incase a client doesn't.have js turned on.
I think your add may need format.js to your add and
remote = true to your shared errors partial call
I am new to rails and trying to limit the number of comments displayed on my Posts Index Page to 2.
Below is my posts_controller:
class PostsController < ApplicationController
before_filter :authorize, :except => [:index, :show]
# GET /posts
# GET /posts.xml
def index
#posts = Post.all(:include => :comments, :order => "created_at DESC")
#comments = Comment.find(:all, :order => "created_at DESC", :limit => 1)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to(#post, :notice => 'Post was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
end
Below is my Post model
class Post < ActiveRecord::Base
has_attached_file :photo, :styles
=> { :medium => "600x600>", :thumb => "100x100>" },
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => "/:attachment/:id/:style/:filename"
has_many :comments
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
end
Below is my posts index view
<table>
<tr>
<th>BoxScore</th>
<th>Content</th>
</tr>
</table>
<% #posts.each do |post| %>
<%= image_tag post.photo.url(:medium), :class =>"floatleft" %>
<p>
<%= post.content %>
</p>
<div class="comments center">
<h3>Comments:</h3>
<%= render :partial => post.comments.reverse %>
<div class="links">
<% if admin? %>
<%= link_to "New Post", new_post_path %>
<%= link_to 'Edit', edit_post_path(post) %>
<%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %>
<% end %>
<%= link_to 'Comment on the Game', post %>
</div>
</div>
<% end %>
</div>
Comments Partial Below
<% div_for comment do %>
<p>
<strong>Posted <%= time_ago_in_words(comment.created_at) %> ago
</strong>
by
<br/>
<%= h(comment.commenter) %>
<br/>
<%= h(comment.body) %>
<br/>
<%= link_to 'More Comments', comment.post %>
</p>
<% end %>
I am not getting an error message, I just don't know how to limit the amount of comments we are rendering on Posts index page. Thanks
You can't specify conditions on eager loaded associations, unfortunately. Likewise, you can't limit the number of rows returned based on a condition (to my knowledge, though there are a lot of things I don't know about SQL functions).
So you're stuck with either:
Load all of the comments for the posts you're displaying in a query, and limit the number shown in your application.
Load only 2 comments for each of the posts you're displaying individually.
The optimal solution depends on your use case. If you're expecting to show only 5 posts and have thousands of comments on each, option 1 might not be very performant and option 2 might be a good solution. If you are expecting to show more posts per page and have only a handful of comments on any one (the more likely scenario), the first option is going to be your best bet.
Option 1
# controller
#posts = Post.limit(20).all
#comments = Comment.find(#posts.collect &:id).group_by &:post_id
# view
<% #comments[#post.id].first(2).each do |comment| %>
...
<% end %>
Option 2
# controller
#posts = Post.limit(5).all
# view
<% post.comments.limit(2).each do |comment| %>
Ok...I am new to rails so this may be a stupid question but need help. I just watched and implemented Ryan Bates screencaset about setting up a blog. You can see it here http://media.rubyonrails.org/video/rails_blog_2.mov. Here is the skinny:
Two tables: Posts and Comments. Everything works great including the addition of comments via AJAX. The default development of this blog gives you the index.html.erb view where you can view all the posts
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
The comments are only viewed via the show.html.erb page and is displayed via this code in that file:
<%= render :partial => #post %>
<p>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Destroy', #post, :method => :delete, :confirm => "Are You Sure" %> |
<%= link_to 'See All Posts', posts_path %>
</p>
<h2>Comments</h2>
<div id="comments">
<%= render :partial => #post.comments %>
</div>
<% remote_form_for [#post, Comment.new] do |f| %>
<p>
<%= f.label :body, "New Comment" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add Comment"%></p>
<% end %>
What I am trying to do is to get similair representation of the comments functionality to exist in the index.html.erb view (which I will hide with javascript). Which currently just looks like this:
<h1>Listing posts</h1>
<%= render :partial => #posts %>
<%= link_to 'New post', new_post_path %>
My initial thought was just to put this exact same code that is in the show.html.erb file in the index.html.erb file but that doesn't work. I have tried a bunch of things here but I am not familiar enough with Rails (or coding for that matter) yet to do this in a timely manner. I get two main errors. Either that I passed a nil.comments error or an undefined object/method (can't remember).
My question is what do I need to included in the post_controller, the comments_controller and the index.html.erb file to accomplish this. To be complete I have included the code in each below.
POSTS_CONTROLLER
class PostsController < ApplicationController
before_filter :authenticate, :except => [:index, :show]
# GET /posts
# GET /posts.xml
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to(#post) }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to(#post) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
private
def authenticate
authenticate_or_request_with_http_basic do |name, password|
name == "admin" && password == "secret"
end
end
end
COMMENTS_CONTROLLER
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create!(params[:comment])
respond_to do |format|
format.html { redirect_to #post}
format.js
end
end
end
INDEX.HTML.ERB
<h1>Listing posts</h1>
<%= render :partial => #posts %>
<%= link_to 'New post', new_post_path %>
Here's one simple solution. Step 1, edit your index action to include all the comments belonging to each post.
def index
#posts = Post.all(:include => :comments)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
Step 2, edit your index view to display each post, followed by its comments:
<h1>Listing posts</h1>
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => post.comments %>
<% end %>
<%= link_to 'New post', new_post_path %>
Edit: I'm not 100% sure of the best way to include the comment creation form also. What I'd try first is this (in index.html.erb):
Try changing your index view to:
<h1>Listing posts</h1>
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => post.comments %>
<% remote_form_for [post, Comment.new] do |f| %>
<p>
<%= f.label :body, "New Comment" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add Comment"%></p>
<% end %>
<% end %>
<%= link_to 'New post', new_post_path %>
This should render the "New comment" form for a given post under the comments for that post, but I'm not sure (without actually trying it out) whether the form submission AJAX will successfully update and refresh the index page.