Want to have a partial update with ajax - ruby-on-rails

I have a form:
<% form_tag({:controller => "/faq", :action => 'search_ajax'}, :update => "help_results", remote: true) do %>
that is going to the search_ajax action which is supposed to update the help_results div. That action is supposed to render a partial at the end, but I for sure am having syntax issues:
def search_ajax
#categories = HelpCategory.find(:all)
if params[:query].not_blank? && params[:query] != "Search for help about..."
#query = params[:query]
#terms = params[:query].split.map {|t| "%#{t.downcase}%" }
options = {
:allow_partial_match => true,
:order => 'fulltext_match_score DESC',
}
#results = SearchableText.search_model(HelpItem, #query, options).uniq
#results = {"Search Results" => #results} if !#results.blank?
#complicated_query = HelpItem.is_complicated_query?(#query)
#search_included = true
else
#results = HelpItem.all.group_by {|item| item.category.name rescue "Misc"}
#search_included = false
end
render :partial => "results"
respond_to do |format|
format.js do
render :partial => 'results'
end
format.html do
render :partial => 'results'
end
end
end
Some of the respond_to area is commented out. I am getting the error message:
ActionController::DoubleRenderError in FaqController#search_ajax
I know that if I add the remote => true helper into my form that the controller action needs to respond to js. I'm pretty sure this is a syntax error. The respond_to also comes at the end of my controller action.

Remove the
render :partial => "results"
Above the respond_to block

Related

how to select database value based on most common field using rails

def selected
#enquiries = Enquiry.all
#enquiry_details = EnquiryDetail.all
#comments = Comment.all
#enquiries.where("created_at >= ? AND created_at <= ?", Time.zone.now.beginning_of_day, Time.zone.now.end_of_day)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #enquiries and #enquiry_details and #comments }
end
end
How to call this method in my view.
<%= link_to '<button type="button">SELECT</button>'.html_safe, method: :selected %>
Create a route for the action selected and then do this;
<%= button_to "SELECT", { :controller => "CONTROLLER", :action => "selected"} %>

rails render is not working in create action

