I have problem with showing an error to date field with simple_form.
I have the following code in my registration form:
.row
.col-md-6.col-md-offset-3
%fieldset
%h2 Rejestracja
%hr.colorgraph/
= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
= f.error_notification
.form-group
= f.input :username
.form-group
= f.label "Birthdate"
%br
= f.date_select :birth_date, end_year: 1950, start_year: (Time.now.year - 18)
.form-group
= f.input :email
.form-group
= f.input :password
.form-group
= f.input :password_confirmation, :required => false
.row.center
.col-xs-6.col-sm-6.col-md-6.center
= f.button :submit, "Submit", class: "btn btn-lg btn-success btn-block"
And the following validation of age in my user model:
validate :at_least_18
def at_least_18
if self.birth_date
errors.add(:birth_date, 'You must be 18 years or older.') if self.birth_date > 18.years.ago.to_date
end
end
The problem is that when i submit the form with valid birth_date, simple_form does not show the error like on the other fields:
But when i change
= f.date_select :birth_date, end_year: 1950, start_year: (Time.now.year - 18) to
= f.input :birth_date
It is working but now i have three ugly fields...
Any ideas?
This is caused by the CSS styling of inputs with errors.
You could fix this by adding some CSS to correctly style the dropdowns, however I think that fundamentally you would be better off replacing the 3 dropdown boxes with a single text field and using something like jquery's date picker to populate it.
Not only will that give your users a far better date-inputting experience, but your error layout issue will also be fixed.
Related
I'm building a rails application and want to add a time tracker. The users should be able to log a time (I worked for 3 hours) and submit, or they should be able to start a timer, wait, and then submit. I picked VueJS to build it out, and successfully have integrated Vue with my Rails 5 application.
I built out a simple timer (start, stop, display current time) within Vue and embedded in my page. Now I want the user to fill out some additional fields and save the time entry.
I've attempted to just take the values for the hours, minutes, and seconds from the Vue data and connect it using v-models to a basic simple_form time field, but since rails automagically generates the input fields as time_entry_duration_4i and time_entry_duration_5i, I'm struggling to connect the data.
Should I even go about pushing the JS data into a rails form? Should I just rebuild the form so it's all in Vue and always submitted that way?
Thanks.
#time_entries/_form.html.haml
= simple_form_for(#time_entry) do |f|
= f.error_notification
= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?
.form-inputs.row
.col
= f.association :project, collection: Project.joins(:assigned_roles).where(assigned_roles: {team_member: current_user}).distinct, hint: "If this is blank, you're not currently assigned to any projects."
= f.input :task, collection: TaskType::TASK_TYPES.sort {|a, b| a <=> b }
.form-inputs.row
// This is the Rails way of doing things and works, but I can't connect it to the v-model
= f.input :duration, as: :time, wrapper_html: { class: 'col-6'}, default: Time.parse('0:00')
.col-6.form-group
.d-flex.flex-row.justify-content-between
= f.label :duration, label: "Hours"
= f.label :duration, label: "Minutes"
= f.label :duration, label: "Seconds"
.d-flex.flex-row.justify-content-between.align-items-center
// This is my attempt to recreate the hours/min/seconds and bind to the v-model, but it doesn't submit
= f.text_field :duration, "v-model" => "hours", class: 'form-control mx-1'
= f.text_field :duration, "v-model" => "minutes", class: 'form-control mx-1'
= f.text_field :duration, "v-model" => "seconds", class: 'form-control mx-1'
= f.input :date, wrapper_html: { class: 'col-6'}
.form-inputs.row
.col
= f.input :notes, placeholder: "What were you working on?"
.form-actions
= f.button :submit, class: 'btn btn-primary btn-block'
You can mix rails and Vue by writing the inputs with plain html:
.col-6.form-group
.d-flex.flex-row.justify-content-between
= f.label :duration, label: "Hours"
= f.label :duration, label: "Minutes"
= f.label :duration, label: "Seconds"
.d-flex.flex-row.justify-content-between.align-items-center
input type="text" name='time_entry[duration(4i)]' v-model="hours" class='form-control mx-1'
input type="text" name='time_entry[duration(5i)]' v-model="minutes" class='form-control mx-1'
input type="text" name='time_entry[duration(6i)]' v-model="seconds" class='form-control mx-1'
tell me how to configure simple_form. I would like to use the checkbox of semantic ui, but when I wrap checkbox in the class, he becomes active, that is, visually it is, but when you click the check box is not activated.
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
.ui.three.column.middle.aligned.relaxed.grid.basic.segment
.column
.column
.column
.ui.form.segment
#marg.field= f.label :email, 'Email'
#marg.field=f.input :email, placeholder: 'Email', autofocus: true, label: false
#marg.field= f.label :password, 'Пароль'
= f.input :password, :required => false, placeholder: 'Пароль', label: false
#marg.ui.toggle.checkbox
= f.input :remember_me, as: :boolean if devise_mapping.rememberable?
#marg= f.button :submit, 'Войти!', class: 'small ui blue submit button'
http://i.imgur.com/C8Wn4K9.png
Please try it
= f.input :remember_me, as: :boolean, boolean_style: :inline
A simpler way to do this is to create a custom simple form wrapper. Here is a blogpost which describes how to add the wrapper: http://pranavsingh.me/semantic-ui-simple-form-wrapper/
The above configuration will automatically add all the essential classes semantic form classes, and also adds wrappers to create proper checkbox fields. Below is an example:
= f.input :published, label: "Published?",
hint: "If you are not ready to go live yet, keep this site unpublished.",
wrapper: :ui_toggle_checkbox
Here's what I had to do (the accepted answer got me on the right track, but didn't fully fix the issue):
In the config/initializers/simple_form.rb file, change
config.boolean_style = :nested
to
config.boolean_style = :inline
This prevents Simple Form from wrapping the input tag in the label tag (essentially inserting a tag between the '.ui .checkbox' div and the input, which breaks Semantic's checkbox functionality).
In the app/assets/javascripts/application.js file:
$('.ui.checkbox').find('input').checkbox();
My form now displays checkboxes correctly and passes the appropriate value when submitted.
Here is another option (to just fix one checkbox) -
In a _form.html.erb partial:
<div class="inline field">
<div class="ui checkbox">
<%= my_form.input :my_input, label: 'My Label', as: :boolean, boolean_style: :inline %>
</div>
</div>
In the application.js file:
$('.ui.checkbox').find('input').checkbox();
I'm trying to set a label for the following line but I keep getting an error if I add label_method anywhere. label: is just ignored. How can I add a label for f.select?
<%= f.select :state_identifier, Location::STATE, { prompt: 'State', id: 'state' } %>
I tried the following but it doesn't format properly in form-horizontal, leaving no gap between the label and data.
<%= f.label :state_identifier, label: 'State' %>
This is because f.select is not a simple_form method and does not support :label
Something like this should work for you w/ simple form.
<%= f.input :state_identifier, :label => "State", :collection => ["a","b"], :input_html => {:id=>"state" } %>
Hope this helps.
This line is in one of my forms:
<%= question.answer %><%= f.text_field :answer, :placeholder => "Respond..." %>
It displays the answer to a question and shows a text field to update that answer.
The only problem is that the place holder text is never shown and the content is always set to the answer content rather than "Respond..." as a placeholder.
Try this:
<%= question.answer %><%= f.text_field :answer, '', :placeholder => "Respond..." %>
You were setting your placeholder as the value parameter: text_field_tag(name, value = nil, options = {})
http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-text_field_tag
<%= question.answer %><%= f.text_field :answer, :value => "", :placeholder => "Respond..." %>
Does the trick it seems, this is a modified version of #Yogzzz's answer - he should get credit. He hasn't made the changes to his answer so I can't accept it as correct.
I'm using simple form for a basic login form for my site within the nav area at the top of the page.
Currently, it's spilling the form fields over two rows and no matter how many display: inline attributes I apply. It still refuses to go back onto one line.
What im trying to do is restrict the number of characters in the form so that the fields fit onto one line.
Here's my current form code..
<%= simple_form_for("user", :url => user_session_path, :html => {:id => "sign_in", :class => 'form-inline' }, :remote => true, :format => :json) do |f| %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.submit 'Login' %>
<%= link_to "Forgot your password?", new_password_path('user') %>
<% end %>
Easy way is to simply use the maxlength html attribute for inputs:
f.input :name, :input_html => { :maxlength => x }
But that will just restrict the number of characters that can be added into a single input. If your problem is with the width of those inputs, just use CSS to specify a custom width per input so the inputs won't overflow into a second line.