Rails: Two Different Submit buttons in a form - ruby-on-rails

I'm trying to create a simple form with two different submit buttons: one which will do a normal submit, and one which will do an ajax submit and render a partial. But I'm not sure how to do this because both go towards the same create action. I tried something like this:
/views/layouts/_form.html.erb:
<div id="theform">
<%= form_for(#user, :remote => true, :form_to_validate => 'user') do |f| %>
Name: <div id='name'><%= f.text_field :name %></div><br/>
Email: <div id='email'><%= f.text_field :email %></div><br/>
Phone Number: <div id='phone_number'><%= f.text_field :phone_number%></div><br/>
<%= f.submit "Normal Submit", name:'normal' %>
<%= f.submit "Ajax Submit" %>
<% end %>
</div>
app/controllers/user_controller.rb:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if params[:normal]
render :partial => "layouts/user"
end
end
EDIT: this may seem like an odd task but it was an assignment given to me to demonstrate I could do it both ways. I know how to do the AJAX submit and the normal submit separately but my confusion is with having two submits in the form! :)

Why not write some JS that listens to the click or submit and you route it in JS if its ajax $.ajax to the ajax location else let it go through normally if its not and dont stop the propagation.

I don't think you need two submit buttons. Have the ajax button simply call the $.ajax method and send your data.
Alternately, you could have the ajax button call $('#formid').submit() after converting the form to be ajax, using whatever method you use to do so. This is probably the easier of the two methods.

Related

Why doesn't submitting this form raise an error?

Hi I am wondering why I am not getting an error when I submit a form with an action set to a method that isn't set up yet. After submission it just keeps me on the same page with different url parameters.
Here is the form:
<form>
<%= form_tag( drop_piece_path, :method => "post" ) do %>
<% 7.times do |col| %>
<%= label_tag col %>
<%= radio_button_tag(:column, col) %>
<% end %>
<%= submit_tag("Enter move")%>
<% end %>
</form>
Here is my route:
post 'drop_piece' => 'connect_four#drop_piece', as: :drop_piece
And here is my drop_piece method in my controller:
def drop_piece
redirect_to fake_path #should raise an error because fake_path is not a real path
end
I am confused because since my form is set to submit to the drop_piece_path shouldn't that trigger the drop_piece method in my controller? Which should then raise an error?
Again, right now after form submission the application just stays on the same page with params corresponding to whichever radio button I selected.
Why doesn't this trigger my drop_piece method in my connect_four controller? Thanks for the help.
This happens because you have nested form tags. One is <form> tag and another one is <%= form_tag... %>. HTML spec doesn't allow nesting forms, so the outer one is submitted. Since it doesn't have action attribute, it is submitted to the current URL.

Rails render lookup value

First: Enter a certain emp_no using the textfield.
Second: I am trying to render/show the lookup value from a table through .
Here's the view:
<div class="field">
<%= f.label :emp_no %><br />
<%= f.text_field :emp_no%>
</div>
<div class="field">
<%= f.label :emp_name %><br />
<div><label><%= #emp_name %></label></div>
</div>
Here's my controller:
before_filter :customer
def customer
#emp_name = where(Employee.params[:employee_code])
end
Any inputs are much appreciated! Thank you!
We've achieved something similar at http://firststopcosmeticshop.co.uk (try the search at the top)
Search
What you're looking for, simply, is a piece of functionality which helps you search your data.
This can be achieved relatively simply, but you have to make sure your syntax is correct:
#config/routes.rb
resources :employees do
get :search
end
#app/controllers/employees_controller.rb
class EmployeesController < ApplicationController
layout: Proc.new {|controller| controller.request.xhr? ? false : "application" }
def search
#emp_names = Employee.where code: params[:employee_code]
end
end
#app/views/employees/search.html.erb
<% #emp_names.each do |employee| %>
<%= employee.name %>
<% end %>
This setup will provide you with the ability to load the search items if you wanted to show them, allowing you both the ability to use ajax (detailed below), or just plain HTML / HTTP
Ajax
If you wanted to use Ajax to deliver "real time" results, you'll want to use the following details:
#app/assets/javascripts/application.js
$(document).on("ajax:success", "form", function(status, data, xhr){
$(this).append(data);
});
This should render the results wherever you want on your front-end (requesting) page. The trick lies in the controller's assertion of the layout depending on the type of request received (HTTP or XHR)
Form
Finally, your form needs to reflect the functionality you wish to define. Currently, you don't have any way to send the request to your emp_names method, and so you need to create a better way to manage it:
#view
<%= form_tag employees_search_path, remote: true do %>
<%= text_field_tag :input %>
<%= submit_tag %>
<% end %>
Of course, the form can change considerably, but it basically means that you will send a simple request to your employees_search_path, which will then give you the capacity to manage the response in the controller; either normally, or with Ajax

Rails - Multiple forms, different Models (Objects), one submit button

