Else part is not working in Rails ajax form - ruby

I have a Rails ajax form to submit.When user will give the correct data it will search the database and do the operation accordingly.If user is giving the Wrong data it should display user to alert message.But it is not happening like that.
I am explaining my codes below.
home.html.erb
<% if current_admin %>
<p class="flash-message"><%=flash[:notice]%></p>
<div class="col-md-6" style="float:none; margin:auto;">
<%= form_for :sdf ,:url => {:action => "scan_report" },remote: true do |f| %>
<% if params[:receipt_no] %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :Receipt_No,:class => "form-control", :value => params[:receipt_no] %><%= f.submit "Scan Report" %>
</div>
<% else %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :Receipt_No,:class => "form-control",placeholder:"Receipt No. scan" %><%= f.submit "Scan Report" %>
</div>
<% end %>
<% end %>
<% end %>
controller/homes_contorller.rb
class HomesController < ApplicationController
def home
#sdf=TSdf.new
respond_to do |format|
format.html
format.js
end
end
def scan_report
if #sdf=TSdf.find_by_Receipt_No(params[:sdf][:Receipt_No])
if #sdf && #sdf.HCSY_Status=='YES'
#hcsy=THcsy.find_by_Sdp_Id(#sdf.Sdp_Id)
#hcsy_deatils=THcsyDetails.find_by_HCSY_ID(#hcsy.id)
#woods=THcsyFundTypeMaster.find_by_Fund_Type_Code(1)
#burn=THcsyFundTypeMaster.find_by_Fund_Type_Code(2)
#good=THcsyFundTypeMaster.find_by_Fund_Type_Code(3)
#swd=THcsyFundTypeMaster.find_by_Fund_Type_Code(5)
#photo=THcsyFundTypeMaster.find_by_Fund_Type_Code(6)
end
else
flash[:notice]="Not Found"
end
end
end
In this form its only taking the correct input but if user is trying to give the wrong input the else part is not executing.Please help me to resolve this error and let me to know how can i make this ajax call in below format.
$('form').submit(function() {
var valuesToSubmit = $(this).serialize();
$.ajax({
type: "POST",
url: $(this).attr('action'), //sumbits it to the given url of the form
data: valuesToSubmit,
dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
}).success(function(json){
console.log("success", json);
});
return false; // prevents normal behaviour
});
Please help me.I am using Rails version 3.2.19.

Here you send AJAX POST request to scan_report, and if it is successful it should render template scan_report.js.erb, and rendered template will appear in json variable in success callback.
But if params are not valid, the same template is rendered, but all instance variables are missing. And probably empty json is returned or an error appears in log.
Anyway, if you'd like to change flash in remote form, you should put custom code in fail callback. Something like
$("#flash").html('<%= j render flash[:notice] %>');

Related

Using wicked_pdf, save as pdf including user supplied data

