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

<Form.Input @type="datetime-local" /> woes #84

Open
MichalBryxi opened this issue Aug 4, 2020 · 3 comments
Open

<Form.Input @type="datetime-local" /> woes #84

MichalBryxi opened this issue Aug 4, 2020 · 3 comments
Labels
Type: Question Further information is requested

Comments

@MichalBryxi
Copy link
Contributor

MichalBryxi commented Aug 4, 2020

This really goes to the weirdness of how datetime-local works, but maybe internal wiring to make it work out-of the box would be a good idea.

The problem

Following code will not work:

// models/meeting.js
import Model, { attr } from '@ember-data/model';

export default class MeetingModel extends Model {
  @attr('date') startedAt;
}
...
<Form.Input
  @fieldName="startedAt"
  @type="datetime-local"
/>
...

The problem is that respective HTML element will return value as string that has format as follows: 2017-06-01T08:30. Which then does not get translated properly from/to Date() used in ember-data. Also I believe this will make problems with validation.

Proposed solution

  • In case <Form.Input> receives @type='datetime-local' it should do the conversion automagically.
  • Possible opt-out functionality should be provided.

Workaround

In case anyone wonders, there is pretty simple manual solution for this:

// models/meeting.js
import Model, { attr } from '@ember-data/model';
import moment from "moment";

export default class MeetingModel extends Model {
  @attr('date') startedAt;

  get startedAtString() {
    return moment(this.startedAt).format('YYYY-MM-DDTHH:mm');
  }

  set startedAtString(newDate) {
    this.startedAt = new Date(newDate);
  }
}
...
<Form.Input
  @fieldName="startedAtString"
  @type="datetime-local"
/>
...
@josemarluedke
Copy link
Owner

This is interesting. I'm not sure if it makes sense to handle that automatically. It really depends on how you are handling the data. For example, if you're using Ember Data, it might make sense, but if you are not, then this could be a bad assumption to transform the data into a Date object.

For these cases where we want to handle the data differently than the default browser behavior, I would not use the Changeset From components, instead, I would use FormInput directly where I can control the onChange, onInput etc.

Does this make sense?

@josemarluedke josemarluedke added the Type: Question Further information is requested label Mar 5, 2021
@MichalBryxi
Copy link
Contributor Author

This one is old. Hope I remember all my thoughts.

I would not use the Changeset From components, instead, I would use FormInput directly where I can control the onChange, onInput etc

This sounds like you would lose the changeset validation though? If not, could you give an example that would work?

if you're using Ember Data, it might make sense...

Yes, I do agree with that one. I wanted to figure out whether there is some one-size-fits all solution. Or whether this might be a note in documentation to help the newcomers?

@MichalBryxi
Copy link
Contributor Author

MichalBryxi commented Nov 28, 2022

And for my future self a version without using moment:

@attr('date') issuedAt;

get issuedAtString() {
  return this.issuedAt.toISOString().replace(/:\d+.\d+Z$/, '');
}

set issuedAtString(newDate) {
  this.issuedAt = new Date(`${newDate}:00.000Z`);
}

Apparently even according to MDN there is no nice way to convert Date() to datetime-local friendly format:

There are several methods provided by JavaScript's Date that can be used to convert numeric date information into a properly-formatted string. For example, the Date.toISOString() method returns the date/time in UTC with the suffix "Z" denoting that timezone; removing the "Z" would provide a value in the format expected by a datetime-local input.

And in reverse MDN warns against different browsers trying to parse strings into dates with different levels of success:

Note: When parsing date strings with the Date constructor (and Date.parse, they are equivalent), always make sure that the input conforms to the ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ) — the parsing behavior with other formats is implementation-defined and may not work across all browsers. A library can help if many different formats are to be accommodated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants