How to add class to form components with simple_form - ruby-on-rails

Does anyone know how to add a class to a ruby on rails simple form, and how to add a class to an individual component so that I can style them later in CSS. Thank you

Straight from the simpleform docs:
It is also possible to pass any html attribute straight to the input, by using the :input_html option, for instance:
<%= simple_form_for #user do |f| %>
<%= f.input :username, input_html: { class: 'special' } %>
<%= f.input :password, input_html: { maxlength: 20 } %>
<%= f.input :remember_me, input_html: { value: '1' } %>
<%= f.button :submit %>
<% end %>
If you want to pass the same options to all inputs in the form (for example, a default class), you can use the :defaults option in simple_form_for. Specific options in input call will overwrite the defaults:
<%= simple_form_for #user, defaults: { input_html: { class: 'default_class' } } do |f| %>
<%= f.input :username, input_html: { class: 'special' } %>
<%= f.input :password, input_html: { maxlength: 20 } %>
<%= f.input :remember_me, input_html: { value: '1' } %>
<%= f.button :submit %>
<% end %>

Just adding a point to #bmac151's answer above.
For styling or dynamic scripting (e.g. javascript) purposes, you can also provide an ID to distinguish the elements from other elements of the same class by providing the id option, like so:
<%= simple_form_for #user, html: { id: 'simple-form' } do |f| %>
<%= f.input :username, input_html: { class: 'special', id: 'username' } %>
<%= f.input :password, input_html: { maxlength: 20, id: 'password' } %>
<%= f.input :remember_me, input_html: { value: '1', id: 'remember_me' } %>
<%= f.button :submit, id: 'submit-button' %>
<% end %>
This will give you unique IDs for all of the elements in the form, as well as the form itself.
From CSS, you can refer to these for styling, like this:
#simple-form {
font-size: 125%;
}
#submit-button {
text-transform: uppercase;
}
From Javascript, you can refer to elements by their element ID, as well. With this, you can apply dynamic behaviors to individual elements, rather than whole classes at a time. Here's a Javascript example:
var submit_button = document.getElementById("submit-button");
submit_button.addEventListener("click", function () {
alert('Yeeehaaah!');
submit_button.submit();
});
For fine-grained control, you'll want to use the id attribute rather than the class attribute; however, for theme-like control of elements, the class attribute is more useful.

<%= f.button :submit, "Sign in", class: "submit-button" %>

Related

Simple Form For that adapts based on checkbox input

