SchemaForm array conditional - angularjs

Background
I am making a form using http://schemaform.io/
Setup
I am trying to make an array of objects that a user can make using a form. So, the user can add as many items into the array as they want.
The array of items contains a type, then another field depending on what the type was.
If the user clicks REST, I want it to offer a field called method.
If the user clicks SSH, I want it to offer a field called path.
Code so far
SCHEMA
{
"type": "object",
"title": "Command Asset",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"commands": {
"type": "array",
"title": "Actions",
"items": {
"type": "object",
"properties": {
"commandType": {
"title": "Command Type",
"type": "string",
"enum": [
"REST",
"SSH"
]
},
"path": {
"title": "Path",
"type": "string"
},
"method": {
"title": "Method",
"type": "string"
}
}
}
}
}
}
FORM
[
{
"type": "help",
"helpvalue": "<h5>Command</h5>"
},
"name",
{
"title":"Command",
"key": "commands",
"items": [
"commands[].commandType",
{
"type": "conditional",
"condition": "modelData.commands[0].commandType=='SSH'",
"items": [
{
"key": "commands[].path"
}
]
},
{
"type": "conditional",
"condition": "modelData.commands[0].commandType=='REST'",
"items": [
{
"key": "commands[].method"
}
]
}
]
}
]
One can test this code here: http://schemaform.io/examples/bootstrap-example.html
Question
As one can see, the code I have now makes all the items' secondary properties (path or method) dependent on the first item in the array's commandType (at [0]), but I want it to depend on the commandType of the corresponding item. So, if item one has commandType of REST, it offers a method field and if item two has a command type of SSH it offers a field of path and so on.

I found an answer.
Replace the [0] with [arrayIndex].
I found it from here: https://github.com/json-schema-form/angular-schema-form/commit/21f6d3ab64435b032456dfe19e03f96b29366320

Related

JSON Schema for array of different types with mandatory property fails validation

I created the following draft4 schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$id": "catalog.structs.schema.json",
"definitions": {
"geography": {
"type": "object",
"description": "Geographical location which may or may not be part of a hierarchy.",
"properties": {
"geography_type": {
"type": "string",
"enum": ["union", "country", "state"]
},
"name": {
"type": "string",
"enum": ["Turkey", "Netherlands"]
},
"parent": {
"type": "object",
"$ref": "#/definitions/geography"
}
},
"required": ["name"]
},
"geography_group": {
"type": "array",
"description": "A grouping of discrete geographies that are not necessarily in a common hierarchy.",
"items": {
"type" : "object",
"$ref": "#/definitions/geography"
}
}
},
"oneOf": [{
"properties": {
"geography": { "type": "object", "$ref": "#/definitions/geography"},
"geography_group" : { "type": "object", "$ref": "#/definitions/geography_group"}
},
"additionalProperties": false
}]
}
The following validates correctly against the schema
{"geography":{"name":"Turkey", "geography_type":"country"}}
However, the following fails stating that the required property name is missing.
{"geography_group":[{"geography":{"name":"Turkey", "geography_type":"country"}}]}
If I remove "required": ["name"] it works, but I don't want to remove this.
What am I doing wrong?
There are a few misconceptions here, but you broadly have the right idea.
I'm not sure what you believe the oneOf is doing here. In this case, it simply isn't required, and you can put properties and additionalProperties straight in the root schema.
In terms of your problem, while you've defined geography as a property at the root level, you haven't done so for an item object in the geography_group value array.
You want to change your geograph_group definition to the following...
"geography_group": {
"type": "array",
"description": "A grouping of discrete geographies that are not necessarily in a common hierarchy.",
"items": {
"properties": {
"geograph": {
"$ref": "#/definitions/geography"
}
}
}
}
As an aside, in draft-04 of JSON Schema, any keywords alongside $ref are ignored.
The key you use in the definitions object has no bearing on the validation of your data.

JsonSchema How to use readonly for array

I read the specification. But, I didn't find any information about how to use the readOnly of Array. And a single readonly property is not enough to cover different scenarios.
An example array schema like below:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/product.schema.json",
"title": "Products",
"type": "array",
"items": {
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
},
"productName": {
"description": "Name of the product",
"type": "string"
},
"price": {
"description": "The price of the product",
"type": "number"
}
}
}
}
Is it possible to achieve the following objectives?
The array is not allowed to add/remove any item of the array. However, it's allowed to update any item of the array.
The array is not allowed to update any item of the array. However, it's allowed to add/remove item of the array. Once an item is added to the array, the only action I can take is "remove".
readOnly is too blunt an instrument to describe those kinds of constraints. However, with a small change, you can express it with JSON Hyper-Schema. You would have to model the individual products and the list of products separately. Unlike readOnly which says what you can't do, links say what you can do. Here's what it would look like for each of the cases you identified.
The array is not allowed to add/remove any item of the array. However, it's allowed to update any item of the array.
{
"$schema": "http://json-schema.org/draft-07/hyper-schema#",
"$id": "http://example.com/product-list.schema.json",
"type": "array",
"items": { "$ref": "product.schema.json" }
}
{
"$schema": "http://json-schema.org/draft-07/hyper-schema#",
"$id": "http://example.com/product.schema.json",
"type": "object",
"properties": {
"productId": { "type": "integer" },
"productName": { "type": "string" },
"price": { "type": "number" }
},
"links": [
{ "rel": "edit", "href": "/product/{productId}" }
]
}
The array is not allowed to update any item of the array. However, it's allowed to add/remove item of the array. Once an item is added to the array, the only action I can take is "remove".
{
"$schema": "http://json-schema.org/draft-07/hyper-schema#",
"$id": "http://example.com/product-list.schema.json",
"type": "array",
"items": { "$ref": "product.schema.json" },
"links": [
{
"rel": "create",
"href": "/products",
"schema": { "$ref": "product-create.schema.json" }
}
]
}
{
"$schema": "http://json-schema.org/draft-07/hyper-schema#",
"$id": "http://example.com/product.schema.json",
"type": "object",
"properties": {
"productId": { "type": "integer" },
"productName": { "type": "string" },
"price": { "type": "number" }
},
"links": [
{ "rel": "delete", "href": "/product/{productId}" }
]
}

