Header Navbar Form URL issue in Rails - ruby-on-rails

I have a search form in the header navbar so that it is always available to users, but I can't get it to send to the correct controller/action. It works correctly when already on the page for search results, when used from any other page it sends to the controller/action for the current page . I found a similar problem here Rails 4 Bootstrap Search Form in Navbar but I did not run into the issue in the same fashion, nor did it help me. Where am I going wrong?
The form in my header navbar
<ul class="navbar-form navbar-left">
<form class="form-inline">
<%= form_tag(search_path, method: :get) do %>
<%=select_tag :gender, options_for_select
([['Male & Female', 'All'],['Male', 'Male'],
['Female', 'Female']]) %>
<%= label_tag "Include unavailable" %>
<%= check_box_tag :unavailable %>
<%= submit_tag "Search", class: "btn btn-success navbar-btn" %>
<% end %>
</form>
</ul>
Routing
get '/search', to: 'searches#search'
I have tried building the form both as form_for and form_tag, as well as URL options with either to force the correct controller/action, to no avail. It only appends the form params to the current url.
What am I missing?

I think I see the issue now.
<form class="form-inline">
<%= form_tag(search_path, method: :get) do %>
is actually putting two form tags on your page. You want to get rid of the outer <form> tag and add a class: 'form-inline' to your form_tag call.
You'll want a name on that route too:
get '/search', to: 'searches#search', as: 'search'

Related

Rails 5 simple search form just won't work

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.

form_for was put inside fields_for

