Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility issue with Rails 5, Chrome 86 and Time fields #75

Open
jhwinters opened this issue Nov 10, 2020 · 4 comments
Open

Compatibility issue with Rails 5, Chrome 86 and Time fields #75

jhwinters opened this issue Nov 10, 2020 · 4 comments

Comments

@jhwinters
Copy link

jhwinters commented Nov 10, 2020

Not necessarily an issue with Tod, but a small change to Tod would fix the problem.

Using Tod::TimeOfDay in a Rails 5 app, with Chrome and HTML time fields. There seems to be an odd bit of behaviour in Chrome, in that if an HTML time field has been modified by the user, the contents are returned as "08:30", whilst if the field remains unmodified from when the form was created, the same field comes back as "08:30:00.000", which Tod::TimeOfDay.parse doesn't understand, resulting in the field in the database record being set to nil.

It would appear that when you create a time field in Rails for an item held in a Tod::TimeOfDay with:

<%= f.time_field :my_tod_time %>

Then the format used in the HTML sent to the browser is "08:30:00.000", and if the user doesn't modify it then that's what Chrome sends back. Tod::TimeOfDay then doesn't understand it and you end up with a nil field. I've tried changing default formatting for both Time and Tod::TimeOfDay but neither has en effect. I've yet to identify what causes the long string to be generated in the first place.

I'm far from sure where the fundamental inconsistency is here. Feedback appreciated.

@jhwinters
Copy link
Author

I should have said - this is with Tod 2.2.0

@jhwinters
Copy link
Author

jhwinters commented Nov 10, 2020

Having investigated this further, the problem seems to be down to the Rails code using a hard-coded format of "%T.%L" when generating the contents for a time_field, which isn't acceptable to Tod::TimeOfDay when it comes back.

My workaround is to add my own field type to the FormBuilder

def tod_time_field(selector, **options)
  unless options[:value]`
    item = @object[selector]
    if item.respond_to?(:strftime)
      options[:value] = item.strftime("%H:%M:%S")
    end
  end
  self.time_field(selector, options)
end

Please feel free to close this ticket, although it might be best kept to document the issue. This extra method would be unnecessary if Tod::TimeOfDay understood "08:30:00.000" as well as being able to produce it as output.

@jackc
Copy link
Owner

jackc commented Nov 11, 2020

Your workaround is probably the best approach for the time being.

tod represents times as an integer of seconds. Accepting 08:30:00.000 would imply accepting 08:30:00.123 which would need to be truncated, rounded, or raise an exception -- none of which seem ideal.

@jhwinters
Copy link
Author

jhwinters commented Nov 11, 2020

I might suggest a change to Rails. The code in Rails is specific to the HTML time field, and that doesn't support anything more precise than seconds. By default they work to a granularity of minutes, but you can configure them for seconds. It seems silly therefore for Rails to send milliseconds in the first place.

efatsi pushed a commit to efatsi/tod that referenced this issue Apr 7, 2021
- This is a potential fix to the issue brought up in jackc#75
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants