Multi level dropdown using react json schema forms - reactjs

Is it possible to have multi-level dropdown using react json schema forms?
I accomplish to get a simple dropdown using a schema like:
{
"title": "A registration form",
"description": "A simple form example.",
"type": "object",
"properties": {
"Dropdown Label": {
"type": "object",
"enum": [
"Dropdown Option One",
"Dropdown Option One"
]
}
}
}
But I want something like in the image:
I tried to use nested objects in enums it didn't work and didn't find any example in their documentation as well.
Any help would be great! Thanks

Related

Why are my dataset features IDs undefined in Mapbox GL while I have set them?

I struggle to set feature IDs using mapbox GL.
I've read that you can auto-generate IDs using generateId:true in your source:
Whether to generate ids for the geojson features. When enabled, the
feature.id property will be auto assigned based on its index in the
features array, over-writing any previous values.
Except that I want to use my data at other places than just the mapbox map (a list of markers aside); so I would like to set them manually because I want to be able to target my feature on the map from my list aside. So, I don't want to use generateId:true here.
In the doc, their dataset example is like
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "marker-iv1qi3x10",//an ID here
"title": "Burnham Park",
"description": "A lakefront park on Chicago's south side.",
"marker-size": "medium",
"marker-color": "#1087bf",
"marker-symbol": "marker-blue"
},
"geometry": {
"coordinates": [
-87.603735,
41.829985
],
"type": "Point"
},
"id": "0de616c939ce2f31676ff0294c78321b"//another ID here
}
]
}
So they have an ID in the feature object "id": "0de616c939ce2f31676ff0294c78321b", and another ID in the properties of that feature "id": "marker-iv1qi3x10".
I guess that the ID that mapbox uses internally for features (and auto-generated when generateId is set to true in your source) is the first one.
Let's say I set the IDs manually:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "customPropId01"
},
"geometry": {
"coordinates": [
-87.603735,
41.829985
],
"type": "Point"
},
"id": "customID01"
}
]
}
When inspecting the data when the source has loaded, my custom IDs are still in place (using this code).
//when a specific source has been loaded
map.on('sourcedata', (e) => {
if (e.sourceId !== 'markers') return;
if (!e.isSourceLoaded) return;
console.log("SOURCE DATA LOADED",e.source);
});
But when I click on a marker on the map and that I log it, the ID property of my feature has been removed and is now undefined:
Rather than using my input source data to list my markers, I also had a look at querySourceFeatures, but this doesn't help since it returns only the features in the map bouding box - and I want my listing to display all the features, that is why I need to use the "raw" source data there.
This is driving me crazy.
Does anyone knows why the IDs are unset and how I could fix this ?
Thanks !
Your id is a string. But if you want preserve your id, this string should be cast in integer like the doc explain:
Features are identified by their id attribute, which must be an integer or a string that can be cast to an integer.
I found out that you can set promoteId to the feature property you want to use as IDs :
map.addSource('markers',{
type:"geojson",
data:"http://www.example.com/markers.geojson",
promoteId:'unique_id'
})
With promoteId:'unique_id', the property unique_id of my features will be used to set each feature's ID.

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
}
}
}
]
}

Render the select form items dynamically as per the user select the dropdown value in REACT?

Hello there so today I have this confusion on how to dynamically render more select dropdown options.
The scene is during a form submittion user has to select a category and if he select a category having sub category I have to render the next select dropdown. The data I get from api looks like this.
{
"id": "f35dc7d2-755e-4531-981b-6862bbb97512",
"name": "Mobile & Accesories",
"image": null,
"categories": [
{
"id": "d038c127-d3f8-47f6-a47b-0f4b625e8caf",
"name": "Handsets",
"image": null,
"categories": [
{
"id": "ab46c001-7d8e-4784-99de-eb26f67dc4e2",
"name": "Smartphone",
"image": "",
"categories": []
}
]
}
]
}
So at last, if there are no inner categories the final one's id should be used to send to the api.
I know working with react hooks so it would be helpful if I can get some help or the logics to accomplish this task.
You can Create those Dynamic Dropdowns using Recursion for the Same Component.
Here is the Code Sandbox demo from the API Data you have given:
https://codesandbox.io/s/gifted-paper-4cu6l?file=/src/SimpleSelect.js

Microsoft Azure Search

I have a use case in which:
I want to store images in Microsoft Blob storage,
Search images by giving text input like 'water' then all images which contain water in any way should appear in the search result.
I followed below link:
https://github.com/Azure/LearnAI-Cognitive-Search/blob/master/05-Lab-2-Image-Skills.md
But here I get to know that there are only 2 predefined skills which are ImageAnalysisSkill and OcrSkill which do not give full images as the search result.
Please help...
Programatically, you can use the Image Analysis Cognitive Skill to automatically extract tags from the images.
See https://learn.microsoft.com/en-us/azure/search/cognitive-search-skill-image-analysis for more information on this skill.
Your skill would look something like this:
{ "#odata.type": "#Microsoft.Skills.Vision.ImageAnalysisSkill",
"context": "/document/normalized_images/*",
"visualFeatures": [
"Tags",
"Description"
],
"defaultLanguageCode": "en",
"inputs": [
{
"name": "image",
"source": "/document/normalized_images/*"
}
],
"outputs": [
{
"name": "tags",
"targetName": "myTags"
},
{
"name": "description",
"targetName": "myDescription"
}
]
}
Then in the index, make sure to create a field of type Collection(Edm.String) to contain the list of tags. Let's call that the imageTags field. Make sure that field is searchable.
In the output field mappings (a property of the indexer) you will need to map the list of tags to the newly created imageTags field as follows:
"outputFieldMappings": [
{
"sourceFieldName": "/document/normalized_images/*/myDescription/tags/*",
"targetFieldName": "imageTags"
}
This will ensure that each of the tags found on the images are insterted in the imageTags array.
Please also read this document that explains how to extract normalized_imagesif you are not familiar with that already: https://learn.microsoft.com/en-us/azure/search/cognitive-search-concept-image-scenarios

Angular schema form destroyStrategy works only on siblings that are array of objects. It does not work on other siblings

I have not been successful in getting the destroy strategy to work on any sibling properties or sibling objects. It only works on sibling array of objects. Please check this example:
$scope.schema = {
"type": "object",
"properties": {
"propertyOne": {
"type": "string",
"enum": ["option1", "option2"],
"title": "Property One Select"
},
"propertyTwo": {
"type": "string",
"enum": ["option3", "option4"],
"title": "Property Two Select"
},
"objectOne": {
"type": "object",
"properties": {
"objectOnePropertyThree": {
"type": "string",
"enum": ["option5","option6"],
"title": "Property Three Select"
}
}
},
"arrayOfObjects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"arrayObjectPropertyFour": {
"type": "string",
"enum": ["option7","option8"],
"title": "Property Four Select"
}
}
}
}
},
"required": ["propertyOne"]
};
$scope.form = [{
"key": "propertyOne"
}, {
"key": "propertyTwo",
"condition": "model.propertyOne === \"option1\""
},{
"key": "objectOne.objectOnePropertyThree",
"condition": "model.propertyOne === \"option1\""
},{
"key": "arrayOfObjects",
"condition": "model.propertyOne === \"option1\""
},
{
"type": "submit",
"title": "Save"
}];
http://jsfiddle.net/mutharasus/dp18a70b/
In here if you select the first dropdown to "Option1" then select all the other dropdowns and save. Then go back and switch the first dropdown to "Option2" and save you can see that only the very last array of objects is removed with the destroy strategy.
Am I doing something wrong or is this a bug in angular-schema-form? I looked under the issues that are currently open in the github project and I do not see an open issue about this.
You're correct, it's not currently behaving the way that you expect when an individual field is removed from the view because of a condition.
Here's what's happening: under the "old" bundled decorators for ASF, each field-type decorator is rendered on the page within an outer tag. The contents of the appropriate field template are then processed and rendered. Condition logic applies to everything within the tag, but not to the tag itself. Normally, this would be fine, but the destroyStrategy logic was assigned to the $destroy event of the tag. The end result is that the $destroy event will never fire unless the entire tag would be removed from the DOM. This is why the model values in the array of objects are being cleaned up - the container is removed when the "model.propertyOne === 'option1'" condition fails, which cascades the $destroy event to each object in the array.
I think that this got overlooked with the creation and release of the new builder, because I raised the issue at the end of the PR for the feature (https://github.com/Textalk/angular-schema-form/pull/371).
On the bright side, the new builder approach (which you can use by adding the bootstrap-decorator file from https://github.com/Textalk/angular-schema-form-bootstrap) doesn't have this issue. Instead, the destroyStrategy logic is applied via directive to the form fields because the tag is no longer used. Unless you have a need to stay with the old decorators at this time, I suggest grabbing the new ones and giving them a try.
Let us know how it goes!

Resources