I have a view with 3 forms, Schedules, Workouts and Exercises, all behaving like an edit form, each. And one submit(save) button in the all the view.
When I click on the save button. Every data changed on those forms should be updated after click.
What is the best solution for this ? Javascript updating each data separated ? How to do that ? Is there a more Rails way to do this easily ?
My difficulty is how to integrated all those models in one view, while all this is happening in the show(view) from the Student model.
If you're implementing something like a profile / edit page (where you can save all the records at once), the two ways I would look at would either be to save the forms via Ajax, or use a single submit method to handle them
Ajax
The ajax method would be the most conventional:
Every form you submit will go to the form's own update method in the backend
Each form could be handled by a single button, but it's best to split them up
#app/controllers/profile_controller.rb
def edit
#schedules = Schedule.all #-> not sure how many records you're using
#workouts = Workout.all
#exercises = Exercise.all
end
#app/views/profile/edit.html.erb
<%= form_for #schedule do |f| %>
<%= f.text_field :test %>
<% end %>
# -> other forms
<%= button_to "Save", "#", id: "save" %>
#app/assets/javascripts/application.js
$("#save").on("click", function() {
$("form").submit(); // we'll have to define the form to submit
});
Single
If you submit all the forms as one, you'll have to encase them all in a single form, as sending different errors. This could be achieved by using _, and handled in the backend by looping through the different params, saving each one individually.
I'd do this:
#app/controllers/application_controller.rb
def submit
types = %w(schedules exercises workouts)
for type in types do
type.constantize.update_attributes()
end
end
This allows you to create a form with the different data types submitted in the same action:
#app/views/profile/edit.html.erb
<%= form_tag profile_submit_path do %>
<%= fields_for #schedules do |f| %>
<%= f.text_field :title %>
<% end %>
# -> fields_for for the other objects
<% end %>
This will allow you to send the updated objects to your controller, allowing them to submit
If all of your models (Schedules, Workouts and Exercises) are associated, using fields_for should be a good option.
From the above link:
<%= form_for #person do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for :permission, #person.permission do |permission_fields| %>
Admin? : <%= permission_fields.check_box :admin %>
<% end %>
<%= f.submit %>
<% end %>
Read the guides.
You could have some simple javascript that iterates over all form tags and submits each of them.
Alternatively, if you are going to use javascript anyways, you could follow an AJAXish auto-save approach upon changing any field.
But I think it might be cleaner if you just had one form for multiple models, using fields_for.

edit form submitting to the wrong url and remote: true failing to be picked-up

This has been driving me nuts because it doesnt seem to make any sense.
I want to do something relatively simple.
Display an edit form in a modal on the index page.
I have the following code looping through a collection of sites
<%= render(#sites) %>
<%= will_paginate #sites %>
Within the sites partial i have the following form hidden away
<%= simple_form_for site, remote: true do |f| %>
<%= f.input :name %>
<%= f.input :matter %>
<%= f.submit "Save", :class => "button gr thirt", id: "site_save" %>
<% end %>
instead of generating the expected HTML i get the following, linking to the show action, am I missing something fundamental here?
<form accept-charset="UTF-8" action="/sites/1" class="simple_form edit_site" data-remote="true" method="post" novalidate="novalidate">
</form>
I was looping through a collection of #sites, a results returned by a call to Site.all
so the object being served to the above form is one of the |site|'s contained within #sites
If you serve a form_for form with a an object retrieved from the database or a 'new record' object like Site.new, it will automatically differentiate and modify the route etc accordingly between the create and the update action.
The site object contained in the #sites block was not recognizable by the form_for. So a quick re factor to request an edit from via ajax, and provide the form with the instance variable created by the edit action (#site = Site.find(params[:id]) ) was recognizable by the form_for helper and meant that the submit action, accordingly adjusted to the correct route.

Ruby on rails parameters are appearing in the url

Hi im having two actions check and display in my controller and i have two views check.html.erb and display.html.erb in the view corresponding to those actions. The check method has a form in it's view
Here is the check.html.erb
<%= form_for :display_command_list, :method => "get", :url => {:action => "display"} do |f| %>
<%= f.label :username %>
<%= f.text_field :username %><br />
<%= f.label :password %>
<%= f.password_field (:password) %><br />
<%= f.submit "Submit"%>
<% end%>
Below are both the actions:
def check
end
def display
#some code here
respond_to do |format|
format.html
end
end
When i fill the form in check view, it submits the form the display action and display action redirects to display view. But the problem is /display.html.erb is having all the parameters submitted in the form in it's url like this - /display?%username%=myname... I think my check method needs something to be written in it so that the form is submitted to display method and the url does not contain the parameters in the form.
I cannot use the parameters in the check method using params as they are empty and it throws a nil object error
Please help
Update:
I used a :method => post instead of a :method=> get in the form_for tag after seeing
how can I hide params I transmit to a method (like form_for seems to do)?
and it does not show any parameters in url.
But now when i go to another view from display.html.erb (say do_something.html.erb) and click on back button to come back to my display.html.erb, it says the web page expired.
Please let me know if iam not clear in asking the question or if iam doing something obviously wrong here..
Why don't you like having parameters in url? That's standard practice. Anyway you should either use POST and face some issues with browser behavior (like returning back to the page as you described or Ctrl-R-ing the page) or use GET and have all parameters in the url. That's how HTTP works.

Resources