remoteoss / json-schema-form Goto Github PK
View Code? Open in Web Editor NEWHome Page: https://json-schema-form.vercel.app
License: MIT License
Home Page: https://json-schema-form.vercel.app
License: MIT License
The following example is about description
, but this happens with any conditional attribute (title, minimum, etc).
Given a form that asks for two fields is_full_time
(yes/no) and hours
(number). If yes is selected, then it shows a description warning about the maximum hours.
The JSON Schema is the following:
{
"properties": {
"is_full_time": {
"type": "string",
"title": "Is full time",
"oneOf": [{ "const": "yes", "title": "Yes" }, { "const": "no", "title": "No" }]
},
"hours": { "type": "number", "title": "Hours per day" }
},
"allOf": [
{
"if": {
"properties": { "is_full_time": { "const": "yes" } },
"required": ["is_full_time"]
},
"then": {
"properties": {
"hours": {
"description": "We recommend no more than 8 hours."
}
}
}
}
]
}
Steps to reproduce:
For this scenario, a workaround could be to undo the value by set description: ""
in the else
statement, like this:
"else": {
"properties": {
"hours": {
"description": ""
}
}
}
But this ain't possible for every attribute. For example, if you set const: 10
, there's no way to "undo" it. Same for any other type of validation.
Hello!
First off I just want to share that this looks really great, and I'd love to be able to make use of the package!
Currently however I'm blocked by the missing support for the $ref
keyword - I'm working with a pretty complicated schema (it's defined in multiple different files, but is almost 1000 lines when bundled together), and using internal $ref
s for organizational purposes.
I think there's a workaround here that would work for most of my use case, which is just to dereference those $ref
s in all locations when rendering the form; however we'd really prefer not to have to do that if at all possible!
Would you all be open to adding this to your roadmap, and if so, what sort of timeline do you think we'd be looking at for getting that change in?
Thanks for the great tool json-schema-form
!
it is very helpful because it is headless and can be used in any framework.
In many json schemas generated by other tools (e.g. OpenAPI, Pydantic, ...), you may see the keyword $ref
which is used to reference another schema. This is a very useful feature to avoid duplication and keep the schema DRY.
It would be great if json-schema-form
can support this feature. I have tried to use it but it seems not working. I have also checked the documentation and the source code but I cannot find any information about this.
Most of cases, the $defs
is defined in the same definition, so it should be easy to implement.
ex) #/$defs/Person
will point to the definition of {"$defs": { "Person": {... } } }
in the same file.
So, before parsing the schema, we can resolve the $ref
and replace it with the actual definition.
I've wrote some simple pseudo code to demonstrate how it can be implemented. I hope this will be helpful.
function getRef(path: string, object: any): any {
const keys = path.replace(/^#/, '').split('/');
let current = object;
for (const key of keys) {
if (key in current) {
current = current[key];
} else {
return null;
}
}
return current;
}
function resolveRefs(object: any, rootObject: any = object): any {
for (const key in object) {
const value = object[key];
if (typeof value === 'object' && value !== null) {
if ('$ref' in value) {
const resolved = getRef(value['$ref'], rootObject);
if (resolved) {
object[key] = resolved;
} else {
// throw new Error('Cannot resolve reference: ' + value['$ref']);
console.error('Cannot resolve reference:', value['$ref']);
}
} else {
// go recursive
resolveRefs(value, rootObject);
}
}
}
return object;
}
Then, add option to the createHeadlessForm
function to enable this feature.
const { fields, handleValidation } = createHeadlessForm(schema, {
resolveRefs: true, // or the referable other schema
})
I hope this feature will be implemented in the future. Thanks!
I've been using the library for my personal projects, and it's been excellent. I plan on using the library for a work project and was wondering if we could get some information on the future plans/roadmap for a stable release version.
Thanks!
Currently the roadmap for json-schema-form
is private for Remote only. We plan to move it to GitHub soon.
Given the following JSON Schema, I cannot override errorMessage using createHeadlessForm()
{
"type": "object",
"additionalProperties": false,
"properties": {
"browsers": {
"title": "Browsers (solo)",
"description": "This solo select also includes a disabled option.",
"type": "string",
"oneOf": [
{
"const": "chr",
"title": "Chrome"
},
{
"const": "ff",
"title": "Firefox"
},
{
"const": "ie",
"title": "Internet Explorer",
"disabled": true
}
],
"x-jsf-presentation": {
"inputType": "select"
}
},
"has_pet": {
"title": "Has Pet",
"description": "Do you have a pet?",
"oneOf": [
{
"title": "Yes",
"const": "yes"
},
{
"title": "No",
"const": "no"
}
],
"x-jsf-presentation": {
"inputType": "radio"
},
"type": "string"
},
"pet_name": {
"title": "Pet's name",
"description": "What's your pet's name?",
"x-jsf-presentation": {
"inputType": "text"
},
"type": "string",
"errorMessage": "string"
}
},
"required": ["has_pet"],
"x-jsf-order": ["has_pet", "pet_name"],
"allOf": [
{
"if": {
"properties": {
"has_pet": {
"const": "yes"
}
},
"required": ["has_pet"]
},
"then": {
"required": ["pet_name"]
},
"else": {
"properties": {
"pet_name": false
}
}
}
]
}
JSF Config:
const { fields, handleValidation } = createHeadlessForm(Schema, {
inputTypes: {
errorMessage: {
required: 'This cannot be empty.',
},
},
});
This is very important to be able to i18n in the application
{
$schema: 'http://json-schema.org/draft-04/schema#',
$id: 'https://example.com/employee.schema.json',
title: 'Input',
description: 'Soooooooo meee',
type: 'object',
properties: {
id: {
description: 'A unique identifier for an employee',
type: 'number',
},
name: {
description: 'Full name of the employee',
type: 'string',
},
age: {
description: 'Age of the employee',
placeholder: 'Age of the employee',
type: 'number',
},
maggies: {
description: 'maggies of the employee',
type: 'object',
properties: {
name: {
description: 'Full name of the employee',
type: 'string',
},
age: {
description: 'Age of the employee',
placeholder: 'Age of the employee',
type: 'number',
},
},
},
dependent_details: {
items: {
properties: {
birthdate: {
description: 'Enter your child’s date of birth',
format: 'date',
'x-jsf-presentation': {
inputType: 'date',
},
title: 'Child Birthdate',
type: 'string',
maxLength: 255,
},
full_name: {
description: 'Enter your child’s full name',
'x-jsf-presentation': {
inputType: 'text',
},
title: 'Child Full Name',
type: 'string',
maxLength: 255,
},
sex: {
description:
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
enum: ['female', 'male'],
'x-jsf-presentation': {
inputType: 'radio',
options: [
{
label: 'Male',
value: 'male',
},
{
label: 'Female',
value: 'female',
},
],
},
title: 'Child Sex',
},
},
'x-jsf-order': ['full_name', 'birthdate', 'sex'],
required: ['full_name', 'birthdate', 'sex'],
type: 'object',
},
'x-jsf-presentation': {
inputType: 'group-array',
addFieldText: 'Add new field',
},
title: 'Child details',
description: 'Add the dependents you claim below',
type: 'array',
},
optional_dependent_details: {
items: {
properties: {
birthdate: {
description: 'Enter your child’s date of birth',
format: 'date',
'x-jsf-presentation': {
inputType: 'date',
},
title: 'Child Birthdate',
type: 'string',
maxLength: 255,
},
full_name: {
description: 'Enter your child’s full name',
'x-jsf-presentation': {
inputType: 'text',
},
title: 'Child Full Name',
type: 'string',
maxLength: 255,
},
sex: {
description:
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
enum: ['female', 'male'],
'x-jsf-presentation': {
inputType: 'radio',
options: [
{
label: 'Male',
value: 'male',
},
{
label: 'Female',
value: 'female',
},
],
},
title: 'Child Sex',
},
},
'x-jsf-order': ['full_name', 'birthdate', 'sex'],
required: ['full_name', 'birthdate', 'sex'],
type: 'object',
},
'x-jsf-presentation': {
inputType: 'group-array',
addFieldText: 'Add new field',
},
title: 'Child details (optional)',
description:
'This is an optional group-array. For a better UX, this Component asks a Yes/No question before allowing to add new field entries.',
type: 'array',
},
hobbies: {
description: 'Hobbies of the employee',
type: 'object',
properties: {
indoor: {
type: 'array',
items: {
'x-jsf-presentation': {
inputType: 'text',
},
description: 'List of indoor hobbies',
type: 'string',
},
},
outdoor: {
type: 'array',
title: 'Child details',
description: 'List of outdoor hobbies',
items: {
description: 'List of outdoor hobbies',
type: 'object',
properties: {
indoor: {
type: 'array',
items: {
description: 'List of indoor hobbies',
type: 'string',
},
},
outdoor: {
type: 'array',
items: {
description: 'List of outdoor hobbies',
type: 'string',
},
},
},
},
},
maggies: {
description: 'Hobbies of the employee',
type: 'object',
properties: {
indoor: {
type: 'array',
items: {
description: 'List of indoor hobbies',
type: 'string',
},
},
outdoor: {
type: 'array',
items: {
description: 'List of outdoor hobbies',
type: 'string',
},
},
},
},
},
},
},
required: ['id'],
}
The above schema breaks the form due to this part here
outdoor: {
type: 'array',
title: 'Child details',
description: 'List of outdoor hobbies',
items: {
description: 'List of outdoor hobbies',
type: 'object',
properties: {
indoor: {
type: 'array',
items: {
description: 'List of indoor hobbies',
type: 'string',
},
},
outdoor: {
type: 'array',
items: {
description: 'List of outdoor hobbies',
type: 'string',
},
},
},
},
},
Would have loved to make a fix, but I'm encumbered
Given the following JSON Schema, I cannot override its errorMessage
using createHeadlessForm()
{
"properties": {
"year": {
"title": "Year",
"type": "number",
"presentation": {
"inputType": "number"
},
"x-jsf-errorMessage": {
"required": "Cannot be empty."
},
"minimum": 1900,
"maximum": 2023
}
},
"required": ["year"]
}
JSF Config:
const { fields } = createHeadlessForm(schemaAbove, {
customProperties: {
year: {
errorMessage: {
required: "The year is mandatory."
}
}
}
})
It looks like yall are trying to put this function in to the repo so it simplifies for those looking to implement your library. I have come across your library and I am using it for my SaaS platform. Its been good so far pretty straight forward with good enough documentation. How ever I am stuck on shaping the jsonValues in regards to the group-array type so I can get some validation running. Everything else is working fine with validation and errors for my form except for the nested inputs inside my group-arrays. How should I approach this or can you get me a developer preview on what the 'formValuesToJsonValues' function is going to look like that y'all are planning to ship with the library.
Example of Json Values I'm passing to handleValidation:
{ "club_code": "Dallas - Uptown", "team_member_last_name": "d", "team_member_email": "[email protected]", "team_member_street_address": "409 St", "team_member_city": "Bville", "team_member_state": "AK", "expense_details": [ { "amount": "32324", "receipt": "<redacted url>" } ] }
The group array expense_details has 5 required fields and the overall form has many required fields and returns back
{ "team_member_first_name": "Required field" }
Which is accurate for the main part of the form its just not validating my group-array.
Any assistance on this would be greatly appreciated. Also happy to provide more details as needed. Thanks.
Maybe you can make public the docs examples, that would be of help to many.
Has anyone tried this package with react native expo and does it work?
Only one issue with sveltekit, I had to manually jam a default eport in there, could you please add a default clause?
Currently, given a JSON Schema not supported by json-schema-form
, the error message is hard to understand and trace back to where the problem originates from.
Evaluate a JSON Schema structure before trying to parse it, to spot and warn about invalid types.
For example, in this #21 , the error should be:
- JSON Schema invalid TypeError: innerFields.forEach is not a function
+ JSON Schema invalid: data/properties/hobbies/items/type must be object
Investigate the possibility of using TypeScript, Zod, or any other typing tool for this type check.
Hi,
I am evaluating your library. Therefore I would like to prefill a form with values.
I use pass initialValues to createHeadlessForm() like this
export default function WithReact() {
const { fields, handleValidation } = createHeadlessForm(jsonSchemaDemo, {
strictInputType: false, // so you don't need to pass presentation.inputType
initialValues: { name: "Initial value" },
});
...
I can't get this to work tough with your demo on the quickstart page. The initialValue is ignored.
Is this the correct way or am I missing something?
Here is an example btw:
https://codesandbox.io/p/sandbox/json-schema-form-demo-react-forked-5sfc7d
i have this json schema
{
"type": "object",
"additionalProperties": false,
"properties": {
"AccountType": {
"title": "Select account type",
"description": "",
"x-jsf-presentation": {
"inputType": "select"
},
"oneOf": [
{
"title": "Normal User",
"const": 0
},
{
"title": "Business",
"const": 1
},
{
"title": "Services Provider",
"const": 2
}
],
"type": "number"
}
},
"required": [],
"x-jsf-order": [
"AccountType"
]
}
and on validation cannot accepts that value must be number and not string
as the output field is (it has schema type : string)
{
"type": "select",
"name": "AccountType",
"label": "Select account type",
"options": [
{
"label": "Normal User",
"value": 0
},
{
"label": "Business",
"value": 1
},
{
"label": "Services Provider",
"value": 2
}
],
"required": false,
"inputType": "select",
"jsonType": "number",
"computedAttributes": {},
"description": "",
"errorMessage": {},
"schema": {
"_deps": [],
"_conditions": [],
"_options": {
"abortEarly": true,
"recursive": true
},
"_exclusive": {},
"_whitelist": {
"list": {},
"refs": {}
},
"_blacklist": {
"list": {},
"refs": {}
},
"tests": [],
"transforms": [
null,
null
],
"type": "string",
"_type": "string",
"_nullable": true
},
"scopedJsonSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"AccountType": {
"title": "Select account type",
"description": "",
"x-jsf-presentation": {
"inputType": "select"
},
"oneOf": [
{
"title": "Normal User",
"const": 0
},
{
"title": "Business",
"const": 1
},
{
"title": "Services Provider",
"const": 2
}
],
"type": "number"
}
},
"required": [],
"x-jsf-order": [
"AccountType"
]
},
"isVisible": true
}
Given the following JSON Schema, and handleValidation({})
for nested conditions is not working: Cannot read properties of undefined (reading 'country')
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"additionalProperties": false,
"properties": {
"location": {
"title": "Delivery location",
"x-jsf-presentation": {
"inputType": "fieldset"
},
"type": "object",
"additionalProperties": false,
"properties": {
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"city": {
"type": "string"
},
"country": {
"type": "string"
},
"state": {
"type": "string"
},
"zip": {
"type": "string"
}
},
"required": [
"country"
]
},
"test": {
"title": "Test",
"type": "string",
"x-jsf-presentation": {
"inputType": "text",
"step": "additional"
}
}
},
"required": [
"location"
],
"allOf": [
{
"if": {
"properties": {
"location": {
"properties": {
"country": {
"const": "US"
}
},
"required": [
"country"
]
}
},
"required": [
"location"
]
},
"then": {
"required": [
"test"
]
},
"else": {
"properties": {
"test": false
}
}
}
]
}
Currently we do not have any github template for issues or PR.
Create:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.