Display number in adaptive card - adaptive-cards

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

Related

How to use $when in an adaptive card template to find out the length of an incoming data payload and drop an input block

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.

Unable to get data to show in Adaptive Card FactSet

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.

Adaptive Cards: Visibility of element depending on value of a ChoiceSet

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}

Predefined Resource Group in ARM Template

I'm working on a custom arm template.
I would like to have specific resource group to be hard coded inside the JSON so
when opening the template it will simulate "Resource Group: Use existing: predefined selected Resource group"
I've been scratching my head for hours and searched the web deeply, I also tried to export existing resource group template and import it to custom deployment but it still shows
Resource Group *Create New *Use Existing
Is there any way to define existing RG inside the JSON template?
You can use nested templates, like #4c74356b41 said, but you will still see the ugly "Select a resource group" field at the portal.
I have a similar problem (even if #4c74356b41 repeatedly claims that it doesn't make any sense). I want to generate the resource group name from a parameter.
You can find more about how to use nested templates here: Create resource group and deploy resources
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"someName": {
"type": "string"
}
},
"variables": {
"rgName": "[concat('rg-', parameters('someName'))]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('rgLocation')]",
"name": "[variables('rgName')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "rgDeployment",
"resourceGroup": "[variables('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', variables('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
// PUT YOUR RESOURCES TEMPLATES HERE! //
}
],
"outputs": {}
}
}
}
],
"outputs": {}
}
Just replace the rgName variable with the name of your actual resource group name.
there are several ways to achieve this (not that it makes sense, but you can do this).
Use automation around the template to always deploy it to the same rg. this makes most sense as your template stays flexible
wrap your template with a parent template (so "convert" your template to a nested template). that way the parent template can control to which resource group your nested template gets deployed (look for cross resource group ARM Template deployments).
Make your template a nested inline template (worst case). this is pretty much the same as point 2, but kinda worse, because nested inline templates have this peculiar drawback of not being able to use their own parameters\variables, only the ones defined in the parent.
Again, none of this makes sense as you should just deploy it to the proper subscription\resource group combination. but there you have it, if you insist.
But the portal experience will stay the same (there is no way of working around that, you can forcé the template to always deploy to the same resource group (not that it makes any sense), but not alter the portal experience), if thats what you are concerned about.

Elasticsearch mapping of nested structure

I'm looking for some pointers on mapping a somewhat dynamic structure for consumption by Elasticsearch.
The raw structure itself is json, but the problem is that a portion of the structure contains a variable, rather than the outer elements of the structure being static.
To provide a somewhat redacted example, my json looks like this:
"stat": {
"state": "valid",
"duration": 5,
},
"12345-abc": {
"content_length": 5,
"version": 2
}
"54321-xyz": {
"content_length": 2,
"version", 1
}
The first block is easy; Elasticsearch does a great job of mapping the "stat" portion of the structure, and if I were to dump a lot of that data into an index it would work as expected. The problem is that the next 2 blocks are essentially the same thing, but the raw json is formatted in such a way that a unique element has crept into the structure, and Elasticsearch wants to map that by default, generating a map that looks like this:
"stat": {
"properties": {
"state": {
"type": "string"
},
"duration": {
"type": "double"
}
}
},
"12345-abc": {
"properties": {
"content_length": {
"type": "double"
},
"version": {
"type": "double"
}
}
},
"54321-xyz": {
"properties": {
"content_length": {
"type": "double"
},
"version": {
"type": "double"
}
}
}
I'd like the ability to index all of the "content_length" data, but it's getting separated, and with some of the variable names being used, when I drop the data into Kibana I wind up with really long fieldnames that become next to useless.
Is it possible to provide a generic tag to the structure? Or is this more trivially addressed at the json generation phase, with our developers hard coding a generic structure name and adding an identifier field name.
Any insight / help greatly appreciated.
Thanks!
If those keys like 12345-abc are generated and possibly infinite values, it will get hard (if not impossible) to do some useful queries or aggregations. It's not really clear which exact use case you have for analyzing your data, but you should probably have a look at nested objects (https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html) and generate your input json accordingly to what you want to query for. It seems that you will have better aggregation results if you put these additional objects into an array with a special field containing what is currently your key.
{
"stat": ...,
"things": [
{
"thingkey": "12345-abc",
"content_length": 5,
"version": 2
},
...
]
}