Issue regarding ajax search rails - ruby-on-rails

I tried to built my search with Ajax and I have added remote: true , and respond_ to block in the controller and I created the partial _xvaziri.html.erb and finally index.js.erb.
But I am not getting the desired results for the Ajax search.
Please refer the images as shown below;
In the above image when I searched for "cash" then I get rendering multiple times in the terminal.
index.html.erb
<% #balance = 0 %>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="table-responsive myTable">
<table class="table listing text-center">
<tr class="tr-head">
<td>Date</td>
<td>Description</td>
<td>Amount</td>
<td>Discount</td>
<td>Paid</td>
<td>Balance</td>
</tr>
<tr>
<td></td>
</tr>
<a href="#" class="toggle-form" style="float: right;" >Search</a>
<div id="sample">
<%= form_tag xvaziris_path, remote: true, method: :get, class: "form-group", role: "search" do %>
<p>
<center><%= text_field_tag :search, params[:search], placeholder: "Search for.....", autofocus: true, class: "form-control-search" %>
<%= submit_tag "Search", name: nil, class: "btn btn-md btn-primary" %></center>
</p>
<% end %><br>
</div>
<% if #xvaziris.empty? %>
<center><p><em>No results found.</em></p></center>
<% end %>
<%= render #xvaziris %>
</table>
</div>
</div>
</div>
_xvaziri.html.erb
<tr id = "kola" class="tr-<%= cycle('odd', 'even') %>">
<td class="col-1"><%= xvaziri.date.strftime('%d/%m/%Y') %></td>
<td class="col-3"><%= span_with_possibly_red_color xvaziri.description %></td>
<td class="col-1"><%= number_with_precision(xvaziri.amount, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 neg"><%= number_with_precision(xvaziri.discount, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 neg"><%= number_with_precision(xvaziri.paid, :delimiter => ",", :precision => 2) %></td>
<% #balance += xvaziri.amount.to_f - xvaziri.discount.to_f - xvaziri.paid.to_f %>
<% color = #balance >= 0 ? "pos" : "neg" %>
<td class="col-1 <%= color %>"><%= number_with_precision(#balance.abs, :delimiter => ",", :precision => 2) %></td>
</tr>
xvaziris_controller.rb
class XvazirisController < ApplicationController
before_action :set_xvaziri, only: [:show, :edit, :update, :destroy]
def index
#xvaziris = Xvaziri.where (["description LIKE ? OR amount LIKE ? OR paid LIKE ?", "%#{params[:search]}%","%#{params[:search]}%","%#{params[:search]}%"])
respond_to do |format|
format.js
format.html
end
end
def import
Xvaziri.import(params[:file])
redirect_to xvaziris_url, notice: "Xvaziris imported."
end
def show
end
def new
#xvaziri = Xvaziri.new
end
def create
#xvaziri = Xvaziri.new(xvaziri)
if
#xvaziri.save
flash[:notice] = 'Xvaziri Created'
redirect_to #xvaziri
else
render 'new'
end
end
def edit
end
def update
if #xvaziri.update(xvaziri)
flash[:notice] = 'Xvaziri Updated'
redirect_to #xvaziri
else
render 'edit'
end
end
def destroy
#xvaziri.destroy
flash[:notice] = 'Xvaziri was successfully destroyed.'
redirect_to xvaziris_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_xvaziri
#xvaziri = Xvaziri.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def xvaziri
params.require(:xvaziri).permit(:date, :description, :amount, :discount, :paid)
end
end
index.js.erb
<% #balance = 0 %>
<% #xvaziris.each do |xvaziri| %>
$('#kola').append("<%= j render xvaziri %>");
<% end %>
How should I write the above code in order to find searches in xvaziris#index ?
Secondly, I want to display the no results found when search is nil,blank or empty.I wrote the below code but it is not working.
<% if #xvaziris.empty? %>
<center><p><em>No results found.</em></p></center>
<% end %>
Any suggestions are most welcome.
Thank you in advance.

I revised my index.html and index.js.erb as below;
<% #balance = 0 %>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="table-responsive myTable">
<table id = "kola" class="table listing text-center">
<thead>
<tr class="tr-head">
<td>Date</td>
<td>Description</td>
<td>Amount</td>
<td>Discount</td>
<td>Paid</td>
<td>Balance</td>
</tr>
</thead>
<a href="#" class="toggle-formed" style="float: right;" ><strong>Search</strong></a>
<div id="sample">
<%= form_tag xvaziris_path, remote: true, method: :get, class: "form-group", role: "search" do %>
<p>
<center><%= text_field_tag :search, params[:search], placeholder: "Search for.....", autofocus: true, class: "form-control-search" %>
<%= submit_tag "Search", name: nil, class: "btn btn-md btn-primary" %></center>
</p>
<% end %><br>
</div>
<tbody>
<%= render #xvaziris %>
</tbody>
</table>
</div>
</div>
</div>
index.js.erb
<% #balance = 0 %>
$('#kola tbody').empty();
<% #xvaziris.each do |xvaziri| %>
$('#kola tbody').append("<%= j render xvaziri %>");
<% end %>

Related

NoMethodError in Spree::Admin::Reviews#index

I am new to spree and ruby on rails.While clicking the 'reviews' in spree back-end, it's throwing an error.
Thanks in Advance.
NoMethodError in Spree::Admin::Reviews#index
Showing - var/lib/gems/2.3.0/ruby/2.3.0/bundler/gems/spree_reviews-e51cae9627f9/app/views/spree/admin/reviews/index.html.erb where line #25 raised:
index.html.erb:
<% content_for :page_title do %>
<%= Spree.t('reviews') %>
<% end %>
<% render 'spree/admin/shared/product_sub_menu' %>
<% content_for :table_filter_title do %>
<%= Spree.t('search') %>
<% end %>
<% content_for :table_filter do %>
<div data-hook="admin_reviews_index_search">
<%= search_form_for [:admin, #search] do |f| %>
<div class="alpha three columns">
<div class="field">
<%= label_tag nil, Spree.t(:user) %><br />
<%= f.text_field :name_cont, :size => 25 %>
</div>
</div>
<div class="seven columns">
<div class="field">
<%= label_tag nil, Spree.t(:title) -%><br/>
<%= f.text_field :title_cont, :size => 25 -%>
</div>
</div>
<div class="four columns">
<div class="field">
<%= label_tag nil, Spree.t(:review) -%><br/>
<%= f.text_field :review_cont, :size => 25 -%>
</div>
</div>
<div class="two columns omega">
<div class="field">
<%= label_tag nil, Spree.t(:approval_status)-%><br/>
<%= f.select :approved_eq, [[Spree.t('all'), nil],
[Spree.t('approved_reviews'), true],
[Spree.t('unapproved_reviews'),false]] -%>
</div>
</div>
<div class="clear"></div>
<div class="form-buttons actions filter-actions" data-
hook="admin_reviews_index_search_buttons">
<%= button Spree.t(:search), 'icon-search' %>
</div>
<%- end -%>
</div>
<%- end -%>
<% paginate #reviews %>
<% if #reviews.any? %>
<table class="index">
<colgroup>
<col style="width: 25%;">
<col style="width: 10%;">
<col style="width: 10%;">
<col style="width: 20%;">
<col style="width: 15%;">
<col style="width: 17%;">
</colgroup>
<thead>
<tr>
<th><%= Spree.t('product') %></th>
<th><%= Spree::Review.human_attribute_name(:rating) %></th>
<th><%= Spree.t('feedback') %></th>
<th><%= Spree::Review.human_attribute_name(:user) %></th>
<th><%= Spree::Review.human_attribute_name(:created_at) %></th>
</tr>
</thead>
<tbody>
<%- #reviews.each do |review| -%>
<tr id="<%= dom_id review %>">
<td>
<% if review.product %>
<%= link_to review.product.name, product_path(review.product) %>
<% end %>
</td>
<td class="align-center">
<%= txt_stars(review.rating) %>
</td>
<td class="align-center">
<%= link_to "(#{review.feedback_stars}/#{review.feedback_reviews.size})", admin_review_feedback_reviews_path(review) %>
</td>
<td class="align-center">
<%= review.user_id ? link_to(review.user.try(:email), [:admin, review.user]) : Spree.t(:anonymous) %></p>
<p><%= Spree::Review.human_attribute_name(:ip_address) %>: <%= review.ip_address ? link_to(review.ip_address, "http://whois.domaintools.com/#{review.ip_address}") : '-' %></p>
</td>
<td class="align-center">
<%= l review.created_at, :format => :short %>
</td>
<td class="actions">
<%= link_to_with_icon 'check', Spree.t('approve'), approve_admin_review_url(review), :no_text => true, class: 'approve' unless review.approved %>
<%= link_to_edit review, :no_text => true, :class => 'edit' %>
<%= link_to_delete review, :no_text => true %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="no-objects-found">
<%= Spree.t(:no_results) %>
</div>
<% end %>
<%= paginate #reviews -%>
reviews_controller
class Spree::Admin::ReviewsController <
Spree::Admin::ResourceController
helper Spree::ReviewsHelper
def index
#reviews = collection
params[:q] ||= {}
#search = Spree::Review.ransack(params[:q])
#collection = #search.result.includes([:product, :user,
:feedback_reviews]).page(params[:page]).per(params[:per_page])
end
def approve
r = Spree::Review.find(params[:id])
if r.update_attribute(:approved, true)
flash[:notice] = Spree.t("info_approve_review")
else
flash[:error] = Spree.t("error_approve_review")
end
redirect_to admin_reviews_path
end
def edit
if #review.product.nil?
flash[:error] = Spree.t("error_no_product")
redirect_to admin_reviews_path and return
end
end
private
def collection
params[:q] ||= {}
#search = Spree::Review.ransack(params[:q])
#collection = #search.result.includes([:product, :user,
:feedback_reviews]).page(params[:page]).per(params[:per_page])
end
end
review.rb
class Spree::Review < ActiveRecord::Base
belongs_to :product, touch: true
belongs_to :user, :class_name => Spree.user_class.to_s
has_many :feedback_reviews
after_save :recalculate_product_rating, :if => :approved?
after_destroy :recalculate_product_rating
validates :name, presence: true
validates :review, presence: true
validates :rating, numericality: { only_integer: true,
greater_than_or_equal_to: 1,
less_than_or_equal_to: 5,
message: Spree.t('you_must_enter_value_for_rating') }
default_scope { order("spree_reviews.created_at DESC") }
scope :localized, ->(lc) { where('spree_reviews.locale = ?', lc) }
scope :most_recent_first, -> { order('spree_reviews.created_at DESC') }
scope :oldest_first, -> { reorder('spree_reviews.created_at ASC') }
scope :preview, -> { limit(Spree::Reviews::Config[:preview_size]).oldest_first }
scope :approved, -> { where(approved: true) }
scope :not_approved, -> { where(approved: false) }
scope :default_approval_filter, -> { Spree::Reviews::Config[:include_unapproved_reviews] ? all : approved }
def feedback_stars
return 0 if feedback_reviews.size <= 0
((feedback_reviews.sum(:rating) / feedback_reviews.size) + 0.5).floor
end
def set_search
#search=Product.search(params[:q])
end
def recalculate_product_rating
self.product.recalculate_rating if product.present?
end
end
Try to add result method after ransack:
#search = Spree::Review.ransack(params[:q]).result

