f.time_field with 24 hour clock - Rails Fields - ruby-on-rails

I've got a little Rails app that I need to use the 24-hour clock for inputting times. Right now, I've got:
<div class=".col-md-7">
<%= f.label :backinservice %><br>
<%= f.time_field :backinservice %>
</div>
Which gives an AM/PM option. When I input a time like 18:56, it automagically converts it to 06:56 PM. Normally that would be totally ok, just not in this app.
I also tried:
<div class=".col-md-7">
<%= f.label :recieved %><br>
<%= f.time_field :recieved, :format=>"%H:%M" %>
</div>
But that doesn't work either.
Is there a :format option that allows for straight use of the 24-hour clock?

You have to pass the format using value key.
<div class=".col-md-7">
<%= f.label :recieved %><br>
<%=
f.time_field :recieved,
value: "%H:%M",
min: 'hh:mm:ss',
max: 'hh:mm:ss'
%>
</div>
The doc says:
The default value is generated by trying to call strftime with “%T.%L” on the objects's value. It is still possible to override that by passing the “value” option.

I had to do the following to get this to work for me:
<%=
f.time_field :my_time_field,
value: f.object.my_time_field.strftime("%H:%M")
%>
Found this out by looking at the definition of time_field, that is only creating a new instance of Tags::TimeField.new
In turn Tags::TimeField.new only does one thing which is to define the format.

Related

Set both end_ and start_time in form with datetime_select

