I have a simple rails form looks something like this
<%= form_for :phrase, url: phrases_path do |f| %>
<p>
<%= f.label :"Enter Your Text" %><br>
<%= f.text_area :text %>
</p>
<%= f.fields_for :order do |builder| %>
<p>
<%= builder.label :"ваш email" %><br />
<%= builder.text_field :email %>
</p>
<% end %>
This form goes to the appropriate controller and in the controller depending on the value(text) of the text area performs some calculations to create a price and then save the order.
And it works just fine. But I have another requirement. Before submitting this application the user can click on a button(inserted somewhere between the form) to know the cost. As I said above the cost is calculated using text of the text_area and some logic present inside some method. I would like to implement the button. On clicking the button an ajax request is started, the value(text) of the text area is retrieved and the cost is calculated depending on some method. This calculated value is then shown on the page.
I know to start an ajax request and update the page. What I dont know is how to get the value of the text_area for the Ajax request. I cannot apply everything in javascript since the computation of cost requires some method which is ruby/rails dependent
Related
How would I go about creating a form that takes what user input as a value and just passes it to the controller without being connected to any model?
Something simple like i.e. calculating tax based on input salary, or other calculation like that, when I show the user a form, let them fill it, and when submitting it would go to the results
<%= form_with url: 'calculator#result' do |form| %>
<%= form.number_field :value, in: 1000.0..20000.0, step: 0.5 %>
<%= form.submit %>
<% end %>
i expected something like this to pass 'value' and redirect to calculator#result when submitting, but the button doesn't really do anything. whereas a form connected to a model seems pretty smart and does it
The form_tag Helper method is usually used for forms that are not linked to a model.
I think this should work:
<%= form_tag("/calculator/result", :method => "get") do %>
<%= label_tag(:value, "Value:") %>
<%= text_field_tag(:value) %>
<%= submit_tag("Submit") %>
<% end %>
I have a controller named Welcome with view called index.
In my index view i have created a small form as such.
<%= form_for :location do |f| %>
<%= f.label :Longitude %><br>
<%= f.text_field :integer %>
<br>
<br>
<%= f.label :Latitude %><br>
<%= f.text_field :integer %>
<p>
<%= f.submit %>
</p>
<% end %>
In this form the user can enter some integer value for longitude and latitude. Once the user enters value for longitude and latitude. They click submit. Upon submit i would like to store these values in my controller. So i am using the following method where i have two instance variables taking values from the form.
def index
#long = params[:longitude]
#lat = params[:latitude]
end
In my routes.rb I have
get 'welcome/index'
post 'welcome/index'
Please tell me where i went wrong. Also if someone can suggest a better way of doing this also i would appreciate it i am new to rails and i want to learn the correct way of doing things so i don't create bad habits early on.
The reason it's not working is because your fields are both named :integer, and since they share the same name, the browser will only send one value.
So, with your code, if you filled in the first field with 'a' and the second with 'b', your params would contain something like this:
{ location: { integer: "aaa" } }
Which obviously isn't what you want! If your HTML looked more like this (I've stripped the layout stuff to make things clearer):
<%= form_for :location do |f| %>
<%= f.label :longitude %>
<%= f.text_field :longitude %>
<%= f.label :latitude %>
<%= f.text_field :latitude %>
<%= f.submit %>
<% end %>
Then you could access the params in your controller params[:location][:longitude] and params[:location][:latitude]
A good idea to see the difference between the effect of your form vs this form would be to inspect the html. Take a look at the input name attributes, and label for attributes and see how they match up with the params Rails receives. Also, when you post the form, be sure to look in your server log to see the params! :)
After reading your question, I think you want to see how controllers, views and models work. For learning purpose you can generate scaffold and study the generated code.
For example, generate a model GeoLocation, related controller and views by this:
rails g scaffold GeoLocation longitude:string latitude:string
Now fire up rails server and browse http://localhost:3000/geo_locations/new and save your long, lat. I wrote this answer to give you some guidance.
You can follow these excellent books:
The book of Ruby
The Rails 4 Way
I've previously been able to use the following code to link to an external site listed in a form. However, I can't get it work here. My controller defines the parameter and it's in the view and in my db/schema (t.string "website").
Is there something I'm missing?
/show
<p>
<strong>Website:</strong>
<%= link_to #woman.website %>
</p>
The website shows up in active admin in my db, but not as a link. This is what the form partial asks the user to input:
/_form
<div class="form-group">
<%= f.label :website %><br>
<%= f.text_field :website, class: "form-control" %>
</div>
Every time I click the link, it just reloads the same page I'm on. Would appreciate any insight.
You missed the href part, try this
<%= link_to #woman.website, #woman.website %>
I am useing a form_for helper to collect data on the client side of my application. However something weird is happening. I am not collecting the :name and :description and they are both returning as nil. this is my code:
<%= form_for #type do |f| %>
....
<%= f.text_field :name, :class => "col-xs-4" %>
<%= f.text_field :description, :class => "col-xs-4" %>
<%= f.submit %>
....
Do I need to make a fields_for under the form_for to get this working? It is a bit tricky because I am using #type which in this case is set up to tell the view which kind of attr. they are looking at. For example, this line:
<%= f.label #type %> <label> Description</label>
depending on what view you are on shows ether:
Group Description
or
Tag Description
and because they are both technically the same, I am using the same index for both. I hope I am clear with my issue and thank anyone who understands my problem and solution.
The param name will depend on the object you pass.
If #type contains an instance of Group, then you will get the params under params[:group], and if it is an instance of Tag, the you will get them on params[:tag]
<%= form_for #type do |f| %>
<%= f.label :name, "#{#type.model_name} Description" %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
Note the label definition. The way you are defining it will create 2 labels and the second one will not be linked to any field.
fields_for is normally used when you are creating several objects within the same form, for instance a Project and several tasks associated to it.
Hope this helps.
update:
If #type is a string or symbol it should work too. The tradeoffs using this approach will be that if there are any validation errors when creating the object, those will not be displayed and the fields will not be prefilled with the input that the user gave before submitting the form, forcing the user to enter all the information again and guessing which was the validation error (you can initialize it from the received params, but that complicates the code readability)
The unique thing different in your view would be the label definition.
<%= f.label :name, "#{#type} Description" %>
I've researched a while on this topic but haven't found a real solution to what I am trying to achieve.
I'm working with a nested one-to-many nested form (Project has many Tasks). And each task has many attributes, e.g. type, assigned_individual, due_date, etc. I got no problem having the parent Project and the nested child model Tasks saved/updated on one submit. But what I need to achieve seems to be the opposite of this effort. I need one Ajax save call for each Task besides the global submit. so when the task list gets long, users don't have to worry about losing what they have written earlier for the other tasks. They can click that save button and get's a feedback saying that what he has entered for the task has been saved.
Currently the Project is in a form_for wrapper, and the Tasks are in fields_for partial
these are the simplified version of what I have right now.
Here is the form in edit.html.erb
<%= form_for #project do |f| %>
<p>f.text_field :title</p>
<p>f.text_field :author</p>
<%= render :partial=> 'tasks', :collection=> #project.tasks %>
<%= f.submit 'submit' %>
<% end %>
Here is tasks partial:
<%= fields_for :tasks do |f| %>
<label>Category</label>
<%= f.text_field :category%>
<label>Description</label>
<%= f.text_field :description%>
<label>Author</label>
<%= f.text_field :author%>
<label>Assigned Individual</label>
<%= f.text_field :assigned_individual%>
<label>Notes</label>
<%= f.text_area :notes%>
<label>Due Date</label>
<%= f.text_field :due_date%>
<button onclick='update_task();'>Save Task</button>
<% end %>
Since I cannot have multiple submit button in one form, what I can think of right now is to use jQuery to collect every single user entry in that partial and pass them as a big hash back to the Task controller update method.
update_task()
but is there a cleaner way?