I try to create simple search engine but I meet some problmes. I have several search_field in my form and if either is empty should returns all objects. Otherwise when it has any content it should be selected by that content. Below is my sample form:
<%= form_for :product, url: products_path, method: :get do |form| %>
<%= form.search_field :brand %>
<%= form.search_field :model %>
<%= form.search_field :price_from %>
<%= form.search_field :price_to %>
<%= form.submit 'Submit' %>
<% end %>
my model method:
def self.search(search)
where(brand: search[:brand]).where(model: search[:model]).where("price >= ?", search[:price_from]).where("price <= ?", search[:price_to])
end
But the above piece of code is wrong because if I leave some field empty it is treated directly as empty string instead of ignore this field and final result is not correct.
Summary this form should work similarly to filter on online store
You'd could do something like this
def self.search(search)
results = all
results = results.where(brand: search[:brand]) if search[:brand]
results = results.where(model: search[:model]) if search[:model]
results = results.where("price >= ?", search[:price_from]) if search[:price_from]
results = results.where("price <= ?", search[:price_to]) if search[:price_to]
return results
end
Good luck.
I have a Rails 3.2.16 legacy app where I record call information and times on each call en_route_time on_scene_time, etc all are datetime fields.
In my Call show view I have an edit times path which redirects to an edit_times view via a get request. This allows you to edit times in case errors were made.
edit_times in calls_controller.rb
def edit_times
#call = Call.find(params[:id])
end
edit_times.html.erb
<%= form_for(#call) do |f| %>
<%= f.label :En_Route_Time %>
<%= f.date_select :en_route_time %>
<%= f.time_select :en_route_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :On_Scene_Time %>
<%= f.date_select :on_scene_time %>
<%= f.time_select :on_scene_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :To_Hospital_Time %>
<%= f.date_select :to_hospital_time %>
<%= f.time_select :to_hospital_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :At_Hospital_Time %>
<%= f.date_select :at_hospital_time %>
<%= f.time_select :at_hospital_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.label :In_Service_Time %>
<%= f.date_select :in_service_time %>
<%= f.time_select :in_service_time,
:combined => true,
:default => Time.zone.now,
:include_blank => true,
:minute_interval => 1,
:time_separator => "",
:start_hour => 00,
:end_hour => 23 %>
<%= f.button :Submit %>
<% end %>
This works fine, however when editing times if a time is not populated it will update_attributes with a default time when blank is selected 0:00.
So I wrote the following private method in calls_controller' to allow blank times if the5iparams is blank on the update action and use abefore_filter` to trigger it.
calls_controller.rb
before_filter :filter_blank_call_times, only: [:update]
def filter_blank_call_times
if params[:call]['en_route_time(5i)'].blank?
params[:call]['en_route_time(1i)'] = ""
params[:call]['en_route_time(2i)'] = ""
params[:call]['en_route_time(3i)'] = ""
params[:call]['en_route_time(4i)'] = ""
params[:call]['en_route_time(5i)'] = ""
end
if params[:call]['on_scene_time(5i)'].blank?
params[:call]['on_scene_time(1i)'] = ""
params[:call]['on_scene_time(2i)'] = ""
params[:call]['on_scene_time(3i)'] = ""
params[:call]['on_scene_time(4i)'] = ""
params[:call]['on_scene_time(5i)'] = ""
end
if params[:call]['to_hospital_time(5i)'].blank?
params[:call]['to_hospital_time(1i)'] = ""
params[:call]['to_hospital_time(2i)'] = ""
params[:call]['to_hospital_time(3i)'] = ""
params[:call]['to_hospital_time(4i)'] = ""
params[:call]['to_hospital_time(5i)'] = ""
end
if params[:call]['at_hospital_time(5i)'].blank?
params[:call]['at_hospital_time(1i)'] = ""
params[:call]['at_hospital_time(2i)'] = ""
params[:call]['at_hospital_time(3i)'] = ""
params[:call]['at_hospital_time(4i)'] = ""
params[:call]['at_hospital_time(5i)'] = ""
end
if params[:call]['in_service_time(5i)'].blank?
params[:call]['in_service_time(1i)'] = ""
params[:call]['in_service_time(2i)'] = ""
params[:call]['in_service_time(3i)'] = ""
params[:call]['in_service_time(4i)'] = ""
params[:call]['in_service_time(5i)'] = ""
end
end
routes.rb except
resources :calls do
member do
post 'close'
post 'cancel'
post 'note'
get 'opencall'
get 'new_return'
get 'duplicate_call'
get 'edit_times'
put 'update_billing'
post 'dispatch_call'
put 'en_route'
put 'on_scene'
put 'to_hospital'
put 'at_hospital'
put 'in_service'
end
collection do
get "scheduled"
get "call_search"
end
end
This works fine when editing times and allows for a blank time to be entered if the 5i datetime field is blank.
The problem I'm having is when editing/updating a call through the normal edit/update convention, whenever I do edit the call it wipes out whatever times are there.
I'm looking for a way to either write a conditional in the update method in calls_controller.rb where filter_blank_call_times is only called if any of the 5i keys are blank. The way it's working right now is that when you edit times it calls the update action on the calls_controller and sets all of the times to nil. I need to figure out a way to only perform the filter_blank_call_times method when editing times, not when editing/updating a call to prevent call times from being wiped out.
If there is a better way of doing this, such as building another controller for edit_times and nesting that resource under calls or somehow doing a post request instead of utilizing the update action action on the calls_controller I'd love to hear about it.
So in summary, editing times is no problem, but calling this on the update action wipes out the time calls and I need to figure out a way around this.
If my question is not clear or you need more information/code, please let me know.
Here's an except of the params that are passed when calling the update action in calls_controller
Started PUT "/calls/125" for 127.0.0.1 at 2014-10-08 06:59:05 -0500
Processing by CallsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"uH+XDJpZQDH4PNAuOOi7dfLVolfRzziMKWc/rSR6UMg=", "call"=>{"caller_name"=>"James Jelinek", "caller_phone"=>"281-444-2222", "caller_address"=>"", "patient_name"=>"Doe, John", "billing_address"=>"", "patient_dob"=>"2001-10-17", "patient_age"=>"12", "patient_sex_id"=>"1", "insurance_id"=>"4", "nature_id"=>"2", "region_id"=>"2", "transfer_from_id"=>"3", "transfer_from_other"=>"", "facility_from_location"=>"", "transfer_to_id"=>"", "transfer_to_other"=>"123 w 8th st Houston, TX 77088", "facility_to_location"=>"ER Room 2", "service_level_id"=>"1", "special_equipment_ids"=>["", "2"], "transfer_date(2i)"=>"10", "transfer_date(3i)"=>"2", "transfer_date(1i)"=>"2014", "transfer_date(5i)"=>"00:00:00", "wait_return"=>"yes", "parent_call_id"=>"124", "traffic_type"=>"Non-Emergency", "unit_ids"=>["", "1"], "call_status"=>"open"}, "button"=>"", "id"=>"125"}
To check the time against all zeros, nil, or empty this regex should work.
"00:00:00"::=~(/[1-9]/).nil?
=> true
And instead of manually writing everything out you can write code to grab the text before "(5i)" and change all the other values to empty. The code would look something like this:
params["call"].keys.each {|item|
post_text = "(5i)" # Set the target text we're looking for
if !!item[post_text] # If target text matches
if params["call"][item]::=~(/[1-9]/).nil? # Time is all zeros, nil, or empty
pre_text = item[0...item.index(post_text)] # get the text from before target
params["call"].keys.select {|i|
!!i[pre_text] and !i[post_text] #select the OTHER values that match the pre_text
}.each {|like_item|
params["call"][like_item] = "" # set all the OTHER values that match the same pre_text to ""
}
end
end
}
Note if you want to change the (5i) field to blank as well you'd change it to this:
params["call"].keys.each {|item|
post_text = "(5i)" # Set the target text we're looking for
if !!item[post_text] # If target text matches
if params["call"][item]::=~(/[1-9]/).nil? # Time is all zeros, nil, or empty
pre_text = item[0...item.index(post_text)] # get the text from before target
params["call"].keys.select {|i|
!!i[pre_text] #select the values that match the pre_text (including post_text)
}.each {|like_item|
params["call"][like_item] = "" # set all the values that match the same pre_text to ""
}
end
end
}
Either of these get placed inside
def filter_blank_call_times
# CODE HERE
end
I,m using bootstrap-datepicker-rails gem for date picker and want to shoe calender only on icon click(not on clicking text filed).
Write Now I'm using in my form:
= form_for (ServiceExp.new), :remote => true do |s|
%ul
%li
= s.label :position
= s.text_field :position
%li
= s.label :start_date
%p
From
%li
.input-append.date.datepicker
= s.text_field :start_date, :class =>"input-mini"
%span.add-on
.calander-icon
To
.input-append.date.datepicker
= s.text_field :end_date, :class => "input-mini"
%span.add-on
.calander-icon
%li
= s.label :description
= s.text_area :description
= s.submit 'Save',:class => "btn btn-primary"
And in javascript:
$('.datepicker').datepicker();
Here, Calendar shows on both text field and icon because class datepicker on top of both. If use this class only on icon than it show calender only on icon click but not adding value on text field. How can I achieve that one. please give any suggestion !!
Add :"data-date-format" => 'dd-mm-yyyy', :'data-date' => '12/2/2013' # default date
To div container containing input box and span.
Like
%li
.input-append.date.datepicker{:"data-date-format" => 'dd-mm-yyyy', :'data-date' => '12/2/2013'} # default date
= s.text_field :start_date, :class =>"input-mini"
%span.add-on
.calander-icon
How can I add my own name to an input, e.g. a textbox?
i.e. how can I customize the input name that is displayed beside an input?
Here is my code:
- title "Add a NEO"
= simple_form_for #neo do |f|
= f.input :name
br
- for obs in #observations do
= simple_form_for obs do |o|
table
tr
td = o.input :ra
td = o.input :dec
= f.button :wrapped, "Create NEO"
I would like to specify text for o.dec and o.ra. How can I do that?
- title "Add a NEO"
= simple_form_for #neo do |f|
= f.input :name
br
- for obs in #observations do
= simple_form_for obs do |o|
table
tr
td = o.input :ra, :label => "Right Ascension"
td = o.input :dec, :label => "Declination"
= f.button :wrapped, "Create NEO"
I'm using Rails 3.0.7 with awesome_nested_set and I'm trying to create a nested form which will allow me to enter a category and sub categories all in one create form.
Here is my category model, controller & form
category.rb
class Category < ActiveRecord::Base
acts_as_nested_set
end
categories_controller.rb
class CategoriesController < InheritedResources::Base
def new
#category = Category.new
3.times { #category.children.build(:name => "test") }
end
end
form
= form_for #category do |f|
-if #category.errors.any?
#error_explanation
%h2= "#{pluralize(#category.errors.count, "error")} prohibited this category from being saved:"
%ul
- #category.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name
%p Sub categories
= f.fields_for :children do |child|
= child.text_field :name
.actions
= f.submit 'Save'
The problem here is that I only end up with one sub category in my form and it doesn't have name set to 'test' so I don't believe that it's actually the child of the category showing here.
What am I missing here?
Can this be done?
Is there an easier way?
Update
If I change my form to the following then it displays three sub categories each with name set to 'test'. This will not save correctly though.
%p Sub categories
- #category.children.each do |sub|
= f.fields_for sub do |child|
= child.label :name
= child.text_field :name
%br
Found my answer and wrote a wiki page about it here:
https://github.com/collectiveidea/awesome_nested_set/wiki/nested-form-for-nested-set