I have a template to be filled out by a user. My goal is to convert the template into a pdf (containing information supplied by the user) using wicked_pdf.
Also, none of the user input is hitting the model/database. I simply need to convert the template to a pdf containing the user's data, nothing more.
So far, I can convert the template to a pdf, save it and redirect back to my index view. However, none of the fields filled in by the user are saved; all fields that were containing input or values typed by the user are blank. It's simply saving a blank template. How can I convert a pdf and user supplied data to a pdf using wicked_pdf?
# controller save method --->
def save_grade_sheet
#result = Result.find(params[:id])
if current_user.admin?
filename = "#{#result.user.last_name}_grades.pdf"
save_path = "#{Rails.root}/public/uploads/#{#result.user.last_name}/#{filename}"
respond_to do |format|
pdf = render_to_string pdf: filename,
template: "/results/grade_sheet.html.erb",
encoding: "UTF-8",
disposition: "attachment",
save_to_file: save_path,
save_only: true
File.open(save_path, "wb") do |file|
file << pdf
end
flash[:notice] = "#{filename} successfully saved"
format.html { redirect_to results_path }
end
else
head :unauthorized
end
end
# sample template code
<div>
<div>
<h2>PERSONNEL INFORMATION</h2>
<p>Examinee's Name: <%= #result.user.first_name %> <%= #result.user.last_name %></p>
<p>Examiner's Name: <input class="inline" type="text"></p>
</div>
<div>
<p>Exam Type: <%= #result.test.upcase %></p>
<p>Exam Version: <input class="inline" type="text"></p>
<p>Exam Date: <%= #result.created_at.strftime("%m-%d-%y") %></p>
</div>
<%= button_to "Create Grade Sheet", save_grade_sheet_result_path(#result), data: { method: :post }, class: "btn btn-primary btn-lg"%>
</div>
I was sending everything to the correct route, but none of the data was actually being passed. Instead, I needed to wrap everything in a form_tag and use a submit_tag.
<%= form_tag(save_grade_sheet_result_path(#result), method: :post) %>
<div>
<h2>PERSONNEL INFORMATION</h2>
<p>Examiner's Name: <%= text_field_tag :examiner_name, #examiner_name, class: "inline" %></p>
<p>Exam Version:<%= text_field_tag :exam_version, #exam_version, class: "inline" %></p>
</div>
<%= submit_tag "Create Grade Sheet", class: "btn btn-primary btn-lg" %>
<% end %>
And in my controller, I needed to grab the params passed in:
def save_grade_sheet
#result = Result.find(params[:id])
#examiner_name = params[:examiner_name]
#exam_version = params[:exam_version]
if current_user.admin?
# existing code
end
end

How to update feed using ajax in Rails 4.0

I am trying to create an ajax functionality for a sample app of michael heart book . I created a feed model controller which is micropost in hear book . I am trying to use ajax like post feed method . But I am getting some error . I am attaching my code below take a look and help me .
#feeds_controller.erb
class FeedsController < ApplicationController
before_action :authenticate_user! ,only: [:create, :destroy]
def create
#feed = current_user.feeds.build(feed_params)
if #feed.save
flash[:success] = "Micropost created!"
#redirect_to root_url
respond_to do |format|
format.html { redirect_to root_url }
format.js
else
#feed_items = []
render 'static_pages/home'
end
end
def destroy
end
private
def feed_params
params.require(:feed).permit(:content)
end
end
And my home page is rendering some partials Here is the code :
#static_pages/home.html.erb
<% if user_signed_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<section class="stats">
<%= render 'shared/stats' %>
</section>
</aside>
<div class="col-md-8">
<h3>Micropost Feed</h3>
<section class="micropost_form">
<%= render 'shared/feed_form' %>
</section>
<%= render 'shared/feed' %>
</div>
</div>
<% else %>
<% end %>
Here are two codes Everything work perfectly but when I am trying to add ajax I get the error which is :
Rendered shared/_feed.html.erb (3.1ms)
Rendered feeds/create.js.erb (6.0ms)
Completed 500 Internal Server Error in 73ms (ActiveRecord: 44.4ms)
NoMethodError (undefined method `any?' for nil:NilClass):
app/views/shared/_feed.html.erb:1:in `_app_views_shared__feed_html_erb___516512175__638262078'
app/views/feeds/create.js.erb:1:in `_app_views_feeds_create_js_erb___967625174__637838198'
app/controllers/feeds_controller.rb:9:in `create'
To execute ajax on create method I added these files unders feeds views file name is create.js.erb
$("#feed_add").html("<%= escape_javascript(render partial: "shared/feed") %>");
And form file is under shared view file with name _feed_form.html.erb
<%= form_for(#feed,:remote => true) do |f| %>
<div id="feed_add">
<%= f.text_area :content, placeholder: "Compose new feed..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
#_feed.html.erb
<% if #feed_items.any? %>
<ol class="microposts">
<%= render #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
So tell me how can I add feed and without refreshing how can I show feed using partial In this code .
Here you simply need to render one thing that is feed for that in micheal heart book you simply add this line of code inside your create ajax file here is the code :
$(".microposts").prepend('<%= j render #feed %>');
Here you can get the result what you want .

Understanding Ajax in Rails 3

I thought I understood Ajax in Rails 3 to a point but think I am confusing myself somewhere or misinterpreted something. My understanding is that if I want to call different content on the same page then i create a js.erb file for that particular action. For example if i have an action of tynewyddnews, I will have an tynewyddnews view and a tynewyddnews.js.erb file.
I then create a partial to render on that page and call that partial in my .js.erb file.
Example
View
<% #tynewyddpost.each do |t| %>
<li>
<% single = t.photos.first %>
<a class="photo" href="#"><%= image_tag(single.avatar.url(:thumbnail_news_images)) %></a>
<p><%= link_to t.title, tynewyddnews_path(:type => 'tynewyddnews'), :post_id => t.id, :remote => true %></p>
<p class="date"><%= date_output(t.published_on) %></p>
</li>
<% end %>
<div class="post-item">
<h2><%= #tynewyddpostlatest.title %></h2>
<div id="work-samples">
<% for photo in #tynewyddpostlatest.photos %>
<%= image_tag(photo.avatar.url(:news_images), :class => 'work-sample') %>
<% end %>
</div>
<p class="post-description"><%= #tynewyddpostlatest.comments.html_safe %></p><a class="post-more" href="#">Continue Reading »</a>
<div class="post-item-panel">
<ul>
<li class="date">
<p><%= date_output(#tynewyddpostlatest.published_on) %></p>
</li>
</ul>
</div>
</div>
So the historical posts go down the left hand side and the latest post goes in the center
.js.erb
<% if params[:type] == 'tynewyddnews' %>
jQuery('.post-item').html('<%= escape_javascript(render partial: 'tynewyddnewspost') %>');
<% end %>
Partial
<div class="post-item">
<h2><%= #tynewyddpost.title %></h2>
<div id="work-samples">
<% for photo in #tynewyddpost.photos %>
<%= image_tag(photo.avatar.url(:news_images), :class => 'work-sample') %>
<% end %>
</div>
<p class="post-description"><%= #tynewyddpost.comments.html_safe %></p>
<div class="post-item-panel">
<ul>
<li class="date">
<p><%= date_output(#tynewyddpost.published_on) %></p>
</li>
</ul>
</div>
</div>
Controller
def tynewyddnews
tynewyddpost = Post.tynewydd_posts.find(params[:post_id])
tynewyddpost.shift
#tynewyddpost = tynewyddpost
#tynewyddpostlatest = Post.tynewydd_posts.first
end
tynewydd_posts is a scope
scope :tynewydd_posts, :include => :department, :conditions => {"departments.name" => "Ty Newydd"}, :order => "posts.published_on DESC"
So my issue at the moment is when i try and render the page i get the error
Couldn't find Post without an ID
Apologies for the long post but if someone could point me in the right direction that would be great
Thanks
It looks to me like you're doing it way wrong, sorry. It doesn't need to be that complicated. I would start over from scratch with a much simpler example, and then build up from there.
I would do something like rails g scaffold post title:string and then do this, just in a browser console:
$.ajax({
url: "/posts/index"
}).done(function() {
console.log("done");
});
You should be able to see the data coming back through your browser's console. On the Rails side, that data is coming from here:
class PostsController < ApplicationController
def index
#posts = Post.all
# there might be more stuff here
end
end
Hopefully you understand what I'm talking about. If you don't, I'd recommend separately learning a little more about Rails and a little more about jQuery/ajax before trying to combine the two.
OK so it seems my issue was the way i was calling the id of a post and I also moved my ajax call into a separate action, setup all be it complicated is correct.
What i changed
<%= link_to t.title, tynewyddnews_path(:type => 'tynewyddnews'), :post_id => t.id, :remote => true %>
was changed to
<%= link_to t.title, my_path_path(:type => 'tynewyddnews', :id => t.id), :remote => true %>
Controller
I added a new action to handle the ajax call, finding a post by id
def my_path
#tynewyddpost = Post.find(params[:id])
end
Then in my partial I could use the #tynewyddpost instance variable
Hope this helps someone else

RoR: How can I get my microposts to show up?

Here is the users show view where they are supposed to show up. ..
<section>
<div id= "purchases">
<%= render 'shared/micropost_form_purchase' %>
</div>
<div id="sales">
<%= render 'shared/micropost_form_sale' %>
</div>
</section>
<%= #sales %> <%# This is just to see if it outputs anything. It doesn't :( %>
<div id="purchases list">
<ol class="microposts">
<%= render #purchases unless #purchases.nil? %>
</ol>
</div>
<div id="sales list">
<ol class="microposts">
<%= render #sales unless #sales.nil? %>
</ol>
</div>
so the forms (partials) are loading fine, but then when I make a post, in either one, neither the purchases list nor the sales list shows up. I checked the database and they are being created along with an entry in the column indicating kind (either sale or purchase).
Here are the forms:
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
and
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
also, here is the show part of the users_controller.rb
def show
#user = User.find(params[:id])
#micropost=Micropost.new
#microposts = #user.microposts.paginate(page: params[:page])
end
and here is the show part of the microposts_controller.rb
def show
#micropost = Micropost.find(params[:id])
#microposts = Micropost.where(:user_id => #user.id)
#purchases= #microposts.collect{ |m| m if m.kind == "purchase"}.compact
#sales = #microposts.collect{ |m| m if m.kind == "sale"}.compact
end
additionally, with the help of this post (http://stackoverflow.com/questions/12505845/ruby-error-wrong-number-of-arguments-0-for-1#12505865) the variables #microposts, #purchases, and #sales are all outputting correctly in the console.
can anyone help me out?
edit: using scopes as suggested by the answer given works in the console (it outputs everything correctly, but they still don't show up in the view. Does this mean it is something wrong with my syntax for the users show page?
edit 2:
Here is the view/microposts/_micropost.html.erb code
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
confirm: "You sure?",
title: micropost.content %>
<% end %>
</li>
I'm making some assumptions without seeing more of your code, but it looks like you could
write what you've shown a little differently. I'm assuming your databases are migrating
and have the required columns, e.g., Micropost#kind, Micropost#user_id, etc.
You can use scopes to refine a collection of microposts more expressively. It might be helpful to read
up about ActiveRecord scopes: http://guides.rubyonrails.org/active_record_querying.html#scopes.
class Micropost < ActiveRecord::Base
belongs_to :user
scope :purchases, where(:kind => "purchase")
scope :sales, where(:kind => "sale")
# your code
end
I'm also assuming your user has many microposts:
class User < ActiveRecord::Base
has_many :microposts
# your code
end
For your forms, I'd suggest attaching your hidden field to the form object (f.hidden_field) so
you don't have to specify the name as 'micropost[kind]'.
<%= form_for(#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= f.hidden_field :kind, :value => "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
In MicropostsController#show, you can use your new scopes:
def show
#micropost = Micropost.find(params[:id])
#microposts = #user.microposts
#purchases = #microposts.purchases
#sales = #microposts.sales
end
You should also confirm that your MicropostsController#create action is actually adding
the microposts to the user sending the form (I'm assuming a current user method).
def create
#micropost = current_user.microposts.create(params[:micropost])
# yada
end
You can also confirm expected results on rails console after creating purchases or sales micropost with:
Micropost.purchases
Micropost.sales
Again, I could be missing something without seeing more of the code base.
Check Micropost.count, #purchases.count, #sales.count (by printing them in the controller, or some part of the view) to see if the records actually exist.
Also, if you want to render collections likes #sales and #purchases, you need to make sure that the model partial exists (_micropost.html.erb in your case). That is probably where you need to look for the view errors. For all you know, that file could be empty, thus no errors will show up at all.
The problem might also lie in your microposts#create (or whichever action that you are saving the micropost in), the micropost should be associated with the current_user:
#micropost = current_user.microposts.build(params[:micropost])
Taking this and your previous question into account, I suggest you go through the original code for the RoR tutorial again (and verify that all tests are passing) before taking it apart. You can always add new tests to it for your experiments and they will help in figuring out where you went wrong.

rails ajax request doesn't work

I have some problem with ajax
This request GET http://localhost:3000/projects/new (304 Not Modified) does work, it executes javascript from response:
$('#add-project-button').hide();
$('#project-form').append("<form accept-charset=\"UTF-8\" action=\"/projects\" class=\"new_project\" data-remote=\"true\" id=\"new_project\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"utf8\" type=\"hidden\" value=\"✓\" /><input name=\"authenticity_token\" type=\"hidden\" value=\"gzu9DETiVV8N+OtRnkdYpD6aa0/RbM7i2H+nkQ0yXGc=\" /><\/div>\n <div class=\"field\">\n <label for=\"project_name\">Name<\/label><br />\n <input id=\"project_name\" name=\"project[name]\" size=\"30\" type=\"text\" />\n <\/div>\n <div class=\"actions\"><input name=\"commit\" type=\"submit\" value=\"Create Project\" /><\/div>\n<\/form>");
But another request POST http://localhost:3000/projects (200 OK) seems ok but response is empty, no javascript is executing, but the server answer is ok:
Rendered tasks/_task.html.erb (0.0ms)
Rendered projects/_project.html.erb (4.5ms)
Rendered shared/_create.js.erb (5.4ms)
Rendered projects/create.js.erb (6.1ms)
Completed 200 OK in 96ms (Views: 8.6ms | ActiveRecord: 84.9ms)
So I'm guessing that the browser somehow is of not supposed to execute javascript from server in this case.
What might be a problem? How to make browser receive the javascript and execute it? Thanks.
UPDATE: The form which is making ajax request:
<%= form_for(#project, :remote => true) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
The controller action:
def create
#project = current_user.projects.build(params[:project])
respond_with(#project.tap(&:save))
end
Maybe the problem is causing by using partial as layout, projects/create.js.erb:
<% render :layout => '/shared/create', locals: { obj: #project } do %>
$('#project-container').append("<%= escape_javascript render(#project) %>");
$('#add-project-button').show('fast');
$('#project-form').hide('fast', function(){ $('#project-form').empty(); });
<% end %>
The problem was very simple, I forget to put <%= sign in erb, so it should be:
<%= render :layout => '/shared/create', locals: { obj: #project } do %>
$('#project-container').append("<%= escape_javascript render(#project) %>");
$('#add-project-button').show('fast');
$('#project-form').hide('fast', function(){ $('#project-form').empty(); });
<% end %>

Resources