Angular Schema Form - "required" not working select and checkbox fields - angularjs

I'm new to Angular Schema Form and having some issues with select and checkbox fields required validation.
Under $scope.schema I have the select field named designation:
"designation": {
"title": "Designation",
"type": "select",
"default": undefined
}
$scope.form (declaring designation and agreeTerms):
{
"key": "designation",
"type": "select",
"title": "Designation",
"titleMap": [
{ value: undefined, name: "Select a designation" }, // first value
{ value: "Andersson", name: "Andersson" },
{ value: "Johansson", name: "Johansson" },
{ value: "other", name: "Something else..."}
]
},
{
"key": "agreeTerms",
"type": "checkbox",
"title": "I agree to ..."
}
Both designation and agreeTerms are defined in the schema's required property.
When I submit the form, both fields however pass the required validation. What I'm expecting the UI to show are the Required messages underneath/after the fields. That is not happening.
Things I've tried:
assign first value of the select field to '' and null and match that with the schema default value.
change the select field type to object in the schema; this worked and passed the required validation but the property didn't show up in the model
Please help :)

You need to change the schema type to string as select is not a valid schema type property.
"designation": {
"title": "Designation",
"type": "string",
"default": undefined
}
Then in your form tag you should have ng-submit="submitForm(ngform,modelData)":
<form sf-schema="schema" sf-form="form" sf-model="model" ng-submit="submitForm(ngform,modelData)" sf-options="option"></form>
Then within your controller you can broadcast on submit to validate:
$scope.submitForm = function(form) {
// First we broadcast an event so all fields validate themselves
$scope.$broadcast('schemaFormValidate');
};

Related

Two kinds of labels for options in select dropdown

Using angularjs, I want to change what is being used as the label. I have objects which are either companies or people, and use a different value to display as the label. So with the example below, my dropdown options should read: Aida Whitburg, Jones Investments, Edison Yuen, using either the name as the value if it's a person or companyName if the entry is a company.
{ id: 1,
name: "Aida Whitburg",
type: "person"
},
{ id: 2,
companyName: "Jones Investments",
type: "company"},
{ id: 3,
name: "Edison Yuen",
type: "person"
}
<select id="entityDropdown"
ng-options="entity as entity.name for entity in ctrl.entities"
ng-model="ctrl.model.markedEntity" class="form-dropdown"
ng-change="ctrl.onChangeModel()">
</select>
make a new object with merged field and use it, something like that:
let people = [
{
"id": 1,
"name": "Aida Whitburg",
"type": "person"
},
{
"id": 2,
"companyName": "Jones Investments",
"type": "company"
},
{
"id": 3,
"name": "Edison Yuen",
"type": "person"
}
].map(p => {
p.label = p.name || p.companyName
return p;
});
console.log(people)

JSON Schema attribute definition: Unsupported field schema for field... : Unknown field type undefined

I'm trying to build a form based on a JSON schema and using the react-jsonschema-form component for ReactJS.
I want to use this to display a form that users can fill with various settings (CSS/HTML selectors, etc) that will be used to parse playlist tracks datas on remote webpages.
I have a selector definition in my JSON schema, like this :
"definitions":{
"selector":{
"$id": "#/definitions/selector",
"type": "object",
"title": "CSS or HTML selector used to extract datas.",
"required": [],
"properties":{
"path":{
"type": "string",
"title": "Selector path",
"default": "",
"examples": ["#playlist .track .title"]
},
"multiple":{
"type": "boolean",
"title": "Should we extract multiple values?",
"default": false,
"readOnly": true
}
}
}
}
My JSON schema for parsing tracks look then like this:
"track":{
"$id": "#/properties/selectors/properties/track",
"type": "object",
"title": "Track selectors",
"required": [
"title"
],
"properties":{
"artist":{
"$ref": "#/definitions/selector",
"title": "Track artist"
},
"title":{
"$ref": "#/definitions/selector",
"title": "Track title"
},
"album":{
"$ref": "#/definitions/selector",
"title": "Track album"
},
"image":{
"$ref": "#/definitions/selector",
"title": "Track image"
},
"duration":{
"$ref": "#/definitions/selector",
"title": "Track duration"
},
"location":{
"$ref": "#/definitions/selector",
"title": "Track locations",
"properties":{
"multiple":{
"default": true
}
}
},
"link":{
"$ref": "#/definitions/selector",
"title": "Track links",
"properties":{
"multiple":{
"default": true
}
}
}
}
}
As you see, the selector definition is used for the artist, title, album, image, duration, location and link attributes.
the multiple attribute of the selector definition is used to know if the parser should extract a single or multiple values.
Its readonly attribute is set to true because the user cannot choose this: I know a track has only ONE artist, title, album, image and duration, but might have several location (files) and links attached to.
"location":{
"$ref": "#/definitions/selector",
"title": "Track locations",
"properties":{
"multiple":{
"default": true
}
}
},
"link":{
"$ref": "#/definitions/selector",
"title": "Track links",
"properties":{
"multiple":{
"default": true
}
}
}
This is where I have a problem:
When displaying those two fields, react-jsonschema-form renders those errors:
Track locations
multiple
Unsupported field schema for field root_selectors_track_location_multiple: Unknown field type undefined.
{
"default": true
}
Track links
multiple
Unsupported field schema for field root_selectors_track_link_multiple: Unknown field type undefined.
{
"default": true
}
I don't know if this occurs because my JSON schema is not well defined (can I "override" the properties of a definition like this ?) or if this is a bug of react-jsonschema-form.
Can someone help ?
Thanks for your long read!
From what I can read in the documentation, the react JSON schema forms library supports draft-07 of the JSON schema specification. In this case, any schema keyword beside $ref at this sub-schema level is simply ignored.
From https://json-schema.org/understanding-json-schema/structuring.html#ref
In Draft 4-7, $ref behaves a little differently. When an object
contains a $ref property, the object is considered a reference, not a
schema. Therefore, any other properties you put in that object will
not be treated as JSON Schema keywords and will be ignored by the
validator. $ref can only be used where a schema is expected.
You will need to change your schema to reflect this. An option could be to surround your extension with allOf:
"location": {
"allOf": [
{ "$ref": "#/definitions/selector" },
{
"title": "Track locations",
"properties": {
"multiple":{
"default": true
}
}
}
]
}

