I am trying to create an adaptive card with a fact set. However, I can't seem to get the actual facts to display. Even the example at https://adaptivecards.io/designer/ is not working. Instead of pulling in the data from the properties element as specified, it just shows ${key} and ${value} as the pair. You can see the output and the full JSON at the link above, but here are the relevant sections for my issue/query:
Adaptive card specification
{
"type": "FactSet",
"facts": [
{
"$data": "${properties}",
"title": "${key}:",
"value": "${value}"
}
]
}
Data object
"properties": [
{
"key": "Board",
"value": "Adaptive Cards"
},
{
"key": "List",
"value": "Backlog"
},
{
"key": "Assigned to",
"value": "Matt Hidinger"
},
{
"key": "Due date",
"value": "Not set"
}
]
As this or similar questions came up multiple times recently. You have to make sure to use the "Preview" button
Elements bound to any array in JSON are not rendered during design time or only when the specific array element is referenced with array[x].xx. Dynamically generated elements currently are only rendered in preview mode when working in the web editor version https://adaptivecards.io/designer
If you need a design time experience for array bound elements you can use Adaptive Cards Studio the Visual Studio Code Extension for card authoring.
Related
I want to know how to use NSGI-LD to upload an image even though these static files are not stored in Orion Context Broker or Mongo. I want to know if there is a way to configure the NSGI-LD to forward the images to AWS S3 Buck or another location?
As you correctly identified, binary files are not a good candidate for context data, and should not be held directly within a context broker. The usual paradigm would be as follows:
Imagine you have a number plate reader library linked to Kurento and wish to store the images of vehicles as they pass. In this case the event from the media stream should cause two separate actions:
Upload the raw image to a storage server
Upsert the context data to the context broker including an attribute holding the URI of the stored image.
Doing things this way means you can confirm that the image is safely stored, and then send the following:
{
"vehicle_registration_number": {
"type": "Property",
"value": "X123RPD"
},
"image_download": {
"type": "Property",
"value": "http://example.com/url/to/image"
}
}
The alternative would be to simply include some link back to the source file somehow as metadata:
{
"vehicle_registration_number": {
"type": "Property",
"value": "X123RPD",
"origin": {
"type": "Property",
"value": "file://localimage"
}
}
}
Then if you have a registration on vehicle_registration_number which somehow links back to the server with the original file, it could upload the image after the context broker has been updated (and then do another upsert)
Option one is simpler. Option two would make more sense if the registration is narrower. For example, only upload images of VRNs for cars whose speed attribute is greater than 70 km/h.
Ontologically you could say that Device has a relationship to a Photograph which would mean that Device could have an additional latestRecord attribute:
{
"latestRecord": {
"type": "Relationship",
"object": "urn:ngsi-ld:CatalogueRecordDCAT-AP:0001"
},
}
And and create a separate entity holding the details of the Photograph itself using a standard data model such as CatalogueRecordDCAT-AP which is defined here. Attributes such as source and sourceMetadata help define the location of the raw file.
{
"id": "urn:ngsi-ld:CatalogueRecordDCAT-AP:0001",
"type": "CatalogueRecordDCAT-AP",
"dateCreated": "2020-11-02T21:25:54Z",
"dateModified": "2021-07-02T18:37:55Z",
"description": "Speeding Ticket",
"dataProvider": "European open data portal",
"location": {
"type": "Point",
"coordinates": [
36.633152,
-85.183315
]
},
"address": {
"streetAddress": "2, rue Mercier",
"addressLocality": "Luxembourg",
"addressRegion": "Luxembourg",
"addressCountry": "Luxembourg",
"postalCode": "2985",
"postOfficeBoxNumber": ""
},
"areaServed": "European Union and beyond",
"primaryTopic": "Public administration",
"modificationDate": "2021-07-02T18:37:55Z",
"applicationProfile": "DCAT Application profile for data portals in Europe",
"changeType": "First version",
"source": "http://example.com/url/to/image"
"sourceMetadata": {"type" :"jpeg", "height" : 100, "width": 100},
"#context": [
"https://smartdatamodels.org/context.jsonld"
]
}
I have an adaptive card in the form of a JSON file, which contains an Input.ChoiceSet. This is provided with a data payload, which is dynamic and so it is not the same amount of data every time. I want to be able to drop this Input.ChoiceSet if it breaks a certain threshold based on the length of the array of data that I'm going to pass to it. Is it possible to write this as an condition inside the Input.ChoiceSet using %when to carry this out?
This is currently what I have, but it is not working as I would've hoped:
{
"type": "Input.ChoiceSet",
"id": "CompactSelectVal1",
"$when": "${$data.length < 400}",
"placeholder": "Select a value",
"choices": [
{
"$data": "${data}",
"title": "${name}",
"value": "${tag}"
}
],
"label": "Input"
}
Using .length here was just a guess here, not based on any documentation. The documentation I have used to find out about $when is the following https://learn.microsoft.com/en-us/adaptive-cards/templating/language.
Any help on this would be much appreciated.
You can use "count" property instead of "length" and also remove the extra '$' inside the curly bracket "${$data.length < 400}".
Try this:
{
"type": "Input.ChoiceSet",
"id": "CompactSelectVal1",
"$when": "${count(data) < 400}",
"placeholder": "Select a value",
"choices": [
{
"$data": "${data}",
"title": "${name}",
"value": "${tag}"
}
],
"label": "Input"
}
If the condition is true then the choice button will hide from the adaptive card.
I am trying to show TextBlock elements on my adaptive card depending in the value selected in a ChoiceSet (radio buttons). And I am not getting it to work properly.
The ChoiceSet does not have an ActionSet integrated, so I cannot call a ToggleVisibility action on selection. Then I tried to use the selectAction Property, but neither the Input.ChoiceSet nor Input.Choice support this property.
The last approach was to use the "$when" property on the element I want to toggle and bind it to the value of the ChoiceSet. Depending on which value it has, the element should be shown or hidden. But I do not get it to work, I tried
"$when": "{damagepart=2}" but it seems that only works with some kind of data binding?!
I am not able to find a proper example of that in the decumentation or in the samples of adaptivecards.io...
Does anyone have an example or some hints on how to get this task solved?
While this can theoretically be done in Web Chat using the extensibility features of Adaptive Cards, you may also not that this feature is in the Adaptive Cards roadmap: https://portal.productboard.com/adaptivecards/1-adaptive-cards-features/c/25-client-side-update-card-upon-input-changes-or-button-presses
I made this example that might be useful for you.
The column section that contain a text box and a action hyperlink will hide and show depending on the condition or the value of the variable.
card payload editor
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "This line will visible when the condition meet:",
"wrap": true
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.OpenUrl",
"title": "Any button you want to show"
}
]
}
]
}
],
"$when": "${$root.MatchVariableValue == \"yes\"}"
}
]
}
use the following sample on Data editor to see how the section appear and hide depending on your input/value.
{"MatchVariableValue":"yes"}
or use
"$when": "${$root.MatchVariableValue}"
if your data is as simple as
{"MatchVariableValue":true}
I have the following simple card:
{
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "{data}"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
When I apply the following data to the card (value is number), the text box is empty:
{
"data":11111
}
With text, the I can see the data in the card:
{
"data":"11111"
}
This is not a code issue, this is how it looks in the designer. Am I missing something, is there a type for a text box that lets display numbers or is this by design and I have to change all numeric fields to text?
This is a limitation of the preview (known as Type Coercion) that we hope to address before release. As another workaround you can include a space after the binding expression which will force it into a string. See the below example, notice the space after {data}
{
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "{data} "
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
I'm guessing you're using Adaptive Cards Templating for this. Remember, this is (a) in preview only and (b) just one option for constructing an Adaptive Card. Basically, at the end of the day, the Card is just a string of JSON text so you can create it in 3 main ways:
Using Templates, as you're doing now
Doing string replacement of your own (e.g. var card = '..."text": "##Number##"...' and then card = card.Replace("##Number##", formattedNumberValue)
Using strongly-typed options like the AdaptiveCards Nuget package for C#, for instance
So, I'd suggest, if this is not possible using Templating, to look more at options 2 or 3 above. I described this a bit more here, with some links to C# and Node examples.
Hope that helps
You can now use the function formatNumber(value, decimalplaces)
Eg:
{
"type": "TextBlock",
"text": "${formatNumber(somenumber), 2}"
}
You can read mode here:
https://learn.microsoft.com/en-us/azure/bot-service/adaptive-expressions/adaptive-expressions-prebuilt-functions?view=azure-bot-service-4.0#formatNumber
I have to build an Angular application that has a single task: It receives JSON data that describe a form structure, e.g.:
{
"textbox": {
"type": "string",
"name": "name",
"maxlength": 30,
"description": "Full Name"
},
"textbox": {
"type": "string",
"name": "email",
"maxlength": 40,
"description": "Email"
},
"date": {
"name": "birthdate",
"description": "Birthdate"
},
"checkbox": {
"name": "subscribe",
"options": [
"Yes",
"No"
],
"default": "No",
"description": "Subscribe?"
},
"button": {
"type": "submit",
"description": "Send"
}
}
And it should display it: (All forms are different with varying elements.)
I'm relatively new to Angular and my initial approach would be to create a simple template that has an ngFor in it, and inside many ngIfs (one for text fileds, one for text area, another for radio button, and so on...) that examine for the "type" of the given form element, and if there is a match, it gets displayed with its attributes written in the JSON.
Is it a good idea to start like this, or should I first learn some more Angular to be able to come up with a more professional solution?
Are things like dynamic and reactive forms in Angular for this purpose, or which part of Angular should I have a deeper understanding in for this task?