JSON Schema draft 4 with unordered array

I would like to create schema which allows me to add multiple addresses when the following is true:
1)Correspondence address must be there
2)Residence address must be there
3)Other types of addresses could be there
4) They can appear in any order
Is this possible to solve with JSON schema? I heard about "contains" in draft 6. But since we are using Altova XML SPY (2018), which is only supporting draft 4, for schema creation, I would like to know how to solve this in draft 4. Are you aware of any good editor for draft 6?
I read JSON schema to enforce array contents but cannot find the answer there. I also read https://gist.github.com/anonymous/7359001 which explains how to have "contains" in draft 4, but was unable to apply it to my case.
So if you can guide me, how to use it for the following schema(which fullfills my requirements except number 4), I would be very thankfull.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Corespondence"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Residence"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
}
],
"additionalItems": {
"$ref": "#/definitions/Address"
}
}
},
"definitions": {
"Address": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Corespondence",
"Residence",
"Other"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
}
}
}
draft-06 has "contains" keyword allowing to test the presence of items matching the schema in the array.
Alternatively, instead of heterogenous array you could use a map with difference address types defined in different properties, so your data could be:
{
addresses: {
correspondence: {/*...*/},
residence: {/*...*/}
// etc...
}
}
The reason contains was added to draft-06 is that it is not possible to accomplish the same thing with draft-04 keywords.
There are several implementations supporting draft-06 on the software page: http://json-schema.org/implementations.html

Angular schema form access Object with Arrays from Form

I have a scenario where i need to display arrays in side a named object like this:
"actions": {
"singleSelection": [
{
"chartable": false,
"label": ""
}
]
}
I have accomplished it with the following schema:
"schema": {
"type": "object",
"title": "smart_report",
"properties": {
"actions": {
"title": "Actions",
"type": "object",
"properties": {
"singleSelection": {
"title": "Action: Single selection",
"type": "array",
"maxItems": 10,
"items": {
"type": "object",
"properties": {
"field": {
"title": "Field name",
"type": "string"
},
"label": {
"title": "Label",
"type": "string",
"description": "Label will be used for column name."
},
"chartable": {
"title": "Chartable",
"type": "boolean"
}
}
}
}
}
}
}
Now am trying to set the 'notitle' flag on 'actions' in from and trying to access the properties of 'actions', but its not working as expected:
{
"key": "actions",
"notitle": true,
"properties": {
"key": "singleSelection",
"notitle": true,
"startEmpty": true
}
},
I still see title for actions as well for 'singleSelection' and 'stratEmpty' is also not set.
If you remove the titles from the schema, as well as using the notitle attribute it should work.
(In case you remove the title, but do not use the notitle attribute, the title will be displayed with the same name as the key).

Using an array inside array

I'm trying to generate a form which will have multiple vehicles and each vehicle should have multiple people inside it.
I tried to do it by using an array inside another array. But for some obscure reasons it's not working.
This is what I want:
http://i.imgur.com/ZB2kCa1.png
This is what I have (so far):
Form:
[
{
"key": "vehicles",
"items": [
"['vehicles'][]['plate-number']",
"['vehicles'][]['color']",
{
"key": "people",
"items": [
"['vehicles'][]['people'][]['name']"
]
}
]
}
]
Schema:
{
"type": "object",
"properties": {
"vehicles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"plate-number": {
"title": "Plate number",
"type": "string"
},
"color": {
"title": "Color",
"type": "string"
},
"people": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string",
"enum": ["dr","jr","sir","mrs","mr","NaN","dj"]
},
"name": {
"title": "Name",
"type": "string"
}
}
}
}
}
}
}
}
}
Edit:
stefankmitph's answer solvers my problem. Thank you!
But something weird is happening: a new object person is added at the same level of vehicles. Also, when I fill a person's information and then delete this person the models is not updated.
The schema you provide does not add a property 'gender' (as shown in your picture link). So I took 'title' instead of 'gender':
[
{
"key": "vehicles",
"items": [
"vehicles[].plate-number",
"vehicles[].color", {
"key": "people",
"type": "array",
"title": "People",
"items": [
"vehicles[].people[].name",
"vehicles[].people[].title"
]
}
]
}
]
I hope this is what you're looking for!
Note: Tested with Schema Form Example Page

Resources