Reputation: 7862
In my application I have search that find proper cars. It works properly. But now I want to use ajax. My search is based on form_object:
class SearchForm
include Virtus.model
include ActiveModel::Naming
include ActiveModel::Validations
include ActiveModel::Conversion
include ActiveModel::Model
def persisted?
false
end
attribute :car_class, String, default: "A"
attribute :handover_location, Integer
attribute :return_location, Integer
attribute :handover_date, DateTime,
default: ->(form, attribute) { Time.current }
attribute :return_date, DateTime,
default: ->(form, attribute) { form.handover_date + 7.days }
attribute :car_body_style, Integer
attribute :car_fuel, Integer
attribute :car_seats, Integer
attribute :car_transmission, Integer
attribute :car_brand, Integer
def submit
Car.search({
handover_date: handover_date,
return_date: return_date,
handover_location: handover_location,
return_location: return_location,
car_class_id: car_class,
car_body_style: car_body_style,
car_fuel: car_fuel,
car_seats: car_seats,
car_transmission: car_transmission,
car_brand: car_brand
})
end
end
I have controller "Cars" with action index which is responsible for searching proper cars:
class CarsController < ApplicationController
before_action :attributes_from_params
skip_authorization_check
def index
@search_form = SearchForm.new(params[:search_form])
@cars = Car.search(@search_form)
respond_to do |format|
format.html
format.js
end
end
private
def attributes_from_params
@car_class = CarClass.where(id: params[:search_form][:car_class]).first.name
@handover_location = "#{Location.where(id: params[:search_form][:handover_location]).first.name }
#{params[:search_form][:handover_date]}"
@return_location = "#{Location.where(id: params[:search_form][:return_location]).first.name }
#{params[:search_form][:return_date]}"
@handover_date = params[:search_form][:handover_date].to_date
@return_date = params[:search_form][:return_date].to_date
@days = @return_date - @handover_date
end
end
My index views looks like this:
#reservation.row
= horizontal_simple_form_for @search_form, {url: cars_path, method: :get, remote: true} do |f|
.basic_search
= f.input :handover_location, label: I18n.t('.handover'), collection: Location.all.map{|hl| [hl.name, hl.id]}
= f.input :handover_date, as: :string, label: false
= f.input :return_location, label: I18n.t('.return') ,collection: Location.all.map{|rl| [rl.name, rl.id]}
= f.input :return_date, as: :string, label: false
= f.input :car_class, label: I18n.t('.car_class') ,collection: CarClass.all.map { |c| [c.name, c.id] }
#search-results.row
#search-filters.col-md-3
%h4.filter-header
= t('search.car_type')
.filter-content.car-type
= f.input :car_body_style, as: :check_boxes, collection: CarBodyStyle.all.map{|x| ["#{x.name}", "#{x.id}"]}, label: false
%h4.filter-header
= t('search.seats')
.filter-content.number-of-people
.checkbox
= f.input :car_seats, as: :check_boxes, collection: [["2", "2"], ["3-5", "5"], ["6+", "6"]], label: false
%h4.filter-header
= t('search.fuel')
.filter-content
= f.input :car_fuel, as: :check_boxes, collection: [["#{t('enumerize.car.fuel.petrol')}", "petrol"], ["#{t('enumerize.car.fuel.petrol_lpg')}", "petrol_lpg"], ["#{t('enumerize.car.fuel.diesel')}", "diesel"]], label: false
%h4.filter-header
= t('search.transmission')
.filter-content
= f.input :car_transmission, as: :check_boxes, collection: [["#{t('enumerize.car.transmission.manual')}", "manual"], ["#{t('enumerize.car.transmission.automatic')}", "automatic"], ["#{t('enumerize.car.transmission.semiautomatic')}", "semiautomatic"]], label: false
#search-cars.col-md-9
= render @cars
%br/
= f.submit t('home.search'), class: "btn btn-default pull-right"
and "_car" partial:
.single-car
.row
.car-img.col-sm-2.col-md-3.col-lg-4
= image_tag image_path("portal/car-sample.jpg"), width: "140", height: "26"
.car-info.col-sm-7.col-md-7.col-lg-6
%h2= car.car_model
%p.location
= car.rental_company.name
%br/
= car.rental_company.correspondence_address.to_label if car.rental_company.correspondence_address
.details
%span.passengers
= car.seats
%span.doors
= car.doors
%span.air-conditioning
= car_air_condition(car)
%span.gearbox
= car.transmission.try(:text)
%span.fuel
= car_fuel(car)
.other-details
= t('search.regulations')
|
= t('search.distance_limit')
BRAK DANYCH
= image_tag image_path("portal/mastercard.jpg"), width: "26", height: "15"
= image_tag image_path("portal/visa.jpg"), width: "32", height: "10"
.car-price.col-sm-3.col-md-2.col-lg-2
%p.overall-price
= number_to_currency(car.price_for_day(@handover_date, @return_date) * @days)
%p.daily-price
= t('search.for_day')
= number_to_currency(car.price_for_day(@handover_date, @return_date))
%p.deposit-price
= t('search.caution')
Brak Danych
= hidden_field :test, "as"
= link_to t('search.reservate'), new_reservation_path(search_form: params[:search_form], car: car.id), class: 'btn'
%hr/
I've also created an index.js.erb file which looks like this:
$("#search-cars").html("<%= escape_javascript(render(@cars)) %>");
This simple ajax search works properly but I must click chceckbox and then click submit button. I want to have checkboxes which are also submit buttons. Is there any way to do this thing? I don't have to much expierience with ajax so I will be very greatful for any help.
Upvotes: 2
Views: 6079
Reputation: 76774
We've done Ajax search before (you can check here)
The way to do it is quite simple. I know you've fixed it, but I guess having more examples will give you some really nice ideas:
--
Ajax
Ajax is very simple when you understand it
It basically makes an asynchronous request to your server through javascript, allowing you to render the response on the page. The way it works is to add to the http
protocol (which basically just responds to single requests made to the server). Ajax essentially gives you the ability to create a "no refresh" experience
Example
Routes
#config/routes.rb
match 'search(/:search)', :to => 'products#search', :as => :search, via: [:get, :post]
--
View (we use form_tag
- not form object
)
<%= form_tag search_path, :method => :post, :id => "SearchForm" do %>
<%= text_field_tag :search, params[:search], placeholder: 'Search your favourite products or brands', :autocomplete => :off, :id => 'SearchSearch' %>
<%= image_submit_tag('nav_bar/search.png', title: 'Search', class: 'search_submit', data: { "placement" => "bottom" }) %>
<% end %>
--
Controller
#app/controllers/products_controller.rb
def search
@products = Product.search(params[:search])
respond_to do |format|
format.js { render :partial => "elements/livesearch", :locals => {:search => @products, :query => params[:search]} }
format.html { render :index }
end
end
--
JS
#app/assets/javascripts/application.js
$(document).ready( function() {
var base_url = window.location.protocol + "//" + window.location.host;
$('#SearchSearch').searchbox({
url: base_url + '/search/',
param: 'search',
dom_id: '#livesearch',
loading_css: '#livesearch_loading'
})
});
Upvotes: 4
Reputation: 7862
I do it in other way. I've add code that submits the form after checkbox click.
$('#search-filters input[type=checkbox]').click ->
$(this).closest("form").submit()
Now everything is working fine.
Upvotes: 1
Reputation: 646
Follow these steps:
This should solve your problem! :)
Upvotes: 2