1

I have a card with input choice set of options a,b,others

enter image description here

If users selects option as "others" then an extra input text block should come below the choice set. Is this possible with "Only show when" element property

enter image description here

Here is my Adaptive Card JSON

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.2",
  "body": [
    {
      "type": "Input.ChoiceSet",
      "choices": [
        {
          "title": "a",
          "value": "a"
        },
        {
          "title": "b",
          "value": "b"
        },
        {
          "title": "c",
          "value": "c"
        },
        {
          "title": "Others",
          "value": "Others"
        }
      ],
      "placeholder": "Select option"
    },
    {
      "type": "Input.Text",
      "placeholder": "Placeholder text",
      "isVisible": false
    },
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.Submit",
          "title": "Submit"
        }
      ]
    }
  ]
}

and i'm using html with webchat-es5 javascript library for rendering the bot to a page.

Kyle Delaney
  • 11,616
  • 6
  • 39
  • 66
User96
  • 53
  • 1
  • 8
  • I can see that you've used the web-chat tag but there's no mention of host/renderer in your question. Are you using Web Chat as your channel client? – Kyle Delaney Aug 13 '20 at 18:02
  • @Kyle Yes, I'm using web chat as channel client. – User96 Aug 14 '20 at 03:56
  • 1
    Sadly no, this is not possible today. The "Only show when" option is for specific data entries when using templating. You could say only show when creator = 'xxx' but can't reference other controls. Showing / Hiding elements based on a control state is not possible today but a highly requested feature that might be released quite soon. As you're using web chat you might be able to build that functionality yourself tho. – Tim Cadenbach Aug 14 '20 at 09:14
  • @User96 - I can show you how to do this based on [this answer](https://stackoverflow.com/a/61621137/2122672), but I need some more information from you. Please show us your Adaptive Card JSON and your Web Chat code. – Kyle Delaney Aug 15 '20 at 00:02
  • @Kyle - I have updated this question with my Adaptive card JSON. – User96 Aug 18 '20 at 11:29
  • @User96 - Is my answer acceptable? – Kyle Delaney Aug 19 '20 at 20:09

1 Answers1

4

All of the information you need in order to create a self-updating Adaptive Card in Web Chat using Adaptive Card extensibility can be found in this answer: BotFramework-WebChat - Adaptive Card

There are a few differences in your case that justify writing another answer:

  1. You're using the CDN instead of the NPM package
  2. You're using the ES5 bundle, which I'm assuming means you want this to work on IE11
  3. You're trying to toggle visibility instead of change text

Just like in the other case, we need to define a naming schema for ourselves that we can use to identify the card elements our code needs to manipulate. I'm only using one keyword this time: "on."

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.2",
  "body": [
    {
      "type": "Input.ChoiceSet",
      "choices": [
        {
          "title": "a",
          "value": "a"
        },
        {
          "title": "b",
          "value": "b"
        },
        {
          "title": "c",
          "value": "c"
        },
        {
          "title": "Others",
          "value": "Others"
        }
      ],
      "placeholder": "Select option",
      "id": "main"
    },
    {
      "type": "Input.Text",
      "placeholder": "Placeholder text",
      "isVisible": false,
      "id": "on_main_Others"
    },
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.Submit",
          "title": "Submit"
        }
      ]
    }
  ]
}

Consider the choice set input to be our switch and the text input to be our target. The choice set input's ID is just the name we've picked for it (and all inputs should have ID's in order for the card to work anyway even if we're not using our own naming schema). The text input's ID takes the form on_<input>_<value> where <input> is the ID of our switch and <value> is the choice that makes the target visible.

Here's the code you can use to make that work (notice that it accommodates IE11 by not using any arrow functions, etc.):

AdaptiveCards.AdaptiveCard.onParseElement = function (element) {
  const PREFIX_ON = 'on';
  const segments = element.id && element.id.split('_');

  if (segments && segments[0] == PREFIX_ON) {
    const card = element.getRootElement();
    const input = card.getElementById(segments[1]);
    const targetValue = segments[2];
    
    input.onValueChanged = function (sender) {
      // The isVisible setter automatically updates the rendered elements
      element.isVisible = (sender.value == targetValue);
    };
  }
};

Notice that we're accessing Adaptive Cards classes with an AdaptiveCards global variable. You may have guessed that this becomes available when you use the Adaptive Cards CDN. I need to warn you that unfortunately the latest version of the Adaptive Cards CDN is currently incompatible with the latest version of Web Chat. Adaptive Cards 2.x introduced breaking changes (which can be expected for a new major version), and Web Chat is currently using 1.2.6. To make sure your code works you should specify the version of the Adaptive Cards CDN in your HTML, and you might as well specify the version of Web Chat too in case newer versions of Web Chat come out later that break with Adaptive Cards 1.2.6.

<script crossorigin="anonymous" src="https://cdn.botframework.com/botframework-webchat/4.9.0/webchat-es5.js" ></script>
<script crossorigin="anonymous" src="https://unpkg.com/adaptivecards@1.2.6/dist/adaptivecards.js" ></script>

While it's unclear if you need to use the adaptiveCardsPackage property in Node, I'm pretty sure you do need to use it with the CDN:

WebChat.renderWebChat(
  {
    adaptiveCardsPackage: AdaptiveCards,
    directLine: window.WebChat.createDirectLine({
      secretOrToken: secretOrToken
    })
  },
  document.getElementById('webchat')
);

Self-updating Adaptive Card

Kyle Delaney
  • 11,616
  • 6
  • 39
  • 66
  • This is really helpful.. can we make javascript code dynamic. Like we can add placeholder for other choices.. Thanks – Sanjeev Gautam Aug 13 '21 at 11:35
  • Sure, do whatever you want – Kyle Delaney Aug 19 '21 at 16:21
  • I need to add a warning here because I've been running into unexpected problems. When you use the `onParseElement` event, it can be dangerous to refer to other elements inside the handler because you will only have access to the elements that have been parsed up to the point when the event fires. The elements are parsed one at a time so for an element in the middle, the handler will have access to the elements that were parsed before it but not after it. The sample code here only works because the "on_main_Others" element is parsed after the choice set and so the handler has access to it. – Kyle Delaney Sep 09 '22 at 09:35