Form creates multiple commit buttons in rails - html

i got a form which looks like this:
<h1>Title: <%= #task.title %></h1>
Dates: <% #dates.map do |date| %>
<%= form_tag("/responses/create/", :method => "post", :id => #task) do %>
<%= date.task_date %> <%= check_box_tag "response_checkbox", date.task_date %>
<%= submit_tag("Add") %>
<% end %>
<% end %>
what i want is a list of checkboxes where the user can select one and then submit the form with one button. but the form produces one submit button for every object and i can't figure out why! working on this for hours now ...
here is the html output:
<h1>Title: Weihnachtsball</h1>
Dates:
<form id="#<Task:0x000001067a6320>" method="post" action="/responses/create/" accept-charset="UTF-8">
<div style="display:none">
<input type="hidden" value="✓" name="utf8">
<input type="hidden" value="OaDIn2B0yHVBAY9z7F0IOdiULu5GiqlSJV5+Ft92tbw=" name="authenticity_token">
</div>
2014-11-10 11:11:00 UTC
<input id="response_checkbox" type="checkbox" value="2014-11-10 11:11:00 UTC" name="response_checkbox">
</form>
<form id="#<Task:0x000001067a6320>" method="post" action="/responses/create/" accept-charset="UTF-8">
<div style="display:none">
<input type="hidden" value="✓" name="utf8">
<input type="hidden" value="OaDIn2B0yHVBAY9z7F0IOdiULu5GiqlSJV5+Ft92tbw=" name="authenticity_token">
</div>
2014-11-23 12:14:00 UTC
<input id="response_checkbox" type="checkbox" value="2014-11-23 12:14:00 UTC" name="response_checkbox">
</form>
<input type="submit" value="Add" name="commit">
</div>
</div>

you need to iterate through dates inside the form_tag
<h1>Title: <%= #task.title %></h1>
<%= form_tag("/responses/create/", :method => "post", :id => #task) do %>
Dates: <% #dates.map do |date| %>
<%= date.task_date %> <%= radio_button_tag "response_checkbox", date.task_date %>
<% end %>
<%= submit_tag("Add") %>
<% end %>
should be ok.
Update
I think radio_button_tag is better for you case. After all you want the user to select one box.

Related

How to apply css Styling in Ruby on Rails HTML page?

I am new in RoR. I am trying to add css classes on my form. Here is my form:
<%= form_tag :action => 'create' do %>
<p><label for = "name">Name</label>:
<%= text_field 'books', 'name' %></p>
<div class="form-control">
<p><label for = "author">Author</label>:
<%= text_field 'books', 'author'%></p>
</div>
<p><label for = "price">Price</label><br/>
<%= text_area 'books', 'price'%></p>
<%= submit_tag "Create" %>
<% end -%>
That form controls does not accepting class="form-control mb-4 col-10" placeholder="Patient name" like <input type="text" th:field="*{name}" class="form-control mb-4 col-10" placeholder="Patient name">. How can I apply css styling.
You have to put the class behind a comma
<%= text_field 'books' :name, class:"form-control mb-4 col-10", placeholder="Patient name" %>

Make Submit button use specific route

Question? How do I get my form.submit button to use a specific route? Specifically, the user can fill out this form from any page, and it will submit to a desired controller.
ruby -v 2.3.0
rails 5.0
This form is a feedback form for users to submit feedback. The way it works is, a little icon is available to click so the user can fill out and submit this form from ANY page. The Problem is, unless the user is on the homepage (local/customers), for example, they're on post/13, the form tries to add its URL route on top of the example and I get a "no route matches" ...post/13/customers/questionaire.
This is my route.rb
post 'customers/questionaire' => 'customers#questionaire'
This is the form view
<%= form_for :anything, url: "customers/questionaire" ,multiple:
true do |form| %>
<div><%= form.label :email, 'E-mail:' %>
<%= form.text_field :email , placeholder: 'JohnDoe#yahoo.com' %>
</div>
<div><%= form.label :feedback, 'Type of feedback:' %>
<%= form.text_field :feedback, placeholder: 'Problem, Bug, Idea...' %>
</div>
<div><%= form.label :notes, 'Notes: (Required)' %>
<%= form.text_field :notes, class: 'notes', id: 'notes', placeholder: "Your Feedback" %>
</div>
<%= form.submit "Submit", class: "btn1", id: "button", disabled: true %>
<% end %>
I think you need something like this. Do http://localhost:3000/routes. You will get all the routes in your app
<%= form_with scope: :post, url: customers_questionaire_path do |form| %>
<%= form.text_field :title %>
<% end %>
May be this for lower rails version :)
<%= form_for :customer, scope: :post, url: customers_questionaire_path do |form| %>
<%= form.text_field :title %>
<%= form.submit %>
<% end %>
What matters is the action attribute of the form HTML element, or the formaction attribute of a button or input element.¹
In Rails it's defined like so:²
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
Which yields:
<form accept-charset="UTF-8" action="/search" method="get">
<input name="utf8" type="hidden" value="✓" />
<label for="q">Search for:</label>
<input id="q" name="q" type="text" />
<input name="commit" type="submit" value="Search" />
</form>
This will send the form data to the /search route.
With this approach, each form of your page will use a different route as target for form processing. You could alternatively use the same route and treat multiple use cases inside a single route, but that's not what you're asking.
Alternatively (or in addition to) you can also use the formaction attribute in buttons and inputs, in which case you override the form element's action attribute:³
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<%= submit_tag("Search On Rails", formaction: search_on_rails) %>
<% end %>
Which yields:
<form accept-charset="UTF-8" action="/search" method="get">
<input name="utf8" type="hidden" value="✓" />
<label for="q">Search for:</label>
<input id="q" name="q" type="text" />
<input name="commit" type="submit" value="Search" />
<input name="commit" type="submit" value="Search On Rails" formaction="/search_on_rails" />
</form>
It's as if the first submit button had a formaction="/search" because it's ommited, therefore the action="/search" in the <form> is used.
Other approaches in this question's answers and this one.
For your use case, you'll have to make sure the route /customers/questionaire it's consistent in any URI level (absolute, not dynamic). I lack this particular knowledge in Rails to provide a failsafe solution for this case, although it seems it works as expected in the current default behavior.
So the mistake in your code is using url: with a relative URI when you really want an action: in this line:
<%= form_for :anything, url: "customers/questionaire" ,multiple: true do |form| %>
Use instead:
<%= form_for :anything, url: {action: "customers/questionaire"}, multiple: true do |form| %>
See this question and this one.
In addition to this, instead of hardcoding routes / urls in the code, there's the url_for helper: https://api.rubyonrails.org/v5.1.7/classes/ActionDispatch/Routing/UrlFor.html

How do I prevent my rails created form from allowing more than 1 radio button to be picked?

For some reason when executing this code, the radio buttons that get created aren't mutually exclusive in getting picked. How do I make it so that users can only pick 1 radio button? This code is essentially going through a variety of addresses and allowing a user to pick an address for their order.
<div class="select-address select-address-row" style="display:none">
<% #order.user.addresses.each do |address, index| %>
<%= form_for #order, remote: true, :html => { :id => 'address-form-'+address.id.to_s} do |a| %>
<div class="col-xs-4 select-address-col">
<div class="enterprise-buy-address-box address-<%= address.id %>">
<%= address.shipping_name %><br>
<%= address.line_1 %><br>
<%= address.city %>, <%= address.state %> <%= address.zipcode %><br>
<% isDefault = address.shipping_name == #defaultAddress.shipping_name ? true : false %>
<%= a.radio_button :pickedAddress, 'Address', :checked => isDefault %>
<%= label :pickedAddress, '' %>
<div class="submit-address">
<%= button_tag(type: 'submit', class: "btn btn-xs btn-default address-custom-button-select address-"+address.id.to_s+"-button") do %>
select
<% end %>
</div>
</div>
</div>
<%= a.hidden_field :address_id, :value => address.id %>
<% end %>
<script>
$('.address-<%=address.id%>-button').click(function() {
$('.default-address').empty();
var selectedAddress = $('.address-<%=address.id%>').clone();
selectedAddress.find('.submit-address').remove();
$('.default-address').append(selectedAddress);
$('default-address').addClass("enterprise-buy-address-box");
$('.default-address').show();
$('.select-address').toggle();
$('.change-address-link').toggle();
});
</script>
<% end %>
</div>
Your form_for tag is inside of the loop for the addresses. Even if the name attribute is the same for all of your input type="radio" elements, they will not be mutually exclusive across different form elements. Move your form_for tag outside of the loop so that the radio inputs belong to the same form.
See the following snippet for demonstration:
<p>These won't work</p>
<form>
<input type="radio" name="foo">
</form>
<form>
<input type="radio" name="foo">
</form>
<p>These do work</p>
<form>
<input type="radio" name="bar">
<input type="radio" name="bar">
</form>

Default object attribute not defaulting for HTML

if #challenge.name == 'foo'
#challenge.category = 'habit'
#challenge.days_challenged = 21
#challenge.why = 'bar'
else
:days_challenged & :why are properly being set in the _form for foo but not :category.
<div class="challenge-category">
<input class="date-format-switcher" type="radio" value="goal" name="challenge[category]" id="challenge_category_goal">
<label for="challenge_category_goal">Goal</label>
<input class="date-format-switcher" type="radio" value="habit" name="challenge[category]" id="challenge_category_habit">
<label for="challenge_category_habit">Habit</label>
</div>
<%= f.number_field :days_challenged, class: 'day-challenge' %>
<%= f.text_area :why %>
I assume you are purposefully custom-coding your radio buttons. The selected radio button should have the attribute "checked", i.e.
<input class="date-format-switcher" type="radio" value="habit"
name="challenge[category]" id="challenge_category_habit" checked />
To set dynamically:
<%= f.radio_button :category, 'goal', class: 'date-format-switcher' %>
<%= f.radio_button :category, 'habit', class: 'date-format-switcher' %>

post form submitting a get request header

I am developing a personal website in ruby on rails.
I have a form being dynamically generated as such:
<div>
<%= #request_type %>
<h1>Login Form</h1>
<% if #error == true %>
<h1>Error: Login Information Invalid</h1>
<% end %>
<%= form_for :user, url: {action: "login"}, method: :post do |f| %>
<p> E-mail: <br /> <%= f.text_field :email %></p>
<p> Password: <br /> <%= f.password_field :password %></p>
<p><%= submit_tag "Log In!", :disable_with => "Logging in..." %></p>
<% end %>
</div>
The #request_type is being set as request.request_method(), for debugging purposes for now.
The HTML generated for the form specifically looks like the following:
<form accept-charset="UTF-8" action="/login" method="post">
<!-- authentication token here -->
<p> E-mail: <br /> <input id="user_email" name="user[email]" type="text" /></p>
<p> Password: <br /> <input id="user_password" name="user[password]" type="password" /></p>
<p><input data-disable-with="Logging in..." name="commit" type="submit" value="Log In!" /></p>
</form>
However, any time I submit it, the headers are set with the GET method, instead of POST as declared in the form element (see method="post").
The R.O.R. might have nothing to do with what's going on... I am using Chrome to test my application. Any thoughts about why this is happening? I absolutely need the request to use POST.
If there's any other information that might be useful to solving this, please ask, and I will provide it.
Edit: Relevant routes:
login POST /login(.:format) user#login
GET /login(.:format) user#login'
I see no reason to post routes that are not associated with the "login" action.
and = submit_tag should be = f.submit_tag
Also replace:
<%= form_for :user, url: {action: "login"}, method: :post do |f| %>
With:
<%= form_for :user, url: login_path, method: :post do |f| %>