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

Local Date Input from UTC Date #221

Open
robodna opened this issue Jul 2, 2024 · 16 comments
Open

Local Date Input from UTC Date #221

robodna opened this issue Jul 2, 2024 · 16 comments
Assignees
Labels
question Further information is requested

Comments

@robodna
Copy link

robodna commented Jul 2, 2024

Hi,

I need to create an input component which allows a user to select a date and time in their local timezone, ( currently using date and time input types ). The server returns an ISO8601 date string like "2021-09-12T17:12:35 00:00", always in UTC time with ' 00:00'. I cannot change the datetime format the server returns. When the user submits the form, the local datetime needs to be converted to UTC time to send back to the server. ( in same format as "2021-09-12T17:12:35 00:00" )

What is the best way to approach this using modular-forms? Should I create a hidden 'datetimeUtc' input together with a visible 'datetimeLocal' input and update datetimeUtc's value in the onChange event of datetimeLocal?

It seems that the 'Field' component ads an onChange event to my custom component via the props. Is there a way to trigger the onChange event to simulate the hidden input datetimeUtc onChange so that modular-form is made aware of the change? ( to complicate things a bit, my custom component has 2 inputs, 1 for type="date" and 1 for type="time" and those 2 get combined into an ISO8601 date string like "2021-09-12T17:12:35 00:00".

I am currently adding an onChange event which is not a real 'InputEvent' but just passes a string with the new input value. I then call setValue(myForm, 'datetimeUtc', e) to update the form, but not sure if this is the best approach. I would like to have modular-form hook into the onChange event of my custom component and send an event which will be understood by modular-form. Hope this makes sense.

I should also mention I"m using Luxon for date stuff.

Thank you,

@fabian-hiller
Copy link
Owner

What framework are you using? Can you share the code for your current implementation?

@fabian-hiller fabian-hiller self-assigned this Jul 2, 2024
@fabian-hiller fabian-hiller added the question Further information is requested label Jul 2, 2024
@robodna
Copy link
Author

robodna commented Jul 2, 2024

Using SolidJS. I'm just starting so I have no substantial code to share at this point. ( just experimental code with pieces that have been deleted/removed as I test things out )

@robodna
Copy link
Author

robodna commented Jul 2, 2024

UPDATE: To keep my question as simple as possible, is there a way to programatically trigger the onChange of the Field component to pass a new input value? I think that would help me solve my original question. ( moving the updating of the input.value to inside of my component since I'm using a hidden input to store my custom element's value )

@fabian-hiller
Copy link
Owner

fabian-hiller commented Jul 3, 2024

You can use our setValue method instead: https://modularforms.dev/solid/api/setValue

@robodna
Copy link
Author

robodna commented Jul 3, 2024

Ok thanks. I'm using setValue now but how do I call it from inside of my custom component? It would be cleaner for me to use setValue in my component instead of adding an onChange attribute to it. My component is a child of and from what I can see, the props.onChange usually gets called from inside my component.

@fabian-hiller
Copy link
Owner

fabian-hiller commented Jul 3, 2024

I do not recommend calling it from inside. Instead, pass a function that calls setValue to your custom component:

<Component onChange={(value) => setValue(formStore, 'name', value)} />

@robodna
Copy link
Author

robodna commented Jul 5, 2024

Ok thanks. Maybe there could be a new event hook for manual updates instead of relaying solely on the props.onChange? In my case, my component calculates a new input value and stores it in a hidden input. The hidden input never has its onChange event triggered, so it would be nice to call onSetValue or something.

Thanks!

@fabian-hiller
Copy link
Owner

fabian-hiller commented Jul 6, 2024

Isn't the onChange from my last comment what you need? Otherwise you could also update the hidden input via an event to automatically trigger our normal props.onInput function.

@robodna
Copy link
Author

robodna commented Jul 6, 2024

The onChange needs to be called from outside of the element. It's ok and works but it would be better to have that encapsulated into the component. From what I understand the onChange event of an input field does not get triggered, only onInput....

@fabian-hiller
Copy link
Owner

The onChange needs to be called from outside of the element. It's ok and works but it would be better to have that encapsulated into the component.

I'm not sure what you mean. Can you explain it with a code example?

From what I understand the onChange event of an input field does not get triggered, only onInput....

Yes, my mistake. I meant props.onInput. I updated my comment.

@robodna
Copy link
Author

robodna commented Jul 6, 2024

For example, if a custom component does not use an input tag of any type, how would that component trigger the Field props.onChange/props.onInput events? It currently would require the custom component generate a 'fake' onChange event to trigger the Field event to update the value, even though there would be no Input/Select tag inside the custom component. I thought onInput would be triggered on the hidden input field, and that Field would update the value on those events but it did not work when I tried that.

@fabian-hiller
Copy link
Owner

fabian-hiller commented Jul 6, 2024

Progressively enhanced forms and forms with file uploads make it necessary to capture all input with a HTML form field like <input /> and <select />. Otherwise, the form input can't be successfully submitted to the server in these cases by default. My goal for Modular Forms is to be as close as possible to what's already possible in the browser to support all these cases. Unfortunately, this makes more complex cases more complicated.

I'd recommend connecting Modular Forms' props to your hidden <input /> element and updating its value via a custom input event. This way Modular Forms should automatically capture any changes. I would be happy to work this out with you to improve the DX for all developers in the long run.

@robodna
Copy link
Author

robodna commented Jul 6, 2024

Ok great. I would agree using a hidden element makes sense. What would the custom event look like? The Field props.onInput and onChange listeners expect a specific type of event. ( I would like avoid Typescript type errors ) My custom component would update the hidden input's value programatically and dispatch an onChange event for Field to handle accordingly, but what would that event look like?

@fabian-hiller
Copy link
Owner

Try to call element.dispatchEvent(new Event('input')) after updating its input.

@robodna
Copy link
Author

robodna commented Jul 7, 2024

That works well for me, problem solved. Note I had to use:
new Event('input', {bubbles:true, composed:true})

@fabian-hiller
Copy link
Owner

Thanks for the info. I will add a guide for such cases in the long run.

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

No branches or pull requests

2 participants