I'm trying to create a filter form that user selects dates and sources. The problem is after clicking submit button, in the new page i see that input values are empty. Is there a way to make form remember its values ? Thanks.
<%= form_tag products_path, :method => 'get' do %>
<%= text_field_tag :from %>
<%= text_field_tag :to %>
<% Source.all.each do |source| %>
<%= check_box_tag "sources[]", source.id %>
<%= source.name %><br />
<% end %>
<%= submit_tag "Submit", :name => nil %>
<% end %>
controller
def index
#from = params[:from] ? params[:from].to_datetime : (Time.now-3.day)
#to = params[:to] ? params[:to].to_datetime : (Time.now)
#sources = params[:sources] ? params[:sources] : 1..6
#products = Product.where(:source_id => #sources, :created_at => #from.beginning_of_day..#to.end_of_day)
end
Can't you use the value and checked options from these tags? Here is an example :
<%= form_tag products_path, :method => 'get' do %>
<%= text_field_tag :from, #from %>
<%= text_field_tag :to, #to %>
<% Source.all.each do |source| %>
<%= check_box_tag "sources[]", source.id, #sources.include?( source.id ) %>
<%= source.name %><br />
<% end %>
<%= submit_tag "Submit", :name => nil %>
<% end %>
Related
Hey guys im developing a rails application that stores quotes in a database and then allows you to search through the quotes using a simple search. I have implemented the search form but the results do not appear and I cant figure out why.
controller:
class BasicsController < ApplicationController
def quotations
#quotations = Quotation.all
if params[:search]
#quotations = Quotation.search(params[:search]).order("created_at DESC")
else
#quotations = Quotation.all.order("created_at DESC")
end
if params[:quotation]
#quotation = Quotation.new( params[:quotation] )
if #quotation.save
flash[:notice] = 'Quotation was successfully created.'
#quotation = Quotation.new
end
elsif
#quotation = Quotation.new
end
if params[:sort_by] == "date"
#quotations = Quotation.order(:created_at)
else
#quotations = Quotation.order(:category)
end
end
end
model:
class Quotation < ApplicationRecord
def self.search(search)
where("author_name LIKE ? OR quote LIKE ?", "%#{search}", "%#{search}")
end
end
view:
<%= form_tag basics_quotations_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search], placeholder: "Search Quotations" %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<h3>Quotations</h3>
<ul>
<% for quotation in #quotations %>
<li><%= h quotation.author_name %>: <%= h quotation.quote %></li>
<% end %>
</ul>
<br/>
<% if params[:sort_by] == "date" %>
<%= link_to "Sort by category", :action => :quotations, :sort_by => :category %>
<% else %>
<%= link_to "Sort by date", :action => :quotations, :sort_by => :date %>
<% end %>
<hr/>
<h3>New quotation</h3>
<%= form_for #quotation, :url => { :action => :quotations } do |form| %>
<fieldset>
<legend>Enter details</legend>
<div class="form_row">
<%= form.label :author_name %>
<%= form.text_field :author_name, :size => 20, :maxlength => 40 %>
</div>
<div class="form_row">
<%= form.label :category %>
<% #cats = [] %>
<% Quotation.select('DISTINCT category').map(&:category).each do |element| %>
<% #cats << element %>
<% end %>
<%= form.select(:category,options_for_select([[#cats[0],1],[#cats[1], 2], [#cats[2],3]])) %>
</div>
<div class="form_row">
<%= form.label :new_category%>
<%= form.text_field :category , :size =>20 , :maxlength => 40 %>
</div>
<div class="form_row">
<%= form.label :quote %>
<%= form.text_area :quote, :rows => 2, :cols => 40, :maxlength => 500 %>
</div>
</fieldset>
<p>
<div class="form_row">
<%= form.submit 'Create' %>
</div>
</p>
<% end %>
routes:
Rails.application.routes.draw do
get 'basics/quotations'
resources :quotation, :quotations
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
You've got EVERYTHING in one action, which isn't great. You might want to review some of the simple rails tutorials available.
On the subject of search in particular, note the last four lines of your method...
if params[:sort_by] == "date"
#quotations = Quotation.order(:created_at)
else
#quotations = Quotation.order(:category)
end
So regardless of the results of your seach, you'll replace #quotations at that point with all quotations in either created_at or category order.
It is not wise to place all the stuffs into a single action,your action should be very clear and well defined.But you can achieve what you wanted to do like this.
class BasicsController < ApplicationController
before_action :new_quotation, only:[:search_quotations,:index,:quotations]
def search_quotations
respond_to do |format|
if params[:search]
#quotations = Quotation.search(params[:search]).order("created_at DESC")
else
#quotations = Quotation.all.order("created_at DESC")
end
if params[:sort_by] == "date" && quotations.present?
#quotations = #quotations.order(:created_at)
else
#quotations = #quotations.order(:category)
end
format.js{}
end
end
def quotations
if params[:quotation]
#quotation = Quotation.new( quotation_params)
if #quotation.save
flash[:notice] = 'Quotation was successfully created.'
end
redirect_to root_path
end
end
def index
#quotations = Quotation.all
end
private:
def new_quotation
#quotation = Quotation.new
end
//If you are using rails4 for later version then go for this line.
def quotation_params
params.require(:quotation).permit(:author_name, :quote,:category)
end
end
You need to actually separate the logic into above actions and where 'quotation' action is meant for creating a new quotation and 'seach_quotation' is for searching all the quotations and it should returns js response cause we are going to need this while rendering a partial '_list.html.erb'.
Your view(index.htm.erb) will be looking like this.
<div>
<%= form_tag basics_search_quotations_path, :method => 'get', remote: true do %>
<p>
<%= text_field_tag :search, params[:search], placeholder: "Search Quotations" %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
</div>
#This partial will be used for refreshing the quotations list via remote true feature for searching and sorting.
<div id="quotation_list">
<%= render 'basics/shared/list',{quotations: #quotations} %>
</div>
br/>
<% if params[:sort_by] == "date" %>
<%= link_to "Sort by category", :action => :search_quotations, :sort_by => :category, :remote => true %>
<% else %>
<%= link_to "Sort by date", :action => :search_quotations, :sort_by => :date, :remote => true %>
<% end %>
<hr/>
<h3>New quotation</h3>
<%= form_for #quotation, :url => { :action => "quotations", :controller => "basics" } do |form| %>
<fieldset>
<legend>Enter details</legend>
<div class="form_row">
<%= form.label :author_name %>
<%= form.text_field :author_name, :size => 20, :maxlength => 40 %>
</div>
<div class="form_row">
<%= form.label :category %>
<%= form.select(:category,options_for_select(['Love','Romance','Sadness'])) %>
</div>
<div class="form_row">
<%= form.label :category%>
<%= form.text_field :category , :size =>20 , :maxlength => 40 %>
</div>
<div class="form_row">
<%= form.label :quote %>
<%= form.text_area :quote, :rows => 2, :cols => 40, :maxlength => 500 %>
</div>
</fieldset>
<p>
<div class="form_row">
<%= form.submit 'Create' %>
</div>
</p>
<% end %>
Here is the partial that display the list of Quotations /basics/shared/_list.html.erb
<h3>Quotations</h3>
<ul>
<% for quotation in #quotations %>
<li><%= h quotation.author_name %>: <%= h quotation.quote %></li>
<% end %>
</ul>
Here is the routes you need to add routes.rb
resources :quotation, :quotations
get "basics/search_quotations" => "basics#search_quotations"
post "basics/quotations" => "basics#quotations"
root 'basics#index'
Instead of performing any calculation in views its better to perform it in controller/model if needed.
so instead of this following line in your view
<% #cats = [] %>
<% Quotation.select('DISTINCT category').map(&:category).each do |element| %>
<% #cats << element %>
<% end %>
<%= form.select(:category,options_for_select([[#cats[0],1],[#cats[1], 2], [#cats[2],3]])) %>
You can create an instance variable let's say #categories or something and use it like this
<%= form.select(:category,options_for_select(#categories)) %>
And last but not the least we have to have a search_quotations.js.erb because we are sending ajax request for fetching the search result and returning 'js' response.
$("#quotation_list").html("<%= escape_javascript(render('basics/shared/list', {quotations: #quotations })) %>")
Hi I am new to RoR and I was making a simple math_app. The addition function works fine. Now I'm trying to do a simple subtraction.The subtract controller is invoked and the subtract form is displayed but when I click on subtract the add controller gets invoked and an addition is performed. Where have I gone wrong?
This is my routes.rb:
Rails.application.routes.draw do
get 'subtract/form'
post 'subtract/result'
get 'add/form'
post 'add/result'
end
result.html.erb:
<%= #first %> - <%= #second %> = <%= #result %>
<br/>
<%= link_to 'back', subtract_form_path %>
form.html.erb: (This is the subtraction form)
<%= form_tag subtract_result_path do %>
<%= number_field_tag :first %>
-
<%= number_field_tag :second %>
<%= submit_tag "subtract" %>
<% end %>
subtract_controller.rb:
class SubtractController < ApplicationController
def form
end
def result
#first = params[:first].to_i
#second = params[:second].to_i
#result = #first - #second
end
end
You have problem in views/substract/form.html.erb. It now reads:
<%= form_tag add_result_path do %>
<%= number_field_tag :first %>
-
<%= number_field_tag :second %>
<%= submit_tag "subtract" %>
<% end %>
But it should be:
<%= form_tag substract_result_path do %>
<%= number_field_tag :first %>
-
<%= number_field_tag :second %>
<%= submit_tag "subtract" %>
<% end %>
You should probably also fix route
post '/subtract/result' => 'subtract#result', as: 'substract_result'
Also in views/substract/result.html.erb:
<%= #first %> - <%= #second %> = <%= #result %>
<br/>
<%= link_to 'back', subtract_form_path %>
I am using the following form:
<%= form_for(#document, :remote => true) do |f| %>
<%= f.label :asset, "Document to Upload" %><br />
<%= f.file_field :asset, :class => "behaves", "data-behave" => "passValueOnChange", "data-recipient" => "#campaign_document_name" %>
<%= f.label :name, :class => 'required' %><br />
<%= f.text_field :name, :required => true %>
<%= f.submit "Upload Document", :class => "button" %>
<% end %>
to submit to the following controller:
def create
#document = CampaignDocument.new(params[:campaign_document])
#campaign.documents << #document
respond_to do |format|
format.js
end
end
which should return the following create.js.erb:
<%= remotipart_response do %>
<% unless #document.errors.any? %>
$('.tablewrapper').html( '<%= escape_javascript(render :partial=>'documents_table') %>' );
alertify.success("File Updloaded");
<% else %>
<% #document.errors.each do |attr, msg|%>
alertify.error("<%= msg %>",10000);
<% end %>
<% end %>
<% end %>
but the response is wrapped in a textare tag. Which is pretty odd:
<textarea data-type="text/javascript" response-code="200">
$('.tablewrapper').html('{code for HTML ommited for brevity}');
alertify.success("File Updloaded");
</textarea>
Note
Other, similar styled AJAX functions on the same installation are not behaving this way.
So I am having an issue with an if else statement in the controller. I have 4 radiobuttons on my page and one hidden field. There are also 4 divs where only one can be visible at a time.When a different radiobutton is checked another div is shown. This should work like a 'complex' search interface. In the hidden field I'm inserting a value from 1 to 4 (depending on what radio button is checked). In the controller I'm looking at the value of the hidden field and my functions should change accordingly. My problem is that it does not work. I tried a couple of different things but didn't find an answer to my problem.
Here's my code
View:
<div>
<%= radio_button_tag 'searchRBN', 'patient', true, :onchange => "checkRadioButton()" %>
<%= label_tag :byPatient_patient, "Patient" %>
<%= radio_button_tag 'searchRBN', 'staff', false, :onchange => "checkRadioButton()" %>
<%= label_tag :byStaff_staff, "Staff" %>
<%= radio_button_tag 'searchRBN', 'ocmw', false, :onchange => "checkRadioButton()" %>
<%= label_tag :byOcmw_ocmw, "OCMW" %>
<%= radio_button_tag 'searchRBN', 'mutuality', false, :onchange => "checkRadioButton()" %>
<%= label_tag :byMutuality_mutuality, "Mutuality" %>
</div>
<%= hidden_field_tag(:hidden_one, "1") %>
<div id="searchByPatient">
<%= form_tag patients_path, :method => 'get' do %>
<p>
<%= text_field_tag :search1, params[:search1] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
</div>
<div id="searchByStaff" class="notVisible">
<%= form_tag patients_path, :method => 'get' do %>
<%= text_field_tag :search2, params[:search2] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</div>
Controller:
def index
#staff_all = Staff.all
#ocmw_all = Ocmw.all
#mutuality_all = Mutuality.all
if params[:hidden_one] == '1'
#patients = Patient.searchByName(params[:search1])
elsif params[:hidden_one] == '2'
#patients = Patient.searchByStaff(params[:search2])
else
#patients = Patient.all
end
end
In my model:
def self.searchByName(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
def self.searchByStaff(search)
if search
find(:all, :conditions => ['marriedTo LIKE ?', "%#{search}%"])
else
find(:all)
end
end
Mathias A.
I think your hidden field is outside of your form tag so it will be never submitted to the server.
Another solution would be to simply put a hidden field to each search form you have to identify the corresponding search form on the server.
Example:
<div id="searchByPatient">
<%= form_tag patients_path, :method => 'get' do %>
<%= hidden_field_tag :search_type, :search_by_patient %>
<p>
<%= text_field_tag :search1, params[:search1] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
</div>
I have this form:
in header of my website:
<% form_tag request.path, :method => 'get' do %>
<p>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search User", :name => nil %>
</p>
<% end %>
controller:
def index
#title = "All users"
#users = User.paginate(:page => params[:page])
#users1 = User.simple_search(params[:query]).all
end
model:
acts_as_simply_searchable :columns => [:name, :email]
view
<%= will_paginate %>
<ul class="users">
<%= render #users1 %>
</ul>
<%= will_paginate %>
displays a user
I want to link the submit button to index.html.erb (i have assigned a path in routes.rb). So that the user can look at the search results
You don't do this at the submit button, but at the form_tag URL (the first parameter). It would be something like this:
<% form_tag users_path, :method => 'get' do %>
<p>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search User", :name => nil %>
</p>
<% end %>
Simply change request.path to the desired path.
I think you are missing the '=' sign and string interpolating the 'request.path'
This Worked for me:
<%= form_tag "#{request.path}", method: "get" %>
...the rest of your code ...
<% end %>