I'm having a problem with form_for and fields_for.
So, my problem is:
I had a form_for, and inside this form_for, I use a fields_for. Inside this fields_for, I use a form_tag (i used ajax for this form_tag).
But when I view the generated HTML, it didn't display form_tag, it only display form_for. And I didn't understand why.
Please explain for me, why it didn't display form_tag.
Here is my form_for:
<div class="row">
<%= form_for #real_estate, url: admin_real_estate_update_path do |f| %>
<%= f.fields_for(:client) do |client| %>
<%= text_field :real_estate, :assessment_start_at, value: #real_estate.assessment_start_at %>
<%= render partial: "admin/real_estate/form/assessment", locals: {real_estate_id: #real_estate.id} %>
<% end %>
<%= f.submit "Submut", class: "btn btn-primary"%>
<% end %>
</div>
Here is my form_for which i put inside fields_for:
<%= form_tag admin_search_assessment_path(real_estate_id), method: :post, remote: true do %>
<%= text_field_tag :company_name, params[:company_name] %>
<%= submit_tag "Submit" %>
<% end %>
And i tried to add <form></form> follow as:
<div class="row">
<%= form_for #real_estate, url: admin_real_estate_update_path do |f| %>
<form></form>
<%= f.fields_for(:client) do |client| %>
<%= text_field :real_estate, :assessment_start_at, value: #real_estate.assessment_start_at %>
<%= render partial: "admin/real_estate/form/assessment", locals: {real_estate_id: #real_estate.id} %>
<% end %>
<%= f.submit "Submut", class: "btn btn-primary"%>
<% end %>
</div>
And form_tag was display, but form_for didn't display.
Update:
So, i used $("form_2").submit(function() {....}); to solve this problem.
Actually, i still want to use form-nested.
Inside this fields_for, I use a form_tag (i used ajax for this form_tag)
N'est pas possible, mon ami.
--
Here's how it works...
form_for and form_tag both generate pure HTML forms:
<form action="/action" method="POST">
</form>
Many people get confused about how Rails works - it's really quite simple. Rails employs "helper" methods to generate pure HTML which your browser can read.
Browsers only understand HTML/CSS at the moment. Thus, whenever you send a request to Rails - it has to return that data, otherwise a "web page" simply wouldn't be able to be processed.
Thus, when you ask whether you can nest forms, you have to abide by how the forms work in pure HTML (spec):
Note you are not allowed to nest FORM elements!
HTML fill-out forms can be used for questionaires, hotel reservations,
order forms, data entry and a wide variety of other applications. The
form is specified as part of an HTML document. The user fills in the
form and then submits it. The user agent then sends the form's
contents as designated by the FORM element. Typically, this is to an
HTTP server, but you can also email form contents for asynchronous
processing.
In short, it means that everything within a <form> tag is counted as a form by HTTP. This means that if you have another <form> tag, it's going to cause an error, preventing either from working.
You know this already (otherwise you wouldn't have mentioned ajax).
Your main problem is the use of <form></form> inside your current <form> object. This will confuse HTML profusely, and thus I would recommend replicating the submission of a form, without the <form> object itself:
#app/views/admin/real_estate/form/assessment.html.erb
<%= text_field_tag "[company_name]", params[:company_name], id: real_estate_id %>
<%= button_tag "Submit", type: "button" , data: { id: real_estate_id } %>
#app/assets/javascripts/application.js
$(document).on("click", "button", function(e){
e.preventDefault();
var real_estate_id = $(this).data("id");
$.ajax({
url: "path/to/real/estate/form/assessment/" + $(this).data("id")),
data: {company_name: $("input[type=text]#" + real_estate_id).val()}
success: function(data) {
//do something on success
},
error: function(data) {
//do something on error
}
});
});
This code will still output what you need.
The difference will be two-fold:
The user will experience the same functionality (the input will still be present)
The embedded form will be passed to the main "form" submit, but will not be passed through your strong params method (making it
invisible to your controller)
In effect, you're replicating the functionality of an HTML form through Ajax. Whilst I still wouldn't do it this way, it will give you the functionality you require.

Form without action Ruby on Rails

I have been recently working with Ruby on Rails and have run into an issue that I can not quite figure out. I need to create a bunch of form mockups, that do not function. That is they should have the submit button, but it should not do anything upon being clicked. Normally using html I would do something along the lines of
<form action="#">
</form>
Trying to convert this to use Rails form helpers, I have done the following
<%= form_tag "#" do %>
<%= label_tag :username, "Username: " %>
<%= text_field_tag :username %>
<br />
<%= label_tag :password, "Password: " %>
<%= password_field_tag :password %>
<br />
<%= submit_tag "Login" %>
<% end %>
This generates a form that is similar to what I want to achieve, however when clicking the submit button it tries to access /# via post which is not the desired result. Currently the only thing I can think of to achieve this is to set the disabled attribute of the button, but is there a better way?
Unfortunately this can't be achieved with form helpers. Defining a form_for or a form_tag requires an action for the form. You can set
:action => "#"
But this will require including the action in routes -> having a controller with action for it -> rendering some page yet again.
You could manipulate the form after loading with javascript however (sust remember to set :remote to true - ). Or alternatively, if you insist on using the form helpers - replace the submit_tag with a button_tag:
<%= button_tag "Login", :type => 'button'%>
Try
<% form_tag "#", :onSubmit => "return false" do %>
Have you tried with button_tag instead of submit_tag? See here. Just make sure you don't use the default, or you will be right back where you started.

Modifying parameters passed to external url form with Ruby on Rails

I need to include an external search form in my main layout view, such that it is displayed with every page render. At the moment, in my layouts/main.html.erb I have:
<div style="float: right";>
<% form_tag url_for("http://search.example.co.uk/search"), {:method => :get} do %>
<%= text_field_tag(:q) %>
<%= select_tag(:category, '<option value="all">All</option> <option value="dogs">Dogs</option> <option value="cats">Cats</option>') %>
<%= hidden_field_tag("site", "Example") %>
<%= hidden_field_tag("btnG", "Search") %>
<%= hidden_field_tag("filter", "0") %>
<%= hidden_field_tag("proxystylesheet", "std_stylesheet") %>
<%= submit_tag "Search" %>
<% end %>
</div>
This currently works, and in the header of all pages rendering the main layout, I have a text field, a drop down and a Search button. On clicking the 'Search' button, the page is directed to http://search.example.co.uk/search with all the parameters.
I need to be able to modify the parameters before the page is redirected. I need to concatenate params[:q] and params[:category] and pass this with the redirection. Is this possible?
Thanks for any help/suggestions.
You should do this by submitting your form to an action which would concatenate all your results and they would in-turn redirect your request to the URL which you have specified along with the parameters that you have processed...

One submit tag, two forms on same page

I am looking for the best approach to this problem. I have two search forms on the same page ( they each search a a different api for info) and I would like to have one submit button and then the relevant api is called dependent on which form has content. So I though I could specify the controller action when submitting on each form like so
<div class="container margin50">
<div class="row">
<div class="span6 offset3 cf formBackground">
<h1>CoverArt Finder</h1>
<h3>Search Movies</h3>
<%= form_tag main_results_path, :method => "get" %>
<%= text_field_tag 'search', nil, :placeholder => 'Enter Film Name Here.....' %>
<h1>OR<h1>
<h3>Search Albums</h3>
<%= form_tag album_album_results_path, :method => "get" %>
<%= text_field_tag 'search', nil, :placeholder => 'Enter Artist Name here.....' %>
<%= submit_tag "search" %>
</div>
</div>
</div>
Obviously this is not working as i always get the results for the movie search parameters. Do i need a conditional statement in there to recognise which form is filled in? I’m a little unsure here.
Any other info needed please ask
Any help appreciated
Thanks
If you're willing to do this client side (JavaScript / jQuery) it shouldn't be much hazzle. On clicking the submit button you could check which form has an value. Some simple sudo code:
on submitButton click:
if formA.someValue != null
post / submit formA
else if formB.someValue != null
post / submit formB

Resources