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.
Related
For my ERB, if there are checkboxes with same values but for different forms, after a new render due to create error the checkboxes for different forms with same value gets checked. It doesn't seem to matter their different ids.
I have several checkboxes for model Option with two columns :size and :color. Currently, I'm using a bigger model to accept_nested_attributes for the Option model.
In my form, for each Option, I'm putting a checkbox with hidden value for color and checkbox for size such that:
<%= form_for #big do |big| %>
<%= f.fields_for :options do |option| %>
<%= f.hidden_field :color, value: "Red" %>
<%= f.check_box :size, {}, "Small", nil %>
<% end %>
<%= f.fields_for :options do |option| %>
<%= f.hidden_field :color, value: "Blue" %>
<%= f.check_box :size, {}, "Small", nil %>
<% end %>
.....
<% end %>
The options above have each unique ids according to html and everything but just gets checked equally, which I suspect is due to the same value.
Is there any way to prevent this behaviour?
I solved the problem.
This was more deeply rooted into my shabby controller practice mixed with overusing ERB fields_for.
So for my controller, I only have one #bigmodel.options.build, and in the controller I have four f.fields_for option. The problem was that the big model had one association to the options and therefore all options were being treated equally, regardless of the html output.
Since the html output was unique, the value submission was okay - not buggy - but when something failed server side, there were myriad of problems bound to come out to html.
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}"
I want to use a button inside HTML using information from the HTML itself.
More in detail:
There is a html.erb file. In there lay 2 <input type="hidden" name="Name" value='Tom'> and a Button.
Within the html.erb file i could get the value by typing params['Name']. But here comes my Problem. I have no idea how to write a button, so that it will only save #user when i click it. Therefore the method of the button should be something like:
#user.name = params["Name"]
#user.age = params["Age"]
#user.save
For me it looks like the simplest if i had this method(of the button) within the html, where #user, the name and the age are stored. But i'm a new to ruby, so what do i know.
In your controller where you have access to the params['Name'] and params['Age'] to save or update an existing one:
#user.name = params["Name"]
#user.age = params["Age"]
#user.save
A more Rails-y way, however is to use form_for to create a form for an object:
# show.html.erb (or whatever controller action the view is for)
<% form_for #user do |f| %>
<%= f.text_field :name %>
<%= f.text_field :age %>
<%= button_to "Save User" %>
<% end %>
# user_controller.rb
# If creating:
#user = User.new(params[:user])
# or for updating: (no need for save)
# #user.update_attributes(params[:user])
#user.save
Since the :age and :name will be passed in the :user hash looking like this:
user: {
name: "John",
age: 18
}
which can be passed to User.new or #user.update_attributes and it will set #user.name and #user.age from the hash.
I suggest browsing the saving data in the controller section of the Rails guides
I have this form:
<%= form_for(#building_shared_space, data: {abide:''}) do |f| %>
...
<div class="field">
<%= f.label :room_type, 'Room Type' %>
<%= f.text_field :room_type, placeholder: 'Room Type', required: '' %>
<%= content_tag(:small, 'Please enter a room type', class: 'error') %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :default -%>
<%= f.check_box :default %>
</div>
...
When I submit, it correctly highlights and displays a warning next to Room Type. However, it also makes the other form labels red. Why is this happening?
I'm using Foundation and Rails 4.
In order to make the <small class="error"> ... </small> work, it must be a sibling of the input. While it may look like putting the element after the input, which would be a sibling, would work, the code is affecting -all- siblings. (Which makes sense in 20/20 hind-sight.)
The wording of the documentation, can be interpreted (especially with little sleep) that the wrapping <div> is just for the sake of the example. However, having a parent element for the input control and the error message is mandatory. <DIV> just works incredibly well.
The Custom Named Patterns code example actually doesn't show a wrapping element. It also, to be fair, doesn't show an error message element. But this can mislead one to think the wrapping <div> is superfluous and just for the sake of explaining what's going on, rather than being a necessary component of making the right tree structure in the DOM to isolate validation behaviors.
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.