ngx-schema-form
ngx-schema-form copied to clipboard
Support of prefixed schema extensions
Hi there,
in order to better distinguish schema extensions from standardized keywords, I think it would make sense to add compliant alternative names. Thus, no old code needs to be changed and new code can clearly distinguish between schema and extension.
Looks like three key words are involved:
Name | Prefixed Name |
---|---|
fieldsets | x-field-sets |
widget | x-widget |
visibleIf | x-visible-if |
(I hope the list is complete...)
The reason why I write this is that I want to create the schemas from Java POJOs (at first only out of curiosity). There it would be very unclean, in my opinion, to define such properties without a prefix there. If there is any interest in this topic, I will gladly report on it.
Moreover, I have unfortunately not found the code, which e.g. makes a { "widget": { "id": "string" }
from { "widget": "string" }
. I don't know if I could do an implementation without help. Alternatively I could of course run a crappy recursive algorithm over the schema ;-)
Thanks in advance!
@WhileTrueEndWhile that's the method normalizeWidget
here: https://github.com/makinacorpus/ngx-schema-form/blob/master/projects/schema-form/src/lib/model/schemapreprocessor.ts#L98
I would advice you to give a try to the implementation, it is usually easier than one can imagine at first. We will help you if you get lost :)
Thanks for the quick answer.
Something like...
...
const props = [
{ name: "fieldsets", alias: "x-field-sets" },
{ name: "fieldsets", alias: "x-widget" }
{ name: "fieldsets", alias: "x-visible-if" }
];
props.forEach(p => {
const x = p.name;
const y = p.alias;
fieldSchema[x] = JSON.parse(JSON.stringify(fieldSchema[y] || fieldSchema[x] || null));
});
...
... will be enough?
This means that the original values (x-*
) may not be changed and both properties are in the schema at runtime.
Great!
I think that I will soon create a PR, if this really works with the few lines of code.
I don't get why you use JSON.parse and JSON.stringify here. Any reason why something like that could not work?
const props = [
{ name: "fieldsets", alias: "x-field-sets" },
{ name: "fieldsets", alias: "x-widget" }
{ name: "fieldsets", alias: "x-visible-if" }
];
props
.filter(p => p.name || p.alias)
.forEach(p => {
const id = p.alias || p.name;
fieldSchema[id] = ...
});
I have only used JSON.*
to make both properties really independent of each other (deep copy).
I don't know any easier way ;-)
Is there still something wrong with inserting this code?
Maybe you want props
to be pulled out of the code...
...because there are other 2000+ lines waiting ;-)
Otherwise I would really fork!
I have only used JSON.* to make both properties really independent of each other (deep copy).
ok, fair enough
Is there still something wrong with inserting this code?
looks good to me, go ahead
Thanks!
I don't have a code based on it yet. But when I insert this, it should of course be compact and constant. I have seen little official documentation dealing with this topic, so I want to be careful.
Almost the only thing I found is the following wiki entry of NJsonSchema, which I do not use: https://github.com/RSuter/NJsonSchema/wiki/Custom-Schema-Properties And this seems to have been just a developer's decision.
But if you look at other JSON schema attributes like oneOf
, x-widget
wouldn't fit either, but xWidget
...
Possible solution to never have to touch it again, no matter what:
Name | Regular Expression | Examples |
---|---|---|
fieldsets | /^x-?field-?sets$/i |
X-Field-Sets , x-fieldsets , xFieldSets |
widget | /^x-?widget$/i |
X-Widget , x-widget , xWidget |
visibleIf | /^x-?visible-?if$/i |
X-Visible-If , x-visbleif , xVisibleIf |
As soon as I'm settled, I'll make a request... (done)
@ebrehault To clarify my last comment: I have code based on ngx-schema-form
, but the reason why I want this feature is only now reasonably ready...
This means there is no rush to accept the PR. As motivation why I suggest this, I can briefly collect the results:
This test ...
https://github.com/WhileTrueEndWhile/JJSchema/blob/master/src/test/java/com/github/reinert/jjschema/xproperties/XPropertiesTest.java
... produces this schema ...
https://github.com/WhileTrueEndWhile/JJSchema/blob/master/src/test/resources/xproperties_example.json
... which produces this form ...
https://makinacorpus.github.io/ngx-schema-form/dist/ngx-schema-form/?https%3A%2F%2Fraw.githubusercontent.com%2FWhileTrueEndWhile%2FJJSchema%2Fmaster%2Fsrc%2Ftest%2Fresources%2Fxproperties_example.json
If my code is good enough, you can use the following POJO:
public static class XPropertiesExample {
@JsonProperty(value = "FirstName", required = true, defaultValue = "John")
@Attributes(title = "First Name")
@XProperties({ "X-Widget.id = \"string\"" })
private String firstName;
@JsonProperty(value = "LastName", required = true, defaultValue = "Doe")
@Attributes(title = "Last Name")
@XProperties({ "X-Widget.id = \"string\"" })
private String lastName;
@JsonProperty(value = "Age", required = true, defaultValue = "1")
@Attributes(title = "Age in years", minimum = 0)
@XProperties({ "X-Widget.id = \"number\"", "maximum = 100" })
private int age;
@JsonProperty(value = "EnumString", required = true, defaultValue = "foo")
@Attributes(title = "Enum String")
@XProperties(files = { "/xproperties_example.properties" })
private String enumString;
// ...
}
I think it looks subtly better. So no hurry, I want to use the "new approach" as soon as it is good enough...
ok, fine :)
My 50 cent:
We keep ngx-schema-form json schema extension in a separate file.
We call this file schemaform.json.
At compile time the standard json schema and the schemaform.json get merged together. (There are plenty deep merge libs out there)
This is driven by the fact that mostly the standard json schema cames from the backend.
Thank you for accepting this PR.
Is there a difference between...
https://github.com/makinacorpus/ngx-schema-form#conditional-fields
...
"visibleIf": {
"comment": ['$ANY$']
}
...
... and ...
https://json-schema.org/understanding-json-schema/reference/object.html#property-dependencies
...
"dependencies": {
"credit_card": ["billing_address"]
}
...
???
If not, you could transform "dependencies" to "visibleIf" as well.
@WhileTrueEndWhile I might be wrong but as far as I remember, visibleIf
is just about visibility, so if the field value exists already, it will be processed, validated, stored, etc.
Whereas dependencies
will discard the field from the model.
Thank you for the quick feedback. I have created a GIST for this. It looks like the model always matches the view after all. The only thing the standard doesn't support is "$ANY$", which should mean "not null".
http://makinacorpus.github.io/ngx-schema-form/dist/ngx-schema-form/?https%3A%2F%2Fgist.githubusercontent.com%2FWhileTrueEndWhile%2F158b63ce219a2bff0173d4b59a01d215%2Fraw%2Fb3a3e0f4dbe7ef07514e73f51d6ee1226d7a495b%2Fvisibleif.schema.json
ok well then maybe we could transform "dependencies" to "visibleIf" as you proposed
To distinguish between standard and nxg-schema-form related properties ngx-schema-form does now provide a json schema (came with #241).
Bit apart from that:
what about moving all non standard properties into the widget
property?
Even if, semantically, all our non standard properties are not all about the widget, I guess it could be nice.
Thank you very much for the great work!
I have two more additions: https://github.com/guillotinaweb/ngx-schema-form/compare/master...WhileTrueEndWhile:master
formelement.component.ts: With your own widget registry, setting the validation state CSS classes at this level is more than superfluous. In order not to break legacy code, it would be useful to define an optional property that deactivates it. Is there a way to access the global schema at this point?
schemapreprocessor.ts: The stupid copying of the "dependencies" property as "visibleIf" has already been discussed and is probably not priority 1 ;-)
Support of prefixed schema extension came with commit d7c3d8f3dadf9a8bcbaa0ba004452efc28372b72 See also : https://stackblitz.com/edit/ngx-schema-form-customs-widgets-223?file=src/app/myform/schema-form.json