In my controller I coded like this
class CompanyUploadRequestsController < ApiController
def index
respond_to do |format|
format.html { render action: "index" }
end
end
def create
puts params
respond_to do |format|
format.html { render action: "index" }
end
end
def new
end
end
and in my view new.html.haml file
- page_title("Upload Company")
%h1 Upload Company
%hr
#upload-form
= simple_form_for(#company_upload, :as => :company_update, :url => company_upload_requests_path(#company_upload), :html => { :class => 'file-style'}) do |f|
= f.error_notification
.form-inputs
= f.input :requestname, :label => false, :id => "request_name_input"
= f.input :file,:as => :file, :label => false, :id => "file_select_input"
.form-actions
!= link_to 'Cancel', company_upload_requests_path, :class => 'btn'
= f.button :submit, 'Upload', :class => 'btn-primary'
In my index.html.haml file I have this
- page_title("Upload Company")
%h1 Company index
= link_to("Upload File", new_company_upload_request_path, :class => "btn btn-primary pull-right")
The problem is when I click upload button its not render to index page from create
Here I got the log like this
Processing by CompanyUploadRequestsController#create as HTML
Parameters: {"utf8"=>"?", "authenticity_token"=>"oygIP62E4GHefhN9OnvB3sKhddIb4CN/izfvF5GQtuI=", "company_update"=>{"requestname"=>""}, "commit"=>"Upload"}
Rendered company_upload_requests/create.html.haml within layouts/application (9.8ms)
How can I render to index action and view index file content.
Use like this.
def index
#company_uploads = ModelName.all
respond_to do |format|
format.html
end
end
No need to render index action in index response.
def create
puts params
respond_to do |format|
format.html { render "index" }
end
end
Change the render in your create method to redirect_to
def create
puts params
respond_to do |format|
format.html { redirect_to action: "index" }
end
end
For more explanation on render vs redirect_to, see this SO Question or this.

update database on click

hi i am trying to update a value within my database (PostgreSQL) when a user clicks a certain link, though what i have is working, i dont think its best practice. if anyone can show how i could better achieve this would be great
view
%ul.button-group.round.even-3
%li= link_to '<i class="general foundicon-checkmark"></i>'.html_safe, accept_availability_path(a), :method => 'put', :remote => true, :class => 'button success tiny', :id => a.id, :disable_with => ''
controller
def accept
#availability = Availability.find(params[:id])
#availability.available= true
respond_to do |format|
if #availability.update_attributes(params[:availability])
format.html { render :nothing => true }
format.js
else
format.html { render :action => "edit" }
format.js
end
end
end
routes
resources :availabilities do
put 'accept', :on => :member
put 'decline', :on => :member
end
There's nothing particularly wrong with what you're doing. Your controller doesn't need to use update_attributes, you aren't passing any attributes into it. You can just save it with the change to .available
def accept
#availability = Availability.find(params[:id])
#availability.available = true
respond_to do |format|
if #availability.save
format.html { render :nothing => true }
format.js
else
format.html { render :action => "edit" }
format.js
end
end
end
You could neaten your routes like so:
resources :availabilities do
member do
put :accept
put :decline
end
end

How to render two paginated and ajaxable collections in the same view?

In a Rails 3.2 index view I am rendering two partials.
<%= render :partial => 'users/user', :locals => {:users => #happy_users} %>
<%= render :partial => 'users/user', :locals => {:users => #sad_users} %>
and in the partial
<% users.each do |user| %>
Show some fields
<% end %>
<%= will_paginate users %>
The pagination is not working.
If I alter will_paginate to take an instance variable, pagination works (but the wrong collection)
<%= will_paginate #users %>
How can I pass locals to will_paginate when the partial is called?
(I realize that I'll also need to pass :param_name to get this working with two collections. For now I'm just trying to get one instance working.)
The partial is rendered via index.js.erb
$(".ajaxable-users").html('<%= escape_javascript(render("users/user")) %>');
And the controller looks like
def index
#users = User.scoped.paginate(:page => params[:page], :per_page => 5)
#happy_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5)
#sad_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
format.json { render :json => #users }
format.js
end
end
Thanks for any ideas.
you need to make sure the controller knows which page link of which listing you press. we do this by passing a param to will_paginate page link generator.
you need to make sure your js updates the correct html tag when refreshing the pagination of either listing. we do this by wrapping the pagination in a mood-dependent :) div tag.
since we share the partial we need to make sure mood as well as correct collection is set in controller and passed to partial as local from index views (both html and js).
finally make sure your ajax remote picks up after you redraw pagination (this is a bonus)
so, to set controller instance vars depending on request mood parameter
note that this code also spares you some db calls, since if you just pagintae sad users you do not need to retrieve happy ones or all).
I ommit #users for simplicity, its never used
I suspect happy scope for sad users is only a typo
.
# controller
def index
#mood = params[:mood]
#mood_users = #happy_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5) if #mood.blank? || #mood == 'happy'
#mood_users = #sad_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5) if #mood.blank? || #mood == 'sad'
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
format.json { render :json => #users }
format.js
end
end
make sure we dispatch the right locals to partials:
# index.html.erb
<%= render :partial => 'users/user', :locals => {:users => #happy_users, :mood => 'happy' } %>
<%= render :partial => 'users/user', :locals => {:users => #sad_users, :mood => 'sad' } %>
make partial mood sensitive allowing for distinct div tag id. also put mood in request url.
# users/user partial
<div id='<%= "#{mood || ''}users"%>'>
<% users.each do |user| %>
Show some fields
<% end %>
<%= will_paginate users, :params => { :mood => mood } %>
</div>
this js allows for refreshing different collections in different divs depending on which pagination link was pressed.
# index.js.erb
$("#<%= #mood %>users").html('
<%= escape_javascript(render(partial: "users/user", locals: { users: #mood_users, mood: #mood })) %>
');
For unobtrusive ajax links for pagination you need.
Ruby - Rails 3 - AJAXinate Paginate and sorting
# in a generic js
$(document).ready(function () {
$(".pagination").find("a").livequery(function () {
$(this).attr("data-remote", true);
});
});
Note that the solution should even work if javascript is not enabled and we fall back on html. In this case both sections should be redisplayed allowing for different pages.
MODIFIED CODE TO ALSO HANDLE GRACEFUL JS FALLBACK TO HTML
controller
# controller
def index
#mood = params[:mood]
#happy_page = #mood == 'happy' ? params[:page] : params[:happy_page]
#sad_page = #mood == 'sad' ? params[:page] : params[:sad_page]
#mood_users = #happy_users = User.happy_scope.paginate(:page => #happy_page, :per_page => 5) if !request.xhr? || #mood == 'happy'
#mood_users = #sad_users = User.happy_scope.paginate(:page => #sad_page, :per_page => 5) if !request.xhr? || #mood == 'sad'
#mood_users = #users = User.scoped.paginate(:page => params[:page], :per_page => 5) if #mood.blank?
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
format.json { render :json => #users }
format.js
end
end
forward new view vars to partial local
# index.html.erb
<%= render :partial => 'users/user', :locals => {:users => #happy_users, :mood => 'happy', :happy_page => #happy_page, :sad_page => #sad_page } %>
<%= render :partial => 'users/user', :locals => {:users => #sad_users, :mood => 'sad', :happy_page => #happy_page, :sad_page => #sad_page } %>
we only need to pass this here to not get undefined method in partial.
# index.js.erb (fixed HTML syntax)
$("#<%= #mood %>users").html('
<%= escape_javascript(render(partial: "users/user", locals: { users: #mood_users, mood: #mood, :happy_page => #happy_page, :sad_page => #sad_page })) %>
');
this will then persist happy pages in param if sad page link is clicked, and vica versa.
# users/user partial
<div id='<%= "#{mood || ''}users"%>'>
<% users.each do |user| %>
Show some fields
<% end %>
<%= will_paginate users, :params => { :mood => mood, :happy_page => happy_page, :sad_page => sad_page %>
</div>
First, create in controller two diferent methods for each list for example fill_list1 and fill_list2 there are independent of method for create the main page for example index
Each list method must render a partial without layout for example
render :partial=>'fill_list1', :layout => false
The main page must call partials in view for first time.
when you click in paginate control you must hack click for call ajax next pagination items list
$('list1 a').live('click', function(event){
event.preventDefault();
$.ajax(
{url:URLFORCALLMETHODLIST,
success: function(content) {
DIVLOCATIONLIST.html(content);
},
async:false,
});
});
Try passing proper locals in the index.html.erb:
$(".ajaxable-users").html('
<%= escape_javascript(render("users/user", locals: { users: #users })) %>
');

Confused as to which Prototype helper to use (updated)

This is a continuation of Confused as to which Prototype helper to use. My code has been updated to reflect other user's suggestions:
(model) message.rb:
class Message < ActiveRecord::Base
after_create :destroy_old_messages
def old_messages
messages = Message.all(:order => 'updated_at DESC')
if messages.size >= 24
return messages[24..-1]
else
return []
end
end
protected # works without protected
def destroy_old_messages
messages = Message.all(:order => 'updated_at DESC')
messages[24..-1].each {|p| p.destroy } if messages.size >= 24
end
end
(view) index.html.erb:
<div id="messages">
<%= render :partial => #messages %>
</div>
<%= render :partial => "message_form" %>
(view) _message.html.erb:
<% div_for message do %>
<%= h message.created_at.strftime("%X") %> - <%= h message.author %><%= h message.message %>
<% end %>
(view) _message_form.html.erb:
<% remote_form_for :message, :url => { :action => "create" }, :html => { :id => 'message_form'} do |f| %>
<%= f.text_area :message, :size => "44x3" %><br />
<%= submit_to_remote 'submit_btn', 'submit', :url => { :action => 'create' } %><br />
<% end %>
(view) create.rjs:
page.insert_html :top, :messages, :partial => #message
page[#message].visual_effect :grow
page[:message_form].reset
flash[:notice]
flash.discard
# #old_messages.each do |m|
# page.remove(m.id)
# end
(controller) messages_controller.rb:
class MessagesController < ApplicationController
def index
#messages = Message.all(:order => "created_at DESC")
respond_to do |format|
format.html
format.js
end
end
def new
#message = Message.new
respond_to do |format|
format.html
end
end
def create
#message = Message.new(params[:message])
# #old_messages = Message.old_messages
respond_to do |format|
if #message.save
flash[:notice] = 'message created.'
format.html { redirect_to(messages_url) }
format.js
else
format.html { render :action => "new" }
end
end
end
def update
#message = Message.find(params[:id])
respond_to do |format|
if #message.update_attributes(params[:message])
flash[:notice] = 'message updated.'
format.html { redirect_to(messages_url) }
format.js
else
format.html { render :action => "edit" }
end
end
end
def destroy
#message = Message.find(params[:id])
#message.destroy
respond_to do |format|
format.html { redirect_to(messages_url) }
format.js
end
end
end
With the exception of the old_messages method in the model, all of the commented code were recommended changes from the previous post to make this work. But as soon as I uncomment the last three lines from create.rjs and #old_messages = Message.old_messages from the controller, I can't even submit messages with the message_form partial. Can anyone see what's wrong here? I'm just trying to create a basic app to help further my understanding of rails and rjs. I would greatly appreciate any suggestions or corrections you have to share, thank you for reading my post.
it's not what you're asking for, but i have a suggestion...
to get the older messages you can use named_scope.
in your case, (if i understood what you want) i think it would be something like:
# model
named_scope :limit, lambda { |num| { :limit => num } }
named_scope :order, lambda { |ord| { :order => ord } }
and
#controller
Message.order("updated_at DESC").limit(24)
the problem is that old_messages is an instance method, and you're calling from a class.
if you do
def self.old_messages
# ...
end
it's now a class method.
this blog has a good explanation about class and instance methods.

Resources