Is there a way to make make one of the enum value as mandatory using react-jsonschema-form?

I have the following question where option a needs to be mandatory and option b is optional.
Where do you live?
a. Earth // User has to select this
b. Mars // User may or maynot select this
The schema for it is as:
"properties": {
"live": {
"title": "Where do you live?",
"items" : {
"type": string,
"enum": [
"Earth",
"Mars"
]
},
"minItems": 1,
"uniqueItems": true
},
}
Is there a way on react-jsonschema-form to make option "Earth" as required or mandatory field.

empty array in angular-schema-form

I'm using angular-schema-form in my project and trying to add an empty array in my model.
I expected that array type schema form will not contain any items but it actually pushed one object in my array and showed it in from.
How can I init form with no items in array?
html
<div ng-app="app" ng-controller="Controller as ctr">
<form sf-schema="ctr.schema" sf-form="ctr.form" sf-model="ctr.model"></form>
{{ctr.model.comments}} - Where this object come from? This array was empty. Is it possible to keep it empty on load?
</div>
js
var myApp = angular.module('app', ['schemaForm'])
.controller("Controller", function() {
this.schema = {
"type": "object",
"title": "Comment",
"properties": {
"comments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"comment": {
"title": "Comment",
"type": "string",
"maxLength": 20,
"validationMessage": "Don't be greedy!"
}
}
}
}
}
};
this.form = [{
"key": "comments",
"items": [
"comments[]"
]
}];
this.model = {
comments: [] // Empty array defined
};
});
Jsfiddle
The value you are looking for is startEmpty: true this will avoid pre-populating the array with an object.
Angular Schema Form: Array Documentation
The pre-population is defaulted to ensure that the form fields within an array are available when the form loads. The startEmpty: true value can override this behaviour.

Angular Schema Form custom synchronous validation not working at the very onset

I am using the below Schema and Form. Please check the JSFiddle below for how this behaves. I'd like for form to be Not Valid when I say yes to "Do I have to agree" but then did not check the "agree" and clicked the save button. Looks like I first have to select the agree and then un-select it for the validation message to appear.
http://jsfiddle.net/mutharasus/Ljp7bhgn/
$scope.schema = {
"type": "object",
"properties": {
"doIHaveToAgree": {"type": "boolean"},
"agree": { "type": "boolean" }
},
"required": ["doIHaveToAgree"]
};
$scope.form = [
{
"key":"doIHaveToAgree",
"title": "Do I have to agree",
"type":"radios-inline",
"titleMap":[{"value":true,"name":"Yes"},{"value":false,"name":"No"}]
},
{
"key": "agree",
"condition": "model.doIHaveToAgree",
"validationMessage": {
"agreeRequired": "You have to agree"
},
"$validators": {
"agreeRequired": function(value){
return value;
}
}
},
{
"type": "submit",
"title": "Save"
}
];
This appears to be as a result of https://github.com/Textalk/angular-schema-form/issues/388
I do not want to make "agree" required since that would only work for the UI. On the server side the schema validation would fail when "doIHaveToAgree" is false.
Is there any way for me to trigger the $validate() on the field manually since the $validate() is not being invoked as part of the schemaFormValidate event?

Resources