I am working on a personal project where I want users to be able to create profiles (I am using Devise to handle users). These can either be public or private, whereby public profiles require more input fields than private profiles. Is there any way I can cause these additional form fields to only appear if the user chooses his profile to be public?
I tried looking on StackOverflow and previous threads on here but couldn't find anything. I saw a few suggestions for the Cocoon gem but couldn't get that to work.
<%= simple_form_for(#User, url: registration_path(#User)) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :first_name, required: true, autofocus: true %>
<%= f.input :email,
required: true,
input_html: { autocomplete: "email" }%>
<%= f.input :public, required: false, label: "Enable public profile?" %>
## Ideally the following two-fields would only show if public is clicked
## Best case they would be required fields if this happens and not required if
it does not
<%= f.input :linkedin_link, required: false, label: "Linked-In Profile Link" %>
<%= f.input :photo, as: :file, label: "Profile Picture", accept: "image/*", hint: "Why not use your Linked-In profile picture? (png and jpg only)" %>
<%= f.input :password, required: true, hint: ("#{#minimum_password_length} characters minimum" if #minimum_password_length), input_html: { autocomplete: "new-password" } %>
<%= f.input :password_confirmation, required: true, input_html: { autocomplete: "new-password" } %>
<%= f.button :submit, "Sign up", class: "btn-success btn-full-width" %>
</div>
<% end %>
Looking forward to learning something new :) Thanks a lot for your help!
Managed to solve it with this.
JS:
$(function () {
$('div[name="showthis"]').hide();
//show it when the checkbox is clicked
$('input[type="checkbox"]').on('change', function () {
if ($(this).prop('checked')) {
$('div[name="showthis"]').fadeIn();
} else {
$('div[name="showthis"]').hide();
}
});
});
HTML:
<div class="form-inputs">
<%= f.input :first_name, required: true, autofocus: true %>
<%= f.input :email, required: true, input_html: { autocomplete: "email" }%>
<%= f.input :public, required: false, label: "Enable public profile?" %>
<div name="showthis">
<%= f.input :linkedin_link, required: false, label: "Linked-In Profile Link" %>
<%= f.input :photo, as: :file, label: "Profile Picture", accept: "image/*", hint: "Why not use your Linked-In profile picture? (png and jpg only)" %>
</div>
<%= f.input :password, required: true, hint: ("#{#minimum_password_length} characters minimum" if #minimum_password_length), input_html: { autocomplete: "new-password" } %>
<%= f.input :password_confirmation, required: true, input_html: { autocomplete: "new-password" } %>
<%= f.button :submit, "Sign up", class: "btn-success btn-full-width" %>
</div>

How to dynamically set 'name' attribute of a simple form input

I am using Simple Form in a Rails application in which a FormsController controller was defined as follow :
class FormsController < ApplicationController
def index
#forms = Form.all
end
def new
#form = Form.new(form_params)
end
...
private
def form_params
params.require(:form).permit(:user, :name, :tag, :link, :repo)
end
end
A new view is used to get some inputs from user
<div class="form">
<%= simple_form_for #param do |f| %>
<div class="form-inputs";>
<%= f.input :user %>
<%= f.input :name %>
<%= f.input :tag %>
<%= f.input :link %>
<%= f.input :repo %>
</div>
<div class="form-actions">
<%= f.button :submit, "Create", class: "btn-primary" %>
</div>
<% end %>
</div>
I checked what's the generated name for a each field using inspect :
<input type="text" name="form[user]" id="form_user">
Printing parameters in controller while submitting a form returns :
{“user”=>”value1”, “name”=>”value2”, “tag”=>”value3”, “link”=>”value4”, “repo”=>”value5”}
From now, I would like to duplicate that's simple form few times. So, I first updated the field name from form[<parameter>] to form[1][<parameter>]
<div class="form-inputs";>
<%= f.input :user, input_html: { name: 'form[1][user]' } %>
<%= f.input :name, input_html: { name: 'form[1][name]' } %>
<%= f.input :tag, input_html: { name: 'form[1][tag]' } %>
<%= f.input :link, input_html: { name: 'form[1][link]' } %>
<%= f.input :repo, input_html: { name: 'form[1][repo]' } %>
</div>
What I get from now as parameters output is :
"form"=>{"1"=>{"“user”"=>"value1", "“name”"=>"value2", "“tag”"=>"value3", "“link”"=>"value4", "“repo”"=>"value5"}}
What's the best way to dynamically allocate the id to the form[<id>][user] to the field ?
Is it possible to get parameters formatted as follow ?
form => { 1 => {user: "user1" }, 2 => {user: "user2" }, 3 => {user: "user3" }.. }
form => { 1 => {name: "name1" }, 2 => {name: "name2" }, 3 => {name: "name3" }.. }
...

"Undefined" placeholder on f.select in form

I have a form
<%= form_for #user, url: contact_path do |form| %>
<%= form.select(:email, User.all.map(&:email), {}, { class: 'my-form' }) %>
<% end %>
which works well but has placeholder "Undefined" in start position.
I tried to get rid of that with
<%= form.select(:email, User.all.map(&:email), {placeholder: "Select email"}, { class: 'my-form' }) %>
or
<%= form.select(:email, User.all.map(&:email), {prompt: "Select email"}, { class: 'my-form' }) %>
but still same. Any ideas?
<%= form.select :email, options_for_select(User.all.map(&:email)), include_blank: "whatever your prompt says" , class: 'my-form' %>
Experienced same issues today and this is what I did for one of our projects recently.
<%= f.select :category, options_for_select(Category.all.collect { |c| [c.name, c.id] }), { include_blank: 'Select category' }, { class: 'custom-select' } %>
Try changing the values according to your values.
This is how you add class and placeholder in a form.select element in Rails.

Rails simple_form error: false

in my app I have form that looks like this
= simple_form_for #user do |f|
= f.input :name, error: false
= f.input :surname, error: false
Is there any way to avoid this repetitions (error: false)?
If they're all of the same type, something like this should work:
= simple_form_for #user do |f|
- [ :name , :surname ].each do |field|
= f.input field, error: false
If not, you could use a hash or something, instead of an array, and specify the type, as well.
It appears that simple form has the following option:
If you want to pass the same options to all inputs in the form (for
example, a default class), you can use the :defaults option in
simple_form_for. Specific options in input call will overwrite the
defaults:
<%= simple_form_for #user, defaults: { input_html: { class: 'default_class' } } do |f| %>
<%= f.input :username, input_html: { class: 'special' } %>
<%= f.input :password, input_html: { maxlength: 20 } %>
<%= f.input :remember_me, input_html: { value: '1' } %>
<%= f.button :submit %>
<% end %>
From https://github.com/plataformatec/simple_form
So, in your case:
= simple_form_for #user , defaults: { error: false } do |f|
= f.input :name
= f.input :surname
You could loop through an array of symbols
simple_form_for #user do |f|
[:name, :surname].each do |element|
f.input element, error: false
end
end

Rails - simple form

I use simple_form gem in my Rails app. When I use code like this
= f.input_field :name, label: false, placeholder: 'Name'
= f.input_field :price, label: false, placeholder: 'Price'
= f.input_field :description, label: false, placeholder: 'Description'
= f.input_field :image, label: false, placeholder: 'Image'
I get HTML for input:
<input class="string required textform" id="item_name" label="false" maxlength="255" name="item[name]" placeholder="Имя" size="255" type="text">
As you can see size of input is 255 now. Actually it's much more than enough. How can specify the size of inputs?
Following is from simple_form documentation here
It is also possible to pass any html attribute straight to the input,
by using the :input_html option, for instance:
<%= simple_form_for #user do |f| %>
<%= f.input :username, input_html: { class: 'special' } %>
<%= f.input :password, input_html: { maxlength: 20 } %>
<%= f.input :remember_me, input_html: { value: '1' } %>
<%= f.button :submit %>
<% end %>
To set size of 100 for name input:
= f.input :name, label: false, placeholder: 'Name', input_html: { size: 100 }

Resources