Skip to content

Support for Date objects #187

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

Closed
antonio-ivanovski opened this issue Apr 8, 2025 · 10 comments
Closed

Support for Date objects #187

antonio-ivanovski opened this issue Apr 8, 2025 · 10 comments
Labels
user request Requested by user

Comments

@antonio-ivanovski
Copy link

Suggestion
The JS Date object should be supported as Date value in the editor.

I am aware that Date is not valid JSON value.
Use case

  • The JsonEditor can be used to display Date data
  • I am using the JsonEditor to display developer data that will make request with and to view the response data. For easier working with the data, the API layer does the conversion of number/string->Date.
@antonio-ivanovski antonio-ivanovski added the user request Requested by user label Apr 8, 2025
@CarlosNZ
Copy link
Owner

CarlosNZ commented Apr 8, 2025

You should be able to do this with a Custom Node, I think.

There's actually an example of a DatePicker custom component in the repo, which you can see here: https://github.com/CarlosNZ/json-edit-react/blob/main/demo/src/customComponents/DateTimePicker.tsx

However, that expect dates as ISO strings, which is still valid JSON, whereas I think you're wanting actual Date objects in the data, right? But it should still be possible with a custom component, you'll just have to change the condition function to recognise dates, and then decide how you want them displayed and edited.

I'm happy to help you work through what you need to find a solution, as I'd like this package to be flexible enough to easily handle things like this. So let me know how you're getting and what might be getting in your way.

(Also, if you do come up with a good custom component, please share it, as I'd like to start showcasing a library of custom components for people to use)

@antonio-ivanovski
Copy link
Author

Thanks for the response @CarlosNZ

I have looked into using Custom Node but I am dissatisfied with the result I am getting. I just used the StringDisplay component from the library, but the issue is that the Date as an object is being wrapped into the Object wrapper.

Here it is how it looks for the expiresAt:

Image

What I want to achieve is similar look and feel to the existing style and get the Date rendered aout in some field value. Looked into the library and maybe exposing ValueNodeWrapper would be helpful to achieve this.

Maybe the best path forward is to have library exposed custom component for Date values, similar to the exposed Link String custom node.

@CarlosNZ
Copy link
Owner

CarlosNZ commented Apr 9, 2025

Ah, the problem is that because the "Date" is an Object, the component is treating it as a "Collection" node rather than a "Value", hence it's nested inside the braces.

Bit annoying, yeah. Leave it with me and I'll try and come up with a solution (or at least a workaround)

@antonio-ivanovski
Copy link
Author

antonio-ivanovski commented Apr 9, 2025

Thanks @CarlosNZ, that was exactly the point and conclusion I had looking at the code.

Maybe the best path forward is to expose some of the building blocks, especially the wrappers. Then implementing the Date custom node would be easy.

@CarlosNZ
Copy link
Owner

CarlosNZ commented Apr 9, 2025

I can fix this pretty easily by adding an additional check to my isCollection function to ignore Date objects. After that it's going to work pretty well, I think.

@antonio-ivanovski
Copy link
Author

I can fix this pretty easily by adding an additional check to my isCollection function to ignore Date objects. After that it's going to work pretty well, I think.

Possible solution. Not sure if the library should handle Date objects by default. Maybe sane option is to display the Date objects as string values with value of Date.toISOString()?

@CarlosNZ
Copy link
Owner

CarlosNZ commented Apr 9, 2025

I can fix this pretty easily by adding an additional check to my isCollection function to ignore Date objects. After that it's going to work pretty well, I think.

Possible solution. Not sure if the library should handle Date objects by default. Maybe sane option is to display the Date objects as string values with value of Date.toISOString()?

Yeah, I'm not going to "handle" dates so much as just not treat them as a collection (as it's a whole different React component, with a whole lot of different rendering logic). We can do the toIsoString() thing, perhaps, but I still need to modify isCollection otherwise the Date will get captured by the Collection component and never even get the chance to be rendered as a string.

CarlosNZ added a commit that referenced this issue Apr 10, 2025
* Handle Date values
* Improve types
@CarlosNZ
Copy link
Owner

Hi @antonio-ivanovski, this should be working correctly now in v1.25.5.

You can define a very basic Date custom component with this definintion (which goes in the customNodeDefinitions array:

{
  condition: (nodeData) => nodeData.value instanceof Date,
  element: (props) => {
    const { nodeData, isEditing, setValue, getStyles, canEdit, value, handleEdit } = props
    return isEditing ? (
      <StringEdit
        styles={getStyles('input', nodeData)}
        pathString={toPathString(nodeData.path)}
        {...props}
        value={value instanceof Date ? value.toISOString() : (value as string)}
        setValue={setValue as React.Dispatch<React.SetStateAction<string>>}
        handleEdit={() => {
          const newDate = new Date(value as string)
          handleEdit(newDate as any)
        }}
      />
    ) : (
      <StringDisplay
        {...props}
        styles={getStyles('string', nodeData)}
        canEdit={canEdit}
        pathString={toPathString(nodeData.path)}
        value={nodeData.value.toLocaleString()}
      />
    )
  },
  showEditTools: true,
  showOnEdit: true,
}

There's no error handling, or anything fancy, but it displays a locale string in normal view, an ISO string when editing, and converts it to a Date object on submission.

@CarlosNZ
Copy link
Owner

I've started a collection of custom components now (bit rough around the edges, but it's a start), and the Date Object one is working quite well I think. You can copy the code as you see fit @antonio-ivanovski .

Library root/ReadMe

DateObject component

@antonio-ivanovski
Copy link
Author

Looking good. Thanks for the great support!

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
user request Requested by user
Projects
None yet
Development

No branches or pull requests

2 participants