I have a Rails 4.2 app in which I'm using Ransack mixed with Geocoder for search. I want to use an Ajax (remote: true) for my search to avoid pageloads and changing of the URL.
When I implement this in my index view it works great, but I want to abstract the search box to the application layout file so it's available site wide instead of just on the index view. When I do this (see code example) I'm able to search just fine, but the problem is I can't seem to figure out how to get the Ajax/Remote: True to work. Here is my code:
application.html.erb
<%= search_form_for(#search, url:"/resources", :method => :get, remote: true) do |f| %>
<%= text_field_tag :location, params[:location], placeholder: "Houston, TX", class: "input-sm form-control" %>
<%= f.submit "Find", class:'btn btn-sm btn-info' %>
<% end %>
application_controller.rb
before_action :build_search
private
def build_search
if params[:location].present?
#search = Resource.near(params[:location], 100).search(params[:q])
else
#search = Resource.search(params[:q])
end
end
resources/index.js.erb
$("#mapdisplay").html("<%= escape_javascript render("map") %>");
$("#results").html("<%= escape_javascript render("results") %>");
resources/index.html.erb
<div id="mapdisplay">
<%= render 'map' %>
</div>
<div id="results">
<%= render 'results' %>
</div>
resources_controller.rb
before_action :set_search_results, only: [:show, :index, :new]
def index
#hash = Gmaps4rails.build_markers(#resources) do |resource, marker|
marker.lat resource.latitude
marker.lng resource.longitude
end
respond_to do |format|
format.html {}
format.js {}
end
end
private
def set_search_results
#resources = #search.result(distinct: true)
end
resources/_map.html.erb
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>
<h4>Resources</h4>
<div id="search">
<%= render 'search' %>
</div>
<div class="pull-right">
<%= link_to "Add", new_resource_path, class: 'btn btn-info btn-medium' %>
</div>
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'></div>
</div>
<script>
handler = Gmaps.build('Google');
handler.buildMap({
provider: {
disableDefaultUI: true
// pass in other Google Maps API options here
},
internal: {
id: 'map'
}
},
function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
}
);
</script>
resources/_search.html.erb
<div class="form-group">
<%= search_form_for(#search, :id => "resource_search", remote: true) do |f| %>
<%= text_field_tag :location, params[:location], placeholder: "Houston, TX", class: "input-sm form-control" %>
<%= f.submit "Find", class:'btn btn-sm btn-info' %>
<% end %>
</div>
resources/_results.html.erb
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<% #resources.each do |r| %>
<tr>
<td><%= link_to "#{r.name}", r %></td><td><%= r.address %></td><td><%= r.notes %></td>
</tr>
<% end %>
</tbody>
</table>
Again, I can get this working in the index view/controller with js and remote: true but when I implement the search box sitewide in the application layout file I cannot use JS/remote: true.
I'm sure I'm missing something simple in my implementation so if anyone has any advice, please let me know. If my question and/or code examples are not clear let me know and I'll explain in further detail.
Related
I want to store value in db using Rails ajax form but it is not storing anything.Please let me to know where i did the mistake and help me to resolve this issue.
I am explaining my code below.
users/index.html.ebr:
<script type="text/javascript">
$('form').submit(function() {
var valuesToSubmit = $(this).serialize();
console.log('hello')
$.ajax({
type: "POST",
url: $(this).attr('create'), //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
});
</script>
<p><%= flash[:notice] %></p>
<%= form_for :user do |f| %>
<p>
Name : <%= f.text_field :name,placeholder:"Enter your name" %>
</p>
<p>
Email : <%= f.email_field :email,placeholder:"Enter your email" %>
</p>
<p>
Content : <%= f.text_field :content,placeholder:"Enter your content" %>
</p>
<p>
<%= f.text_field :submit,:onchange => "this.form.submit();" %>
</p>
<% end %>
<div id="sdf-puri" style="display:none" >
</div>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
respond_to do |format|
format.html
format.js
end
end
def create
#user=User.new(params[:user])
if #user.save
flash[:notice]="user created"
end
end
end
create.js.erb
$("#sdf-puri").css("display", "block");
$("#sdf-puri").html("<%= escape_javascript (render 'table' ) %>");
$("#sdf-puri").slideDown(350);
create.html.erb
<%= render 'table' %>
_table.html.erb
<table>
<tr>
<th>Name :</th>
<th>Email :</th>
<th>Content :</th>
</tr>
<% #user.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= user.content %></td>
</tr>
<% end %>
</table>
After submit value should display in same index page.Please help me.
Rails has a built in Ajax system, on your form you need to add remote: true
form_for(#user, remote: true) do |f|
This tells rails to submit the form using Ajax under the hood... You don't need all of the script above the form
Your controller already correctly has the line:
responds_to js
So all you would do is have a create.js file in your views/user folder that handled your return Ajax stuff such as appending or fading etc
you need to add remote: true in form tag
I want to display the database values inside the table using Ajax in Rails.bou i got the following error.
Error:
Template is missing
Missing template users/search, application/search with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "c:/Site/demo2/app/views"
I also added the search.html.erb i removed the error but got the blank page.
Please check my below codes.
views/users/index.html.erb
<%= form_for :user ,:url => {:action => "search" }, remote: true do |f| %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :receipt,:class => "form-control",placeholder:"user number",:onchange => "this.form.submit();" %>
</div>
<% end %>
<div id="search-output-table">
<%= render partial: "search_output_table", locales: {user: #user} %>
</div>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
end
def search
#user = User.find_by_receipt(params[:user][:receipt])
end
end
views/users/_search.js.erb
$("#search-output-table").html("<%= escape_javascript( render(partial: "search_output_table") ) %>");
views/users/_search_output_table.html.erb
<table>
<tr>
<th>User Name</th>
<th>User Email</th>
<th>User Number</th>
</tr>
<tr>
<td><%= #user.name %></td>
<td><%= #user.email %></td>
<td><%= #user.receipt %></td>
</tr>
</table>
I also want remove onchange event and as soon as the value will fill inside text field the action will execute without reload the page as well as the table value will display(initially the table should remain disable/hide).Please help me to resolve this error and add this new scenario.
Well, on request to UsersController#search Rails will by default render app/views/users/search.html.erb, which I assume is empty.
You probably just need to rename views/users/_search.js.erb to views/users/search.js.erb and add following to the controller
def search
#user = User.find_by_receipt(params[:user][:receipt])
respond_to do |format|
format.js
end
end
Also make sure you're passing in #user to the search_output_table template. Like this
render partial: 'search_output_table', locals: {user: #user}
And in 'search_output_table' you should use just user instead of #user.
Question: How to access hidden field value post_id from file view/comments/_comment.html.erb and use it in controllers/dashboards_controller.rb?
- there are 2 controllers - dashboard and comments, and using gem act_as_commentable_with_threading
Now I get: ActiveRecord::RecordNotFound in DashboardsController#index Couldn't find Post without an ID
config/routes.rb
resources :comments, :only => [:create, :destroy]
controllers/dashboards_controller.rb
class DashboardsController < ApplicationController
def index
#post = Post.new
#user = current_user
#newest_users = User.newest_players
#feed_posts = Post.paginate(:page => params[:page], :per_page => 8)
#last_clubs = Club.last_clubs
#commented_post = Post.find(params[:post_id])
# trying to access params from view/comments/_comment.html.erb
# comments is another controller...
# do other operations with #commented_post
#comments = #commented_post.comment_threads.order('created_at desc')
#new_comment = Comment.build_from(#commented_post, current_user, '')
end
end
view/comments/_comment.html.erb
Add comment
place for a comment form
<div class="comment-form">
<%= form_for :comment, :remote => true do |f| %>
<%=f.hidden_field 'post_id', post.id %>
# need to use this value in dasboard controller
<%=f.text_field :body %>
<% end %>
</div>
view/dashboards/_feed_post.html.erb
<ul class="post-items">
<%if #feed_posts.any? %>
<% #feed_posts.each do |post| %>
<li>
<span class="image"><%= image_tag post.image.url(:message) if post.image?%></span>
<span class="content"><%= post.text_html %></span>
<span class="tags">Tags:<%= post.tag_list %></span>
<span class="meta">
Posted <%= time_ago_in_words(post.created_at) %> ago.
| <%= post.user.full_name %>
</span>
<%= render 'comments/form' ,:locals => { :comment => #new_comment, :post_id => post.id } %>
<%= render 'comments/comment', :collection => #comments, :as => :comment, :post_id => post.id %>
</li>
<% end %>
<% end %>
</ul>
view/dashboards/index
<div class="row">
<div class="span7">
<!--form for creating a new post-->
<section>
<%= render :template => 'posts/new' %>
</section>
<!--dashboard feed_post-->
<section>
<%= render :partial => 'dashboards/feed_post' %>
</section>
</div>
you are using f.hidden_field so you will get
<%=f.hidden_field 'post_id', post.id %>
will create following html ref hidden_field
<input type="hidden" id="comment_post_id" name="comment[post_id]" value="#{comment.post_id}" />
so you can access this as following in your controller
params[:comment][:post_id]
so use following instead
#commented_post = Post.find(params[:comment][:post_id])
if you want 'post_id' in params[:post_id] use hidden_field_tag like following
<%= hidden_field_tag 'post_id', post.id %>
I have just started learning Ruby on Rails using Agile Web Develop ment by Sam Ruby. I'm currently stuck on task F: adding Ajax to cart. Everything went well till the time I added to the code for hiding an empty cart. Now when I add the first item the cart shows up empty on the side bar (it should show up with one item n the cart) but when i add the second item the cart shows up with 2 items, as it should.The code works if I add more items. I'm facing the problem only when adding the first item on the cart. I've been tearing my hair out for a day now on this problem. Any help will be greatly appreciated. Apologies if I haven't furnished complete details. Please let me know the additional details, if any, that would be relevant. I'm using rails 3.2.8 and ruby 1.9.3 Thanks!
_cart.html.erb
<div class="cart_title">Your Cart</div>
<table>
<%= render(cart.line_items) %>
<tr class="total_line">
<td colspan="2">Total</td>
<td class="total_cell"><%= number_to_currency(cart.total_price) %></td>
</tr>
</table>
<%= button_to 'Empty Cart',cart, method: :delete, confirm: 'Are you sure?'%>
_line_item.html.erb
<%if #current_item==line_item%>
<tr id="current_item">
<% else %>
<tr>
<% end %>
<td><%= line_item.quantity %> ×</td>
<td><%= line_item.product.title %></td>
<td class="item_price" ><%= number_to_currency(line_item.total_price) %></td>
<td><%= button_to 'Remove Item', line_item, method: :delete, confirm: 'Are you sure?'%>
</tr>
create.js.erb
$("#notice").hide();
if ($('#cart tr').length > 0) { $('#cart').show('blind', 1000); }
$('#cart').html("<%=j render #cart %>");
$('#current_item').css({'background-color':'#88cc88'}).
animate({'background-color':'#114411'}, 1000);
application.js.erb
<html>
<head>
<title>Pragprog Books Online Store</title>
<!-- START:stylesheet -->
<%= stylesheet_link_tag "scaffold" %>
<%= stylesheet_link_tag "depot", :media => "all" %><!-- <label id="code.slt"/> -->
<!-- END:stylesheet -->
<%= javascript_include_tag "application" %>
<%= csrf_meta_tag %><!-- <label id="code.csrf"/> -->
</head>
<body id="store">
<div id="banner">
<%= image_tag("logo.png") %>
<%= #page_title || "Pragmatic Bookshelf" %><!-- <label id="code.depot.e.title"/> -->
</div>
<div id="columns">
<div id="side">
Home<br />
Questions<br />
News<br />
Contact<br />
<%if #cart%>
<%= hidden_div_if(#cart.line_items.empty?, id:"cart") do%>
<%=render #cart%>
<% end %>
<% end %>
</div>
<div id="main">
<%= yield %><!-- <label id="code.depot.e.include"/> -->
</div>
</div>
</body>
</html>
~
managed to solve it myself :)..while typing out the problem i got a hint that the problem was somehow with the rendering itself and so it was .. the solution is to set the show parameter to 0 in { $('#cart').show('blind', 1000); } the code should now be { $('#cart').show('blind', 0); }
#Btuman done!!
Have progressed to get wicked_pdf generating PDF's in Rails 3.2.3. However I want to be able to have links on my pages rendered to screen as HTML from the .html.erb file, but when I review the PDF generated from this template I do not want to see these links.
I had tried to follow what Ryan Bates did in is PDFKit Railscast 220, but its not working for me under Rails 3.2.3, on Ruby 1.9.3.
Here is my an abridged section of the view code:
<h2>Client Setup (Only when Patients module is not available)</h2>
<p>
The setup program installs your Clients module using default settings. After the installation, you can use this program to customize settings to meet your particular needs.
</p>
<p>
<%= pdf_image_tag("clients/blank/.png", alt: "Client Setup (Only when Patients Module is not available) - not-populated") %>
<table>
<thead>
<tr>
<th>Form Item</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default Value Added Tax (Percent)</td>
<td>
The package offers a default Value Added Tax, expressed as a percentage of the invoice, to be added to the invoice. Numbers from 0 to 999.99 are allowed.
</td>
</tr>
</tbody>
</table>
</p>
<hr />
<form class="form-inline">
Back to Top
<%= link_to "Genie Help Index", help_path, class: "btn btn-main-menu pdf_link" %>
<p id="pdf_link"><%= link_to "Client Help Index", static_page_path("clients/index"), class: "btn btn-help" %></p>
<%= link_to "Download PDF", static_page_path(:format => :pdf), class: "btn btn-pdf" %>
<%= link_to image_tag("file_type_pdf.png", height: "24px", width: "24px" , alt: "Download page as PDF"), static_page_path(:format => :pdf) %>
</form>
<p><%= link_to "Client Help Index", static_page_path("clients/index") %></p>
<p><%= link_to "Download as PDF", static_page_path(:format => "pdf"), class: "pdf_link" %></p>
<p id="pdf_link"><%= link_to "Download as PDF", static_page_path(:format => :pdf) %></p>
<% if request.try(:format).to_s == 'pdf' %>
<%= link_to "Download this PDF", static_page_path(:format => "pdf") %>
<% end %>
#<% if params[:media] = 'all' %>
# <%= link_to "Download me as a PDF", static_page_path(:format => "pdf") %>
#<% end %>
<div id="pdf-no"><%= link_to "Get me as a PDF file", static_page_path(:format => "pdf") %></div>
Controller is: (show page is the name of the page to render)
class StaticPages::GenieHelpController < ApplicationController
def static_page
respond_to do |format|
format.html do
render :template => show_page,
:layout => 'application'
end
format.pdf do
render :pdf => show_page,
:layout => 'generic',
:template => "#{show_page}.html.erb",
:handlers => :erb,
:disable_external_links => true,
:print_media_type => true
end
end
end
end
The layout file in views/layouts/generic.pdf.erb file is as below:
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= wicked_pdf_stylesheet_link_tag "static_pages/genie_v23_help", :refer_only => true %>
<!-- <%#= wicked_pdf_stylesheet_link_tag "static_pages/pdf" %> -->
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div class="container">
<%= yield %>
<%= debug(params) if Rails.env.development? %>
</div>
</body>
</html>
The corresponding css file in old location public/stylesheets/static_pages/genie_help.css:
#media print {
body { background-color: LightGreen; }
#container {
width: auto;
margin: 0;
padding: 0;
border: 2px;
}
#pdf_link {
display: none;
}
}
.pdf_link {
display: none;
}
#pdf-no {
display:none;
}
When I render the html page the links at the bottom show up (as expected) when the format is html.
What am I doing wrong on with this. I assume if it can be done via middleware of PDFKit then it is supported under wkhtmltopdf as both PDFKit and wicked_pdf are based on this.
Thanks
Mark
It turned out to be that I solved this problem by mixing-and-matching the four methods in the wicked_helper.pdf file which is based on the lib helper file.
The wicked_pdf_image_tag was changed to pdf_image_tag used in the pull request waiting commit from - mkoentopf
Multi purpose wicked_pdf_helper "Hi there, I've added some code to the wicked_pdf_helper methods. Now they deliver the the full pa…"
def wicked_pdf_image_tag(img, options={})
if request.try(:format).to_s == 'application/pdf'
image_tag "file://#{Rails.root.join('public', 'images', img)}", options rescue nil
else
image_tag img.to_s, options rescue nil
end
end
What I don't understand is under Rails 3.2 are we still using public directory because sprockets and assests get pre-compiled and placed in public?
The solution I used earlier in the day was to add additional header/footer partials within the html layout, but not in the layout for pdf generation.
Here is the helper file I was using:
module WickedPdfHelper
def wicked_pdf_stylesheet_link_tag(*sources)
options = sources.extract_options!
if request.try(:format).to_s == 'application/pdf'
#css_dir = Rails.root.join('public','stylesheets')
css_dir = Rails.root.join('app','assets', 'stylesheets')
refer_only = options.delete(:refer_only)
sources.collect { |source|
source.sub!(/\.css$/o,'')
if refer_only
stylesheet_link_tag "file://#{Rails.root.join('public','stylesheets',source+'.css')}", options
else
"<style type='text/css'>#{File.read(css_dir.join(source+'.css'))}</style>"
end
}.join("\n").html_safe
else
sources.collect { |source|
stylesheet_link_tag(source, options)
}.join("\n").html_safe
end
end
def pdf_image_tag(img, options={})
if request.try(:format).to_s == 'application/pdf'
image_tag "file://#{Rails.root.join('app', 'assets', 'images', img)}", options rescue nil
else
image_tag img.to_s, options rescue nil
end
end
def wicked_pdf_javascript_src_tag(jsfile, options={})
if request.try(:format).to_s == 'application/pdf'
jsfile.sub!(/\.js$/o,'')
javascript_src_tag "file://#{Rails.root.join('public','javascripts',jsfile + '.js')}", options
else
javascript_src_tag jsfile, options
end
end
def wicked_pdf_javascript_include_tag(*sources)
options = sources.extract_options!
sources.collect{ |source| wicked_pdf_javascript_src_tag(source, options) }.join("\n").html_safe
end
end
It would be good to understand more about how the asset pipeline is used. And how the #media is determined. Is it related to MIME types? If so why do we not need to/or are they not defined in wick_pdf?
I have yet to utilise the page numbering and breaking, but now have an outstanding question that I'll put up separately.