I have a form_for, which has an input text field, the inputed text is sent to a controller which is doing a search on a table from db.
But I would like to do something different, instead of inputing the text in a text field, I want to create default search queries. Which will be buttons with text, and based on that text a param will be sent to the controller and do the search.
How can I do this? I am using Rails 4
My form_tag
<%= form_tag pos_project(#project), method: :get do %>
<p>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil %>
</p>
<% end %>
What I want to achieve:
Button:(text in the button) -> MyButton
When clicked on this button, the text MyButton will be sent to the controller, the controller will take the param, and query the db table and display the results which contain the text MyButton using the below query.
where("name ## :q", q: query)
Why not use HTML and Javascript:
<!-- in your view -->
<%= form_tag pos_project(#project), method: :get, id: "your_search_form" do %>
<p>
<%= hidden_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil %>
</p>
<% for value in your_preset_values do %>
<%= link_to(value, '#', data: { search_query_value: value }, class: "search-query-link")
<% end %>
And in your coffee.js file:
# A class for the Search form JS
class SearchForm
constructor: ->
# when a search query link is clicked...
$('a.search-query-link').click (e) ->
# find the value from the data attribute
searchQuery = $(this).data('search-query-value')
# assign the value to the hidden field
$("input[type='hidden']#query").val(searchQuery)
# optional - submit the form
$("#your_search_form")[0].submit()
# Called when the document is loaded
jQuery ->
new SearchForm()
You can use "commit" from parameter to find which button is pressed.
So in controller you will get
params[:commit]="button1" # or
params[:commit]="button2" # or
params[:commit]="button3" # based on which button you pressed
Related
In my app I want to set a search form with two buttons. Each one of those buttons should send request to separate controller. Something like this:
<%= form_tag(products_path, method: :get) do %>
Search Field <%= text_field_tag :q %>
<br>
<%= submit_tag 'First controller' %>
<%= submit_tag 'Second Controller' %>
<% end %>
Is this even possible? Or rails just impose on developer an "one form - one controller" way?
Use JavaScript to change the form URL based on the button clicked.
<%= form_tag(first_controller_path,id: 'search-form', method: :get) do %>
Search Field <%= text_field_tag :q %>
<br>
<button type='submit' id="form-submit-button">First Controller</button>
<button type='button' id="second-controller-button">Second Controller</button>
<% end %>
<script>
$(function(){
$("#second-controller-button").on("click",function(e){
e.preventDefault();
var form = document.getElementById('search-form');
form.action = '<%= second_controller_path %>' ;
form.submit(); // Or you could also try document.getElementById("form-submit-button").click();
})
});
</script>
HTML5 added some attributes to INPUT and BUTTON elements. One of them is formaction so you can set the action triggered by each button independantly and it overrides the default form action.
<%= form_tag(products_path, method: :get) do %>
Search Field <%= text_field_tag :q %>
<br>
<%= submit_tag 'First controller' #triggers the default action %>
<%= submit_tag 'Second Controller', formaction: another_path %>
<% end %>
https://www.w3schools.com/tags/att_input_formaction.asp
You already defined form_tag with products_path through which the controller method is already defined.
So answering your question, you can't pass send requests to two different controllers with one form.
If you want to pass some status with buttons try adding some attributes to the buttons and differentiate them inside the controller.
I have a navbar shared across all views by rendering it in application.html.erb with this form in it:
<form class="form-inline d-none d-lg-inline-flex">
<%= form_tag search_query_path, method: :get do |f| %>
<%= text_field_tag :query, params[:query], class: "form-control", placeholder: "Search" %>
<%= submit_tag "Search", name: nil %>
<% end %>
</form>
I want to search for similar titles in the Post model.
The methods are in the PostsController as follows:
def search_query
#results = Post.find_by_sql("SELECT * FROM posts WHERE title LIKE '%#{params[:query]}%'")
end
def search_query_params
params.require(:post).permit(:query)
end
private :search_query_params
The problem is: the search keeps getting processed by the current controller of the current view. If I'm the the index page (in the PagesController), the query takes place there, just reloading the url like this:
http://localhost:3000/?utf8=%E2%9C%93&query=test+title
I've tried everything and can't find where my logic is wrong.
These are the routes:
get '/search_query', to: 'posts#search_query', as: 'search_query'
form_tag generates a form element, so you are nesting a form inside a form here. Try deleting the outer form.
Right now I have a link_to. It looks like a button the the user. It's an upgrade button so it routes the user to the plans page.
I not only want to route the user to the plans page but I want to pre-select the plan that supports the feature they are upgrading for. I was told that I could pass a query parameter into the link_to? Is the true and what does this look like in my situation? Here is my code.
LINK_TO
<%= link_to edit_account_plan_path, class: "button-big reverse-blue" do %>
HTML
<div class="plan-control">
<%= radio_button_tag :plan_id, plan.id, row.current?, disabled: row.ineligible? %>
</div>
you can pass a query parameter back to your controller something like this:
<%= link_to edit_account_plan_path(feature: 'basic'), class: "button-big reverse-blue" do %>
Then in your controller action routed by edit_account_plan_path, you can set an instance variable which you can use to preselect on your view page:
def edit
#plan = Plan.find_by(feature: params[:feature])
end
Then on your view page:
<div class="plan-control">
<%= radio_button_tag :plan_id, 'Basic', #plan.feature == 'basic' %>
</div>
This is what I'm hoping to do. Currently I have a drop down list of characteristics from which user can choose and search does certain element holds that characteristic. He picks a characteristic from drop down menu and clicks search button. Now I am trying to make a list of links for those characteristics so user can immediately click on certain characteristic.
I will have a couple of links separated with |:
characteristic1_link | characteristic2_link | characteristic3_link
Currently I have the following for drop down search which works:
<%= form_for(#element, method: 'get', url: 'query') do |f| %>
<%= f.collection_select :characteristic_id, Characteristic.all, :id, :name, :include_blank => true %>
<%= f.submit "Search" %>
<% end %>
I am trying to do that with links which I generate like this:
<% #characteristics.each do |characteristic| %>
<%= link_to (characteristic.name), '#' %>
<% end %>
How can I pass :characteristic_id parameter with link and somehow make f.submit to trigger when user clicks on link?
EDIT:
This seems to be working:
<% #characteristics.each do |characteristic| %>
<%= link_to (characteristic.name), query_path(:element => {:characteristic_id => characteristic.id}) %>
<% end %>
Opinions about this method? :)
if i understand your question like that clicking and link_to-anchor selects the option with the same name as the anchors label and submits the form then you might want to...
<%= link_to characteristic.name, '#', class: 'trigger_select' %>
and let your JS do the rest. (untested.)
$('.trigger_select').click( function() {
var href = $(this).attr('href');
$('#select_field').val(href);
$('#form').submit();
});
hope i understood you correcly.
I got a list page and I filter items via links with get params (I can choose many links so query would be like "?param1=value1¶m2=value2"). But also I have to filter it by text field, so I made a form:
<form>
<%= text_field_tag :zip, params[:zip] %>
<%= submit_tag 'OK', :name => nil %>
</form>
But when I submit it, text field param replaces existing query params. So, how to make text field value add to query, not to replace it?
Since I was just dealing with this problem in Rails 4 I thought I'd share my solution.
My page gets loaded with a sport_id parameter, and when the user specifies a sort-order I wanted it to submit a GET request for page.url/event?sport_id=1&sortby=viewers but it wouldn't preserve the sport_id parameter until I added a hidden field tag in the form like so:
<%= hidden_field_tag :sport_id, params[:sport_id] %>
This solution does submit an empty sport_id parameter if that parameter was not in the original request, but that is easily prevented by encapsulating the hidden field in an <% if params[:sport_id].present? %> condition.
Use hidden_field_tag.
Inside of your form, just set hidden_field_tags for the existing GET params, like so:
<% request.query_parameters.collect do |key, value| %>
<%= hidden_field_tag key, value %>
<% end %>
This will ensure that your existing params persist.
Rails 3?
<%= form_tag your_path(params.except(:controller, :action)), :method => :get do %>
<%= text_field_tag :zip, params[:zip] %>
<%= submit_tag 'OK', :name => nil %>
<% end %>