How can I use a single partial to render each object in a collection?

I have a working partial for an instance of my Quote class, _quote.html.erb, I would like to use this same partial to render each object within the collection provided by the index action. However, I am getting stuck and can no longer see where I am going wrong. An instance variable naming issue, a controller crud action format issue? Code below:
quotes_controller.rb
class QuotesController < ApplicationController
before_action :authenticate_user!, only: [ :new, :create, :edit, :update, :destroy ]
# before_action :owners_only, only: [ :show, :edit, :index, :update, :destroy ]
def new
#quote = Quote.new
end
def create
# #quote = Quote.new(quote_params)
#quote = current_user.quotes.new(quote_params)
if #quote.save
redirect_to quote_url(#quote), notice: 'Quote request created'
else
render :new
end
end
def show
# #quote = Quote.find(params[:id])
#quote = current_user.quotes.find(params[:id])
end
def index
#quotes = current_user.quotes.all
end
def edit
#quote = current_user.quotes.find(params[:id])
end
def update
#quote = current_user.quotes.find(params[:id])
if #quote.update_attributes(quote_params)
redirect_to quote_path(#quote)
else
render :edit
end
end
def destroy
#quote = current_user.quotes.find(params[:id])
#quote.destroy
redirect_to quotes_path
end
private
def quote_params
params.require(:quote).permit(:gla, :prev_cover, :co_name, :co_number, :postcode, :industry, :lives_overseas,
:scheme_start_date, :payment_frequency, :commission_level)
end
end
_quote.html.erb
<section id="quote">
<div class="container">
<div class="row">
<div class="col-md-4 text-center">
<div class="panel panel-success panel-quote">
<div class="panel-heading">
<strong>GLA</strong>
</div>
<div class="panel-body text-center">
<p><strong>Quote ID; <%= #quote.id %></strong></p>
</div>
<table class="table table-bordered">
<tr>
<td>Company name</td>
<td><%= #quote.co_name %></td>
</tr>
<tr>
<td>Company number</td>
<td><%= #quote.co_number %></td>
</tr>
<tr>
<td>Office postcode</td>
<td><%= #quote.postcode %></td>
</tr>
<tr>
<td>Industry</td>
<td><%= #quote.industry %></td>
</tr>
<tr>
<td>Previous cover</td>
<td><%= #quote.prev_cover %></td>
</tr>
<tr>
<td>Lives overseas</td>
<td><%= #quote.lives_overseas %></td>
</tr>
<tr>
<td>Scheme start date</td>
<td><%= #quote.scheme_start_date %></td>
</tr>
<tr>
<td>Payment frequency</td>
<td><%= #quote.payment_frequency %></td>
</tr>
<tr>
<td>Commission level</td>
<td><%= #quote.commission_level %></td>
</tr>
</table>
</div>
</div>
</div>
index.html.erb
<% #quotes.each do |q| %>
<%= render :partial => "quote", :collection => q %>
<% end %>
Am i doing something blindingly obvious here that someone can point out for me, been staring so long I can't see it any more!
If I run:
<% #quotes.each do |q| %>
<%= q.co_name %>
<% end %>
The index page renders the co_name values just fine, showing that the collection does get through.
I think this:
<% #quotes.each do |q| %>
<%= render :partial => "quote", :collection => q %>
<% end %>
Might be something more like this:
<% #quotes.each do |quote| %>
<%= render :partial => "quote", locals: {quote: quote} %>
<% end %>
And then in your partial, at the top, do something like:
<% #quote = local_assigns[:quote] %>
<section id="quote">
<div class="container">
<div class="row">
<div class="col-md-4 text-center">
<div class="panel panel-success panel-quote">
<div class="panel-heading">
<strong>GLA</strong>
</div>
<div class="panel-body text-center">
<p><strong>Quote ID; <%= #quote.id %></strong></p>
</div>
<table class="table table-bordered">
<tr>
<td>Company name</td>
<td><%= #quote.co_name %></td>
</tr>
...
</table>
</div>
</div>
</div>
Then I think you'll be on your way.

Search data by first_name and last_name

I am trying to search the data that comes from two different models via another raport model. I need to filter the data listed in the index view by the user's first and last name.
##How can I search and display only the filtered data in data_filter.html.erb view?
## in raports/index.html.erb:
<div>
<div class="" id="pro_content">
<div class="main_container">
<p id="notice"><%= notice %></p>
<h1>Raports </h1>
<hr>
<%= button_to "Filter the data", {:controller => 'raports',:action=>'data_filter'},class: "btn btn-primary kerkes1", :method => "get" %>
<table class="table ">
<thead>
<tr>
<th>User</th>
<th>Vacation type</th>
<th>Start Data</th>
<th>End Data</th>
<th>Ditet</th>
<td>status</td>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #vacation_requests.each do |vacation_request| %>
<tr class="<%= vacation_request.request_level%>">
<td>
<% #home.each do |u|%>
<% if u.id == vacation_request.user_id%>
<%= u.first_name + " "+ u.last_name%>
<%end%>
<%end%>
</td>
<td>
<% #v_r.each do |vr|%>
<%if vr.id == vacation_request.vacation_type_id %>
<%= vr.vacation_type%>
<% end end%>
</td>
<td><%= vacation_request.start_data %> </td>
<td><%= vacation_request.end_data %></td>
<td>
<%=vacation_request.skip_holidays%>
</td>
<% if vacation_request.request_level == "accepted"%>
<td style = "color: green"><i class="fa fa-check"></td>
<%elsif vacation_request.request_level == "rejected" %>
<td style = "color: red"><i class="fa fa-times"></i></td>
<%else%>
<td style = "color: #daa520"><i class="fa fa-hourglass-half"></td>
<%end%>
<!-- <td><%= vacation_request.description %></td> -->
<td><%= link_to 'Show', vacation_request %></td>
<td><%= link_to 'Destroy', vacation_request, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<!-- <td><%= link_to 'Edit', edit_vacation_request_path(vacation_request) %></td>
<td><%= link_to 'Destroy', vacation_request, method: :delete, data: { confirm: 'Are you sure?' } %></td> -->
</tr>
<% end %>
</tbody>
</table>
<br>
<p>
Shiko ne formatin Excel: <br>
<%= button_to "Excel ",raports_path(format: "xls") ,class: "btn btn-primary ", :method => "get" %>
</p>
</div>
</div>
</div>
<div style="clear:both"></div>
<div style="clear:both"></div>
##In raport.rb:
def client_full_name
"#{User.first_name} #{User.last_name}"
end
def self.search_by_client_full_name(query)
where("(User.first_name || User.last_name) LIKE :q", :q => "%#{query}%")
end
In raports_controller.rb
def data_filter
#ndalo_userin = User.find(session[:user_id])
if #ndalo_userin.status.to_i == 1
redirect_to root_path
end
#home=User.all
#useri = User.find(session[:user_id])
#adminRequest =VacationRequest.where(:request_level => "to_admin")
#vacation_types = VacationType.all
#vacation_requests = VacationRequest.all
if params[:search]
#home = User.search_by_client_full_name(params[:search])
else
#home = User.all
end
# head 404 if #users.blank?
# #raport=Raport.new
end
In data_filter.html.erb
<h3>Search for vacations by fullname </h3>
<%= form_tag raports_path, :method => :get do %>
First_Name:<%= text_field_tag :first_name, params[:first_name]%>
Last_name:<%= text_field_tag :last_name, params[:last_name]%>
<%=print%>
<%= submit_tag "Search", :client_full_name => nil , :class => "btn btn-primary"%>
<%end%>
## how can i search for a certain user displayed in raports/index.html.erb even though firs_name and last_name are not saved in the report model just in user model?
You don't need User.first_name in the query. Also, you need to quote the search string.
def self.search_by_client_full_name(query)
where("first_name LIKE :q OR last_name LIKE :q ", q: "'%#{query.downcase}%'")
end
Use ILIKE or downcase the search string
def self.search_by_client_full_name(query)
where("first_name ILIKE :q OR last_name ILIKE :q ", q: "'%#{query}%'")
end
The first name and last name is only in the user.rb model
You are calling the method on User class
User.search_by_client_full_name(params[:search])
You should move the method to User model
NOTE
Also, This should be in User model
def client_full_name
"#{first_name} #{last_name}"
end

Display all the data in the same page using Rails 3

I want to display all the data present in the DB in same page where my form is present.I have saved one record.Please help me to show all the data after submit in that same page.
My code are as follows.
views/users/index.html.erb
<%= form_for :users,:url => {:action => 'create'} do |f| %>
<p>
Name: <%= f.text_field :name %>
</p>
<p>
Email: <%= f.email_field :email %>
</p>
<p>
content: <%= f.text_field :content %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Content</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#users=User.new
end
def create
#users=User.new(params[:users])
if #users.save
flash[:notice]="User has created"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="User couldnot created"
flash[:color]="invalid"
render 'index'
end
end
end
I want to show in the same index page after submitting the form using Rails 3.Please help me.
This should work
views/users/index.html.erb
<%= form_for :user,:url => {:action => 'create'} do |f| %>
<p>
Name: <%= f.text_field :name %>
</p>
<p>
Email: <%= f.email_field :email %>
</p>
<p>
content: <%= f.text_field :content %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Content</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #users.each do |u| %>
<td> <%= u.name%> </td>
<td> <%= u.email%> </td>
<td> <%= u.content%> </td>
<td> <%= link_to 'Show', u %> </td>
<td> <%= link_to 'Edit', edit_user_path(u) %> </td>
<td> <%= link_to 'Destroy', u, :method => :delete, :data => { :confirm => 'Are you sure?' } %> </td>
</tbody>
</table>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#users=User.all
end
def create
#users=User.new(params[:users])
if #users.save
flash[:notice]="User has created"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="User couldnot created"
flash[:color]="invalid"
render 'index'
end
end
end

Update page with ajax on form submit - nested routes

I'm trying to do something similar to adding comments to blog posts via ajax but i'm struggling to get it working. In my project, a user can have many activities and each activity can have many items.
The routing is as follows:
resources :users do
resources :activities do
resources :items
end
end
ActivitiesController.rb
#rest of code
def show
#activity = Activity.find(params[:id])
#new_item = #activity.items.build
#items = #activity.items.all.order('id DESC')
end
ItemsController.rb
#rest of code
def create
#activity = Activity.find(params[:activity_id])
#item = #activity.items.new(item_params)
respond_to do |format|
if #item.save
format.html {redirect_to user_activity_path(#activity.user_id, #activity)}
format.js
else
format.html {redirect_to :back}
end
end
end
activities/show.html.erb
<div class="row">
<div class="large-6 large-offset-3 columns">
<%= simple_form_for [#activity, #new_item], url: user_activity_items_path(#activity.user_id, #activity), remote: true do |f| %>
<%= f.input :name, required: false, :wrapper_html => { class: 'large-8 columns name' } %>
<%= f.input :cost, required: false, :wrapper_html => { class: 'large-4 columns cost' } %>
<%= f.submit "Add Item", class: 'large-4 columns button' %>
<% end %>
</div>
</div>
<div class="row">
<div class="large-6 large-offset-3 columns item-list">
<table>
<thead>
<tr>
<th>Name</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
<% #items.each do |item| %>
<%= render 'item', item: item %>
<% end %>
</tbody>
</table>
</div>
</div>
activities/_item.html.erb
<tr>
<td><%= item.name %></td>
<td><%= item.cost %></td>
</tr>
items/create.js.erb
#currently empty
Your create.js.erb should look like
$("#getItems").last('tr').after('<%= escape_javascript(render partial: "activities/item", :locals => { :item => #item })) %>');
And on show page replace this by mine.
<div class="row">
<div class="large-6 large-offset-3 columns item-list">
<table>
<thead>
<tr>
<th>Name</th>
<th>Cost</th>
</tr>
</thead>
<tbody id="getItems">
<% #items.each do |item| %>
<%= render 'item', item: item %>
<% end %>
</tbody>
</table>
</div>
</div>

Resources