I am currently learning about Adaptive cards for using it in Power Automate to send them to Microsoft teams.
As an exercise I needed to build this card: Candidate FeedBack form
I built the card in the Microsoft Adaptive card designer and I got this card payload:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "CANDIDATE FEEDBACK FORM"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "{CandidateUrl}",
"altText": "ProfilePicture",
"horizontalAlignment": "Left",
"style": "Person"
}
],
"horizontalAlignment": "Center",
"verticalContentAlignment": "Center"
},
{
"type": "Column",
"width": "auto",
"horizontalAlignment": "Center",
"verticalContentAlignment": "Center",
"style": "emphasis",
"items": [
{
"type": "TextBlock",
"text": "{Candidate Name}",
"wrap": true,
"color": "Dark"
}
]
}
]
},
{
"type": "Container",
"backgroundImage": {
"url": "https://www.solidbackgrounds.com/images/950x350/950x350-light-gray-solid-color-background.jpg"
},
"items": [
{
"type": "Input.Text",
"placeholder": "Input candidate comments",
"id": "CandidateComments",
"isMultiline": true,
"isRequired": true,
"label": "Comments",
"errorMessage": "You must set the candidate comments"
},
{
"type": "Input.ChoiceSet",
"choices": [
{
"title": "Hire",
"value": "Hire"
},
{
"title": "No Hire",
"value": "No Hire"
}
],
"placeholder": "Placeholder text",
"isRequired": true,
"style": "expanded",
"id": "Decision",
"label": "Decision",
"errorMessage": "You must select the decision"
},
{
"type": "Input.ChoiceSet",
"choices": [
{
"title": "Past experience in the topic area",
"value": "Experience"
},
{
"title": "Inclusive behaviors and work ethics",
"value": "Inclusivity"
},
{
"title": "Ability to work without supervision",
"value": "Independent"
}
],
"placeholder": "Placeholder text",
"isMultiSelect": true,
"style": "expanded",
"label": "Suggest follow-up discussion regarding:",
"id": "Suggestion"
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
]
}
The card is working ok but I got an idea and I have not been able to do it. The thing is that I would like that the Suggestion Choice element only appears if the user selects the "Hire" decision, because it does not have much sense to have a follow-up discussion with someone that you decided not to hire.
I noticed that the ChoiceSet has a property called "Only show when" but I only have been able to make it work using the sample data editor. For example when I add this data to the sample data editor:
{
"Test":"Testing"
}
And this expression in "Only show when": ${$root.Test == "Testing"}, It works but I don't need it to do it with sample data but when the id "Decision" is equal to "Hire". So that is the question, how can I achieve that the ChoiceSet is only shown when the id "Decision" is equal to "Hire".
PS: Other thing that I saw is that I can unmark the ChoiceSet as "Initially Visible" and there is an action "ToggleVisibility" which can make it visible, but I don't know how to trigger that action only when the Hire decision is chosen.
Thank you in advance!
You can't do it directly from the UI itself. You can update the card when user submits it, but right now there is no such action available that can execute some event on checkbox check and uncheck.
Related
I am trying to find a way to disable the Action.Submit action type and all inputs of adaptive cards that are not the most recent message in the conversation. I found this option of using the attachmentMiddleware of the BotFramework-Webchat used in React.
const attachmentMiddleware = () => next => ({ activity, attachment, ...others }) => {
if (attachment.contentType === "application/vnd.microsoft.card.custom") {
attachment.contentType = "application/vnd.microsoft.card.adaptive"
}
const { activities } = store.getState()
const messageActivities = activities.filter(
activity =>
activity.type === "message" &&
typeof activity.suggestedActions === "undefined" // to filter out suggested actions
)
const recentBotMessage = messageActivities.pop() === activity
const AdaptiveCardContent = Components.AdaptiveCardContent
switch (attachment.contentType) {
case "application/vnd.microsoft.card.adaptive":
return (
<AdaptiveCardContent
actionPerformedClassName="card__action--performed"
content={
attachment.content
}
disabled={!recentBotMessage}
/>
)
default:
return next({ activity, attachment, ...others })
}
}
This solution sets the disabled property in the AdaptiveCardContent Component for not recent messages by the bot and works really well except for Action.OpenUrl actions on containers.
Any Action.OpenUrl will have no functionality, but will look like it is still an enabled button. Example Screenshot:
As seen in the screenshot, the "primary" actions at the bottom of type Action.Submit are disabled correctly. Now the Action.ToggleVisibility ("Toggle", which changes the visibility of an text) and the Action.OpenUrl ("Open in new tab") are not disabled. The Action.ToggleVisibility ("Toggle") works as it did before, which is our intended behavior and fine. But the Action.OpenUrl which looks like it is still clickable, is in fact not.
I think it is because of the following line #107 and #108 in botframework-webchat\src\adaptiveCards\Attachment\AdaptiveCardRenderer.tsx:
// Only listen to event if it is not disabled and have "tapAction" prop.
const handleClickAndKeyPressForTapAction = !disabled && tapAction ? handleClickAndKeyPress : undefined;
But I do not understand why the Action.ToggleVisibility actions work just fine and the Action.OpenUrl actions, which html elements are not disabled and have no aria-disabled="true" properties, have no handling for clicking them.
I tried a completely different way of achieving this behavior by modifying the card, that is given to the AdaptiveCardContent, but this way leads to not wanted effects like loosing the inputted values of users after disabling the inputs, since it seems the usePersistValuesModEffect is overwritten or something, or like some unwanted effects from re-rendering the changed adaptive card.
Does anybody know if this is a bug or intended behavior of the disabled property and if so if there is a good working solution to disable inputs and only Action.Submit actions of adaptive cards?
EDIT:
This is the attachment.content value, meaning the adaptive card that is given to the <AdaptiveCardContent> component:
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.3",
"speak": "",
"body": [
{
"type": "Container",
"id": "content",
"items": [
{
"type": "TextBlock",
"weight": "bolder",
"text": "A title",
"wrap": true
},
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"id": "descriptionPreview",
"text": "Some Content",
"wrap": true
}
],
"spacing": "medium",
"separator": true
},
{
"type": "Container",
"items": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"id": "nonBlocking3",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"id": "toggleKCostDown",
"weight": "bolder",
"text": "Cost",
"wrap": true
},
{
"type": "TextBlock",
"id": "toggleCostUp",
"weight": "bolder",
"text": "Cost",
"wrap": true,
"isVisible": false
}
],
"verticalContentAlignment": "center"
}
],
"style": "accent",
"selectAction": {
"type": "Action.ToggleVisibility",
"targetElements": [
"toggleCostDown",
"toggleCostDownChevron",
"toggleCostUp",
"toggleCostUpChevron",
"contentCost"
]
},
"bleed": true
},
{
"type": "TextBlock",
"id": "contentCost",
"text": "Some info about costs.",
"wrap": true,
"isVisible": false
}
]
}
],
"bleed": true
},
{
"type": "Container",
"id": "nonBlocking4",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "50px",
"items": [
{
"type": "Column",
"width": "70",
"items": [
{
"type": "TextBlock",
"weight": "bolder",
"text": "Open in new tab",
"wrap": true
}
]
}
]
}
]
}
],
"style": "accent",
"selectAction": {
"type": "Action.OpenUrl",
"url": "https://google.com",
"title": "Open in new tab"
},
"spacing": "medium"
}
]
},
{
"type": "TextBlock",
"weight": "bolder",
"text": "Have you found what you are looking for?",
"wrap": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"data": "No",
"title": "No",
"style": "destructive"
}
]
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"data": "Yes",
"title": "Yes",
"style": "positive"
}
]
}
]
}
],
"spacing": "medium",
"separator": true
}
]
}
}
I'm relatively new to this so please bare with me. I'm creating adaptive cards in PowerAutomate to post in Teams. I was previously using the built-in card designer in PowerAutomate but that's been deprecated (and consequently added weeks to my implementation as I'm severely struggling with Designer).
I've created a card in Designer, added it to my flow, and made changes as needed. I now need to troubleshoot some issues so I want to load it back into Designer. When I paste my payload back into the designer to refine it (the bottom left section), the app elements (main window) are not not always refreshing. Sometimes it does, sometimes it doesn't.
I could be doing something totally incorrect but what I'm doing has been working with moderate success up until recently where it works totally randomly.
Below is the code I'm trying to populate into designer. I usually find success when I paste this into the default template leaving the Sample Data as is. At the moment, nothing is happening when I do so.
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.3",
"body": [
{
"type": "TextBlock",
"size": "ExtraLarge",
"text": "Miami Warehouse",
"color": "Accent",
"isSubtle": true,
"weight": "Bolder"
},
{
"type": "TextBlock",
"text": "The packing slip for PO: #{outputs('Get_item')?['body/PO']} has been reviewed and processed. ",
"wrap": true,
"color": "Default"
},
{
"type": "TextBlock",
"text": "Let us know when you've inventoried the shipment.",
"wrap": true,
"color": "Attention",
"size": "Large",
"weight": "Bolder"
},
{
"type": "TextBlock",
"text": "Please update the package information below.",
"wrap": true
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.OpenUrl",
"title": "#{outputs('Get_item')?['body/Name']}",
"url": "#{outputs('Get_item')?['body/Link']}",
"id": "linktofile"
}
],
"id": "file"
},
{
"placeholder": "File Name",
"type": "Input.Text",
"id": "filename",
"spacing": "Medium",
"label": "File Name:",
"value": "#{outputs('Get_item')?['body/Name']}"
},
{
"type": "Input.Text",
"placeholder": "PO Number",
"id": "po",
"spacing": "Medium",
"label": "PO Number:",
"value": "#{outputs('Get_item')?['body/PO']}"
},
{
"type": "Input.Text",
"placeholder": "Client Name",
"id": "client",
"spacing": "Medium",
"label": "Client:",
"value": "#{outputs('Get_item')?['body/Client']}"
},
{
"type": "Input.Text",
"placeholder": "Project Name",
"id": "project",
"spacing": "Medium",
"label": "Project Name:",
"value": "#{outputs('Get_item')?['body/Project']}"
},
{
"type": "Input.ChoiceSet",
"choices": #{body('Select')},
"id": "projectmanager",
"value": "#{outputs('Get_item')?['body/Project_x0020_Manager']}",
"label": "Project Manager"
},
{
"type": "ColumnSet",
"columns": [
{
"width": "stretch",
"type": "Column",
"items": [
{
"type": "Input.Text",
"spacing": "None",
"placeholder": "Optional",
"id": "trackingnumber",
"label": "Tracking Number:",
"value": "#{outputs('Get_item')?['body/Tracking_x0020_Number']}"
}
]
},
{
"width": "stretch",
"type": "Column",
"items": [
{
"placeholder": "Optional",
"type": "Input.Text",
"spacing": "Medium",
"id": "carrier",
"label": "Carrier:",
"value": "#{outputs('Get_item')?['body/Carrier']}"
}
]
}
]
},
{
"type": "Input.Text",
"isMultiline": true,
"id": "notes",
"spacing": "Medium",
"label": "Description:",
"placeholder": "",
"value": ""
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "SHIPMENT INVENTORIED",
"id": "inventoried"
}
]
}
]
}
This is probably due to JSON that you have provided is not valid
As you can see here it is showing error at Input.ChoiceSet if I make #{body('Select'} as string i.e. "#{body('Select'}" it doesn't give any error and I can see the preview of it.
This error you will get in Adaptive Card designer itself if you look closely, also there are multiple JSON validator available on web. Such as https://jsonlint.com/
I have an Adaptive card the code is below. The problem I am facing is The card that will be displayed after clicking the Action.ShowCard button can not render Image. It says undefined. The same image gets displayed when I use it in a normal card. I think it cannot render the image that is in the card of the button. To test it you can copy the code in your App Studio's UI Tool and click Send me this card
Screen shot of what I get
Main code
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.2",
"body": [
],
"actions":[
{
"type": "Action.ShowCard",
"title": "Action.ShowCard",
"card": {
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.2",
"msteams": {
"entities": []
},
"body": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png",
"size": "Small"
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Color theorysdjkf",
"wrap": true,
"weight": "Bolder",
"color": "Attention"
}
],
"verticalContentAlignment": "Center"
}
],
"height": "stretch",
"horizontalAlignment": "Center",
"separator": true,
"spacing": "Large"
},
{
"type": "TextBlock",
"wrap": true,
"spacing": "Small",
"text": "You selected **A**"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "This is a long explanation for the answer and I think it is getting so long and long and long long long long "
}
]
}
],
"style": "emphasis",
"spacing": "Small"
}
]
},
"style": "positive"
}
]
}
Looks like it is a platform issue.
We have raised a bug for it.
We will let you know once it is resolved.
Thanks!!
I tried base64 encoding the image (and tried a very small minified version - 23k), but that also failed. It looks like a bug to me. There are several Microsoft people here on Stack Overflow so they'll pick this up and feed it back if they can repro it (which they should have no trouble doing).
I am using microsoft bot framework. I need to implement a star rated feedback mechanism in my code. Like selecting the star should submit the rating for the bot. Can anyone help me on this? or any suggestions ?
You can create a star rating feedback card with an AdaptiveCard by making columns behave like submit buttons. To begin, add a column set to an AdaptiveCard with the desired number of columns - each column will correspond to a rating. Then in each column, you can add an image of a star or some other object and a text field describing that rating. Next, add a submit action to each column and in the data field add the value of the response. Finally, you can render the card and send it to the user as an attachment. When the user clicks on a column, it will send the value from the data field as a message from the user. See the AdaptiveCard JSON and screenshot of the rendered card below for an example.
Screenshot
JSON AdaptiveCard
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"color": "Accent",
"text": "Rate your experience!"
},
{
"type": "TextBlock",
"separator": true,
"text": "Please rate your experience! Your feedback is very appreciated and will help improve your experience in the future. ",
"wrap": true
},
{
"type": "ColumnSet",
"spacing": "Medium",
"columns": [
{
"type": "Column",
"selectAction": {
"type": "Action.Submit",
"data": "awful"
},
"items": [
{
"type": "Image",
"horizontalAlignment": "Center",
"url": "https://upload.wikimedia.org/wikipedia/commons/1/18/Five-pointed_star.svg"
},
{
"type": "TextBlock",
"horizontalAlignment": "Center",
"text": "Awful"
}
],
"width": "stretch"
},
{
"type": "Column",
"selectAction": {
"type": "Action.Submit",
"data": "bad"
},
"items": [
{
"type": "Image",
"horizontalAlignment": "Center",
"url": "https://upload.wikimedia.org/wikipedia/commons/1/18/Five-pointed_star.svg"
},
{
"type": "TextBlock",
"horizontalAlignment": "Center",
"text": "Bad"
}
],
"width": "stretch"
},
{
"type": "Column",
"selectAction": {
"type": "Action.Submit",
"data": "ok"
},
"items": [
{
"type": "Image",
"horizontalAlignment": "Center",
"url": "https://upload.wikimedia.org/wikipedia/commons/1/18/Five-pointed_star.svg"
},
{
"type": "TextBlock",
"horizontalAlignment": "Center",
"text": "Ok"
}
],
"width": "stretch"
},
{
"type": "Column",
"selectAction": {
"type": "Action.Submit",
"data": "good"
},
"items": [
{
"type": "Image",
"horizontalAlignment": "Center",
"url": "https://upload.wikimedia.org/wikipedia/commons/1/18/Five-pointed_star.svg"
},
{
"type": "TextBlock",
"horizontalAlignment": "Center",
"text": "Good"
}
],
"width": "stretch"
},
{
"type": "Column",
"selectAction": {
"type": "Action.Submit",
"data": "terrific"
},
"items": [
{
"type": "Image",
"horizontalAlignment": "Center",
"url": "https://upload.wikimedia.org/wikipedia/commons/1/18/Five-pointed_star.svg"
},
{
"type": "TextBlock",
"horizontalAlignment": "Center",
"text": "Terrific"
}
],
"width": "stretch"
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
Does anyone know what is a proper value to set for column size for adaptive card ?
Schema (http://adaptivecards.io/explorer/#Column) says
"auto", "stretch", or a number representing relative width of the
column in the column Set (Default:Auto)
but actually I've tried number, percentage, px, pt but none is working.
Thanks
If you have a look to this sample: http://adaptivecards.io/visualizer/?card=/samples/cards/Input%20Form.json
You will see that the format is a basic number:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "0.5",
"body": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"size": 2,
"items": [
{
"type": "TextBlock",
"text": "Tell us about yourself...",
"weight": "bolder",
"size": "large"
},
{
"type": "TextBlock",
"text": "We just need a few more details to get you booked for the trip of a lifetime!",
"isSubtle": true,
"wrap": true
},
{
"type": "TextBlock",
"text": "Don't worry, we'll never share or sell your information.",
"isSubtle": true,
"wrap": true,
"size": "small"
},
{
"type": "TextBlock",
"text": "Your name",
"wrap": true
},
{
"type": "Input.Text",
"id": "myName",
"placeholder": "Last, First"
},
{
"type": "TextBlock",
"text": "Your email",
"wrap": true
},
{
"type": "Input.Text",
"id": "myEmail",
"placeholder": "youremail#example.com",
"style": "email"
},
{
"type": "TextBlock",
"text": "Phone Number"
},
{
"type": "Input.Text",
"id": "myTel",
"placeholder": "xxx.xxx.xxxx",
"style": "tel"
}
]
},
{
"type": "Column",
"size": 1,
"items": [
{
"type": "Image",
"url": "https://upload.wikimedia.org/wikipedia/commons/b/b2/Diver_Silhouette%2C_Great_Barrier_Reef.jpg",
"size": "auto"
}
]
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
]
}
It's working a bit like bootstrap; here your first column will get 2/3 = 2/(2+1) of the total width, and the second one 1 third (1/(2+1)).
You can manipulate the values in the provided tester