ERB Radio Button causing string error - html

I'm working with forms using Embedded Ruby and Rails 4 to create and edit Users. Each User has to be assigned a Role on creation. Initially the form was using check boxes for this and was working fine. Upon changing over to radio buttons however, I get an error.
This is the form:
<%= simple_form_for(#user, html: {class: 'form-horizontal'}) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :name, autofocus: true %>
<%= f.input :email %>
<%= f.input :phone_number %>
<%= f.input :institution_pid, collection: institutions_for_select, as: :select, label: "Institution" %>
<%= f.association :roles, collection: roles_for_select, as: :radio_buttons %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
</div>
<br>
<div class="form-actions">
<%= button_tag(type: 'submit', class: "btn doc-action-btn btn-success") do %>
<i class="glyphicon glyphicon-check"></i> Submit
<% end %>
<%= link_to #user, {class: "btn doc-action-btn btn-cancel"} do %>
<i class="glyphicon glyphicon-remove"></i> Cancel
<% end %>
</div>
I'm specifically asking about the f.association bit. Before, when I was using
as: :check_boxes
it worked exactly as it was supposed to. Now I get this error message:
NoMethodError in UsersController#update
undefined method `reject' for "77":String
I should note that "77" is the value of one of the radio button options.
The method throwing the error is this:
def build_role_ids
[].tap do |role_ids|
roles = Role.find(params[:user][:role_ids].reject &:blank?)
roles.each do |role|
authorize!(:add_user, role)
role_ids << role.id
end
end
end
The HTML when using radio buttons looks like this:
<label class="radio">
<input class="radio_buttons optional" id="user_role_ids_77" name="user[role_ids]" type="radio" value="77">
"Institutional Admin"
</label>
When using check boxes:
<label class="checkbox">
<input class="check_boxes optional" id="user_role_ids_77" name="user[role_ids][]" type="checkbox" value="77">
"Institutional Admin"
</label>
If I'm missing something or you need more information, please let me know. Thank you!

With checkboxes, user can select multiple values so you got an Array of role_ids returned in params[:user][:role_ids]. reject method is implemented for Arrays. Hence, it worked in that case.
With radio buttons, only one value would be selected at a time, so you'll get a String value for role_ids in params[:user][:role_ids]. reject method is not implemented for Strings. Hence, the error.
Instead of
params[:user][:role_ids].reject &:blank?
you can check if role_ids is empty or not, as it is a String object.
params[:user][:role_ids].empty?
and update build_role_ids method keeping in mind that role_ids is a String object and not an Array.

This error seems to indicate that params[:user][:role_ids] is not an Array but a single String value. This would make sense since you are changing from checkboxes (multiple values can be selected at a time = Array) to radio buttons (only a single value can be selected at a time = String).
If you truly want to change from checkboxes to radio buttons, then you'll need to update your build_role_ids method logic to expect a single value instead of an array of values.

Related

RoR form: adding text behind input-field

I am currently working on a registration form. Users should only register with an email-adress belonging to a specific domain (e.g. "#example.com"). I want to add this domain as a text behind the email-input-field to make it clear for the users what to enter. Unfortunately it seems impossible to write something behind an input-field as rails automatically does a line break.
This is the relevant part of the form:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email, autofocus: true %>[#example.com]
</div>
<div class="actions">
<%= f.submit "register", class: "button" %>
</div>
<% end %>
The result should look like [ ] #example.com
Also I need the email-adress to be an actual email-adress. Therefore I also need to manipulate the input e.g. "john" to "john#example.com" before saving the user to the database.
How can I achieve these two things?
The strict answer to your question is that in your controller action you are free to manipulate or set attributes on an instance before you save it.
def create
#foo = Foo.new(foo_params)
#foo.email = mangle_email(#foo.email)
if #foo.save
... # normal stuff
end
end
In your particular case, you should consider the various input scenarios (e.g., user adds the #domain on their own, etc.), since there are lots of cases where just appending something to the end of the user input is probably not what you're after.

html/rails form. Input

This is a simple question but I can't seem to find a solid answer. I simply want to know if this is valid? it's a basic form_for with in input at the bottom.
## Form
<%= form_for #snitch, html: { class: "form-actions", method: 'delete' } do |form| %>
<span class="button-text"><%= link_to 'NO WAY!', home_base_url_or_default(root_path), rel: "modal:close" %></span>
<button type="submit" class="button button--modal delete-snitch" data-snitch-id="<% #snitch.token %>" value="Yes, delete it.">
<% end %>
Is the third line valid? specifically where it says data-snitch-id="<% #snitch.token %>"? if it is not. can someone help me figure out how I can do something like that?
HTML data attributes are perfectly valid and widely supported. They're used to store custom data in an element. You can create elements with those attributes in rails helpers as well.
<%= button_tag "Yes, delete it.", type: :submit,
data: {"snitch-id" => #snitch.token},
class: 'button button--modal delete-snitch' %>
The only problem with your example is that you're not printing the value of #snitch.token. You should be using <%= #snitch.token %> instead of <% #snitch.token %>
Use #{ } expression instead.
data-snitch-id="#{#snitch.token}"

How to add html attributes without a value to a form in Rails?

If I have this form:
<%= form_for #person do |f| %>
First name: <%= f.text_field :first_name %>
...
<% end %>
how do I add an html attribute to both form_for and text_field without assigning a value?
A) form_for - I want to add the attribute data-parsley-validate here, but the best one I came up with is:
<%= form_for #person, html: {'data-parsley-validate' => ''} %>
However this produces data-parsley-validate=''. How do I get rid of the =''?
B) text_field. I want to make the first name field required. I could write:
<%= f.text_field :first_name, required: '' %>
but this produces required="required" and not just required. While in the case of required this is ok, there might be other cases (such as data-parsley-no-focus), where I just need the attribute with no value.
How do I do that?
For what it's worth, HTML5 spec says that these attributes are equivalent:
<input disabled>
<input disabled="">
http://www.w3.org/TR/html-markup/syntax.html#syntax-attr-empty
Note that empty attribute syntax is exactly equivalent to specifying the empty string as the value for the attribute, as in the following example.
<input disabled="">

Rails form submit custom image or use a default image based on radio buttons

I have a form with a radio select. When the user selects the first option, I'd like to pass the default url as the logo_image param (on submit). If the user selects the second option and puts in a url, I want to pass that as the logo_image param.
Right now my code (seen below) submits the second option every time. How can I make it submit based on the selected option? I think I could figure it out with javascript but is there a pure html/css way? I still accept the best answer, even if it uses javascript
<%= form_for(:organization, html: { class: "form-horizontal" }) do |f| %>
...
<div class="form-group">
<%= f.label :logo, class: "col-md-5 control-label" %>
<div class="col-md-7">
<div class="radio">
<label>
<%= radio_button_tag :logo_image, :default, #organization.has_default_logo? %>
Default Logo<br>
<%= image_tag #organization.default_logo, class: "org-logo border" %>
<%= f.hidden_field :logo_image, value: #organization.default_logo %>
</label>
</div>
<div class="radio">
<label>
<%= radio_button_tag :logo_image, :custom, !#organization.has_default_logo? %>
Custom Logo
<%= image_tag #organization.logo_image, class: "org-logo" if #organization.logo_image %>
<%= f.text_field :logo_image, { class: "form-control" } %>
</label>
</div>
</div>
</div>
...
<% end %>
the way HTML submit works, logo_image is being 'overwritten' by the later fields, something like this:
radio button tag ("default", if checked)
hidden field value
radio button tag ("custom", if checked)
text field value
which results in the value returned to your controller always being the text field value.
If I'm reading your intent right, you'll need to have different names for the radio button field and for the custom url field, and use the value of the radio button field in your controller or model to decide which image url to use. You probably don't need the hidden field, since the code will already have that value as the default url anyway.

Basic rails form, does not deselect alternative options - can't find solution for rails

I have excel, video, and multiple choice boolean columns in my Step model. I am trying to get it so the user has to choose one of the three, and when saved it passes back to the database as true. Right now my two problems are a)when I select one, it doesn't deselect the others and b) the radio button is on a different line than the text that labels it. Any help would be appreciated.
<fieldset class="stepCreator">
<%= "Step" %>
<%= f.label :description, "Description" %>
<%= f.text_field :description %>
<div>
<%= f.label :excel, "Excel" %>
<%= f.radio_button(:excel, true, :checked => true) %>
<%= f.label :video, "Video" %>
<%= f.radio_button(:video, true) %>
<%= f.label :multiple_choice, "Multiple Choice" %>
<%= f.radio_button(:multiple_choice, true) %>
</div>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "btn btn-danger btn-mini remove_fields "%>
</fieldset>
Actually you have 2 very different problems.
All the radio buttons (that you want to select one and automatically deselect the others) must have the same name, and different values, so it should be something like:
f.radio_button(:media, :excel, :checked => true)
f.radio_button(:media, :video)
For the labels to be at the same line as the checkbox, you just have to change the CSS.
From the documentation:
http://guides.rubyonrails.org/form_helpers.html
try:
<%= radio_button_tag(:age, "child") %>
<%= label_tag(:age_child, "I am younger than 21") %>
<%= radio_button_tag(:age, "adult") %>
<%= label_tag(:age_adult, "I'm over 21") %>
radio buttons have to select the same attribute in your model, in this example i selected the age attribute and i can give it 1 of two values, or he is a child or he is an adult
hope it helps