Im trying to set up a bookings form where people can book services. Within the Service model there is a duration set and I want to use this to automatically populate the end_time. For example, if I book a 60 minute service at 2017-03-22 1PM I want the end time to be set at the same day but one hour later. Is it possible to send this in with a form?
<%= form_for([service, service.bookings.new]) do |f| %>
<div class="row">
<div class="col-sm-12">
<%= hidden_field_tag "recipients", #user.id %>
<div class="form-group">
<%= label_tag 'Available times' %>
<%= f.datetime_select :start %>
<%= f.hidden_field :end, value: Time.at([:start].to_i + service.duration) %>
<%= f.hidden_field :service_id, value: service.id %>
<%= f.hidden_field :price, value: service.price %>
</div>
<%= submit_tag 'Book', class: 'btn btn-complete btn-lg btn-large btn-block' %>
</div>
</div>
<% end %>
I've tried with above but get
undefined method `to_i' for [:start]:Array
which I guess is because :start is not yet saved and renders nil.
Any ideas on how to solve this?
Thanks a lot
[:start] is just return an Array contain symbol, and you can not get anything.
You should create end_time in controller or model when you got the start_time, or other way is using the javascript code get end_time when type start_time in the form
Consider not doing business logic in a view. Send these params and set the end variable in model or controller.
Why does your code not work?
datetime_select returns a set of select tags (one for year, month, day, hour, and minute).

Rails - format date_field

how can I style the date format of a date_field?
I got the following form:
<%= form_for([#user, #vehicle]) do |f| %>
<%= f.label :name, "Vehicle name" %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :matriculation_date %>
<%= f.date_field :matriculation_date, class: 'form-control' %>
<%= f.submit "Add", class: "btn btn-primary" %>
<% end %>
this is rendering the following HTML for the date field:
<input class="form-control" type="date" name="vehicle[matriculation_date]" id="vehicle_matriculation_date">
The date field accept input in the following format: mm/dd/yyyy. I want it to accept format like dd/mm/yyyy.
I tried to edit it.yml file without any luck.
it:
date:
formats:
default: ! '%d/%m/%Y'
datetime:
formats:
default: ! '%d/%m/%Y %H:%M'
Any clue? Thank you
EDIT
None of the proposed solutions solve my problem, so I think my question was not very clear. What I want is just to style how the date_field prompt the user (see image for more details). At the moment the form show mm/dd/yyyy, and I want it to show dd/mm/yyyy.
Not sure it might be a useful information, but I'm using Bootstrap for styling.
You can do:
<%= f.date_field :matriculation_date, as: :date, value: f.object.try(:strftime,"%m/%d/%Y"), class: 'form-control' %>
You can convert the date formate with strftime()
#date.strftime("%d/%m/%Y")
It will convert your date into dd/mm/yyyy formate as you wanted.
Here I am showing you an example:
t = Time.now
=> 2016-04-28 16:09:42 -0700
>> t.strftime("%d/%m/%Y")
=> "28/04/2016"
for more strftime() formatting options you can check this http://apidock.com/ruby/DateTime/strftime
EDIT :
After reading your comment and screenshot i've got the solution as follow.
You can also use this gem: https://github.com/Nerian/bootstrap-datepicker-rails
on your gemfile.rb
gem 'bootstrap-datepicker-rails'
then bundle install and restart rails server
then add this line to app/assets/stylesheets/application.css
*= require bootstrap-datepicker
and add this line to app/assets/javascripts/application.js
//= require bootstrap-datepicker
and to use this in your form:
<%= f.date_field :matriculation_date, :id => "datepicker" %>
and add this javascript on the same view of your form
<script>
$('#datepicker').datepicker({format: 'dd/mm/yyyy'});
</script>
You can try this
#yourdate.strftime("%m/%d/%Y")
this works!
My answer is based on #Dharmesh_Rupani answer
Follow the steps to add the gem 'bootstrap-datepicker-rails'
I made two little changes on the form
<%= f.text_field : matriculation_date, :placeholder => 'dd/mm/yyyy', class: 'form-control datepicker' %>
The first thing is I changed the type of the field to text, because when I implemented I had two calendars, one from the date_field and another from the new gem
The other thing I changed is instead of :id I used :class, because it may happen that you have more than one date field
lastly, you should add this on the view
<script>
$( document ).ready(function() {
$('.datepicker').datepicker({format: 'dd/mm/yyyy'});
});
</script>

I need to change date part of DateTime variable

I'm having a problem with one of my variables.
I have 2 variables, :starts_on and :ends_on . Both are of type DateTime. :starts_on gets assigned a date and a time in the form, however :ends_on only gets assigned time from the form. Unfortunately, the date part becomes "2000-01-01", which is not right. I would like to assign date from :starts_on variable, then user can change time part in the form. So far it doesn't work. My code:
in app/views/courses/_form.html.erb
<%= form_for #course do |f| %>
<%= f.label :starts_on, "Date:" %>
<%= f.date_select :starts_on %>
<%= f.label :starts_on, "Time:" %>
<%= f.time_select :starts_on, :ignore_date => true %>
<%= f.time_select :ends_on, :ignore_date => true %>
<%= f.submit "Submit" %>
<% end %>
in app/controllers/courses_controller.rb (I'm only showing edit action, but new is the same idea)
def edit
#course = Course.find(params[:id])
#course.ends_on = #course.starts_on
end
So, I attempted putting the code there to make ends_on equal starts_on and then in the form the user would change the time part of it. However this doesn't work and the date ends up being "2000-01-01" for all of them (time part is correct). If I look up the value of ends_on in the form - it is correct, but doesn't save correctly. Please help?
Edit / Solution:
I figured it out.
I tried changing in controller's update action - didn't work. I tried making hidden date_select and in the end what worked was:
<div style="display: none;">
<%= f.date_select :ends_on %>
</div>
This is quite frustrating that THAT is the only thing that works. It appears that there MUST be <%= f.date_select :ends_on %> in order for it to add a date to the god damn variable. You can't even go without = (the equal sign). Very frustrating.
Thank you for comments and answers, it was all helpful.
I feel that this problem could have better solutions, so this question might be useful in the future to others.
Have you tried adding a hidden <%= f.date_select :ends_on %>? I'm assuming you are only concerned with preventing the user from having to select the same date, so you can have this tag in the form but hide it with css in the html_options hash.

f.select not defaulting to correct value

I have a data model that contains the fields for startMonth and endMonth. I also am able to SET them correctly using the following f.select tags, however, when I go to edit the data, the rendered dropdowns do not reflect the proper values stored in the db. Am i setting the f.select tags incorrectly?
<div class="control-group">
<%= f.label "Start Month", :class => 'control-label' %>
<div class="controls">
<%= f.select :startMonth, options_for_select([['January' ,'1'],['February' ,'2'], ['March', '3'],['April' ,'4'], ['May', '5'],['June' ,'6'],['July' ,'7'], ['August', '8'],['September' ,'9'], ['October', '10'],['November' ,'11'], ['December', '12']]), class: "list-select" %>
</div>
<%= f.label "End Month", :class => 'control-label' %>
<div class="controls">
<%= f.select :endMonth, options_for_select([['January' ,'1'],['February' ,'2'], ['March', '3'],['April' ,'4'], ['May', '5'],['June' ,'6'],['July' ,'7'], ['August', '8'],['September' ,'9'], ['October', '10'],['November' ,'11'], ['December', '12']]), class: "list-select" %>
</div>
</div>
Once the data is stored using these dropdowns, it stores it correctly in the database and it shows the correct values on my show page. However, I want the dropdowns to default to the stored values when I return to the edit page. Is there a setting I am forgetting to include?
Alex
You can pass a second argument to the options_for_select method to pre-select the value. For example, assuming your model object is represented by an instance variable called #object, you can pass in #object.endMonth as the second parameter to your options_for_select.:
<%= f.select :endMonth, options_for_select([['January' ,'1'],['February' ,'2'], ['March', '3'],['April' ,'4'], ['May', '5'],['June' ,'6'],['July' ,'7'], ['August', '8'],['September' ,'9'], ['October', '10'],['November' ,'11'], ['December', '12']], #object.endMonth), class: "list-select" %>
Note: the #object.endMonth value must resolve to the same data type as the option value - in this case the number representing the month. See the Rails Guide for details.

Rails: Human-friendly date format for text_field

I have a birth_date field that is stored as a datetime value. The default rails form helpers spit out a not-too-friendly format, e.g. "2008-06-10 22:33:19.000000". The below is the vanilla rails way.
<div class="field">
<%= f.label :birth_date %>
<%= f.text_field :birth_date, :size=>"20" %>
</div>
How can I simply apply a format? I tried various approaches, for example strftime should work, I thought. But when I try the following, I get an error undefined method 'strftime' for nil:NilClass
<div class="field">
<%= f.label :birth_date %>
<%= f.text_field :birth_date, :value=>f.object.birth_date.strftime('%m/%d/%Y'), :size=>"20" %>
</div>
Based on some other questions/answers, I tried the following. It works for non-null values, but it is ugly code, and it doesn't work for blank values (actually it shows today's date).
<div class="field">
<%= f.label :birth_date %>
<%= f.text_field :birth_date, :value=> Time.parse(f.object.birth_date.to_s).strftime('%m/%d/%Y'), :size=>"20" %>
</div>
In playing around, it seems that outputting f.object.birth_date is treated as a date, rather than datetime. However, when displayed in the text_field (original, ugly formatting), it includes the time. It is friday afternoon, and my combined lack of familiarity with rails forms and ruby date/time objects is making me feel foolish.
Any simple way to get my form to display nothing if null/blank, and a friendly date otherwise?
If you want a blank string if birth_date is empty, you should simply check that birth_date is non-nil beforehand:
<%= f.text_field :birth_date, :value => (f.object.birth_date.strftime('%m/%d/%Y') if f.object.birth_date), :size => "20" %>
This way, when birth_date is nil, :value gets set to nil.
Have you tried using the date_select form builder helper method? You can also use datetime_select, but it looks like you just want to work with the date here.
<div class="field">
<%= f.label :birth_date %>
<%= f.date_select :birth_date %>
</div>
The API docs are here: http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-date_select
Add on the options you need.
I've always used that approach, or a javascript date selector like this one from jQuery UI. There are plugins for most JS frameworks these days.
If it MUST be a text_field, use a human language date parsing library like chronic. It'll work, but will require that you parse the input from the form somewhere before applying the attribute to your object.

Resources