ngx-schema-form
ngx-schema-form copied to clipboard
Being able to pass variables to Custom Widgets
Hi, I think it could be nice to make able to pass variables to Custom Widgets, I would like to have something like this:
<sf-form [schema]="mySchema" [extraData]=extraData></sf-form>
And then in our custom widgets, we could use that extra data to retrieve extra data needed to complete the input, or just to perform more complex validations.
Why don't you just add your extraData directly in the schema?
Idea of a solution
Often the JSON schema used as base for the form will be provided by a REST web-service endpoint. Therefore it doesn't always have the final structure to create a form out of it without making changes.
I would suggest to manage an extra JSON schema to describe the form.
This extra JSON schema may also contain additional fields or override existing fields..
Then merging them both together will create the final schema JSON to be used within the sf-form
.
Example
Lets assume you have a JSON schema for a login provided by an REST endpoint.
Actually there is not type password
in JSON schema,
so you would need to handle this anyway.
- Original JSON Schema from Webservice
const orgSchema =
{
"type":"object",
"properties":{
"password":{
"type":"string",
"description":"Password musst match conditions...",
"minLength":10
},
"name" : {
...
}
}
}
- Additional JSON Schema to enhance the form or provide extra data
let formSchema =
{
"name": "Name for your form",
"schemaExtradata":"schemaExtradataContent"
"properties":{
"password":{
"widget": "password",
"description":"Set a password",
"passwordFieldExtradata":"passwordFieldExtradataContent",
"placeholder":"*****"
},
"name" : {
...
}
}
}
Here name
, schemaExtradata
, passwordFieldExtradata
and placeholder
are provided as extra data and description
field gets overridden.
- Merge them together to the final JSON schema
const finalSchemaObject = mergeDeep(newSchema, newSchemaModel);
will look like
{
"type":"object",
"name": "Name for your form",
"schemaExtradata":"schemaExtradataContent"
"properties":{
"password":{
"type":"string",
"minLength":10,
"widget": "password",
"description":"Set a password",
"passwordFieldExtradata":"passwordFieldExtradataContent",
"placeholder":"*****"
},
"name" : {
...
}
}
}
than use it
<sf-form [(schema)]="finalSchemaObject"></sf-form>
and this is how extra data may be accessed
let _schemaName = this.schema.name
let _schemaExtradata = this.schema.schemaExtradata
let _passwordFieldExtradata = this.formProperty.schema.passwordFieldExtradata
let _placeholder = this.formProperty.schema.placeholder
Util
This simple method here may be used to merge Objects
export default function mergeDeep(target, source) {
const output = Object.assign({}, target);
if (isObject(target) && isObject(source)) {
Object.keys(source).forEach(key => {
if (isObject(source[key])) {
if (!(key in target)) {
Object.assign(output, {[key]: source[key]});
} else {
output[key] = mergeDeep(target[key], source[key]);
}
} else {
Object.assign(output, {[key]: source[key]});
}
});
}
return output;
}