Forms: Elixir 1.13 HTML displays a NaiveDateTime as only a Date

I’m working on upgrading our project from Elixir 1.7 to Elixir 1.13, with associated upgrades of “everything”. (Linux from Centos 6 to Redhat 8, Ecto from 2.1.6 to 3.7.1, Phoenix from 1.3.4 to 1.5.9, Phoenix HTML from 2.12.0 to 3.0.4)

I have a problem with a form submission. When I commit the form I get “start date is invalid”, which it turns out is because the form is storing it incorrectly.

The code to put the start_date in the form is below:

  = if debug do
    .start_date-field.input-line
      label
        = ~g(Start date & time)
        = text_input @f, :start_date, class: "datetime-picker start"
  - else
    = hidden_input @f, :start_date

With the debug control false I get:
<input id="queue_reset_schedule_start_date" name="queue[reset_schedule][start_date]" type="hidden" value="2021-02-07">

but if I set debug true I get:
<input class="datetime-picker start flatpickr-input" id="queue_reset_schedule_start_date" name="queue[reset_schedule][start_date]" type="text" value="2021-02-07T00:00:00" readonly="readonly">

The old version:
<input id="queue_reset_schedule_start_date" name="queue[reset_schedule][start_date]" type="hidden" value="2021-02-07 00:00:00.000000">

This seems to be a defect of some underlying dependency. I’ve checked the input data as thoroughly as I can and it seems to be a complete NaiveDateTime, yet the hidden input only contains the date, which causes a problem when I try to commit that to a NaiveDateTime field.

Did something change in one of my upgrades listed above (or one I didn’t think to list)? Is there a new tag that I need to switch to to get the NDT to include the Time?

If this is a real problem, what dependency is it even in? If it’s resolved, what version do I need to pick up?

Thanks.

1 Like

Is this form backed by a changeset? Can you log the changeset (inspect(changeset, structs: false))?

What I’m wondering is if the difference between debug or not is less the data on the elixir side, but rather the datepicker used for one of the inputs.

1 Like

I hope you don’t need more than the structure of the start_date that is the problem. If you want more I can add it, but be specific, it’s a bigger structure than you want to have to filter through.

      __struct__: NaiveDateTime,
      calendar: Calendar.ISO,
      day: 7,
      hour: 0,
      microsecond: {0, 0},
      minute: 0,
      month: 2,
      second: 0,
      year: 2021
    },

The key thing for me is that this code is unchanged from our old version, but seems to be affected by all the infrastructure upgrades. But we are hardly early adopters, so I would hope that someone has run into this.

What is your flatpickr’s configuration? Is it possible it’s removing the time from the input’s value attribute?

1 Like

I think this is the relevant piece when the debug flag is set, but I’m not sure what to look for that would control the format with debug off and just using a hidden_input. Note that with debug on the flatpickr is fine. What can define a format for an unlabelled hidden_input?

const pickrStart = flatpickr('.datetime-picker.start', {enableTime: true, dateFormat: 'Y-m-d H:i:00', appendTo: startContainer, position: 'below right'});

There was a change in html_safe format from phoenix_html v2.12.0, NaiveDateTime would convert with to_string, which returns your old version’s value: "2021-02-07 00:00:00.000000" now in v3.0.4 it calls to_iso8601 which returns "2021-02-07T00:00:00"

I thought that maybe the flatpickr date format was misbehaving and sending back a date-only string, but this dateFormat: 'Y-m-d H:i:00 keeps the time value. (tested with v4.6.11)

I’m just as puzzled as you as to why text_input seems to be parsing it as a Date while hidden_input is a NaiveDateTime.

4 Likes

Your last sentence is backwards. Hidden is Date and text is NaiveDateTime

But that change in html_safe may be the underlying problem. If the old code would return a space in the middle and it will now get a T, it may be that somewhere there is a parsing segment that is failing to match and thus giving the wrong result.

The other thing that is bugging me is that I have a couple of different settings of the surrounding object that use this start_date, and when I render the page for one of the other options on the page, using the same HTML and javascript nominally, the date is complete.

Maybe I’ll go look for some html_safe calls in my own code.

Thanks for that possibility.

Oh my mistake, I got it backwards and went off on a red-herring. Obviously not a problem with flatpickr.

I’m curious what text you get if you also place = inspect(input_value(f, :start_date)) above each input. Does it show ~N[2021-02-07 00:00:00] for both?

It does.

The safe date format is the problem. The javascript code in this file was written to parse the date in the old format with a space in the middle. I still haven’t figured out which specific operation was screwing things up, despite lots of console.log calls, but when I updated the code to split the two fields on ‘T’ instead of ’ ', and join them the same way, and connect them in a single string the same way (sigh), the problem is resolved. Juan gets the +1.

Thanks a lot.

1 Like