0

I was checking out the customizing the cards, so i was thinking if i can use a submit button and every time i click the submit button. the integer value in the text box automatically increases without keep sending the new card every time Like a simple counter.

Like the counter in this link: https://studio.code.org/projects/applab/WH602L7gOqzNtImoHqBrBL00KU5h78yqnXQg-eG2LBg but in adaptive card in a webchat.

2 Answers2

1

As Mick mentioned there isn't a great way to do this other than updating the card after every button click; however, Web Chat does not currently support updating activities.

Even though you can't update the activity, you can use Web Chat's attachmentMiddleware and React to create a counter to wrap around incoming Adaptive Cards. It is difficult to capture the on submit action with this approach, but you can add your own custom buttons to the card or implement some logic on the bot side to send event activities to Web Chat with the updated count and update the card accordingly. I put together a quick sample following the first approach. For more details. I would recommend looking at the Customizing Card Attachments in Web Chat sample.

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>Web Chat: Custom attachment with GitHub Stargazers</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!--
      For simplicity and code clarity, we are using Babel and React from unpkg.com.
    -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="https://unpkg.com/react@16.8.0/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.8.0/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/glamor@2.20.40/umd/index.js"></script>
    <script src="https://unpkg.com/simple-update-in/dist/simple-update-in.production.min.js"></script>
    <!--
      This CDN points to the latest official release of Web Chat. If you need to test against Web Chat's latest bits, please refer to pointing to Web Chat's MyGet feed:
      https://github.com/microsoft/BotFramework-WebChat#how-to-test-with-web-chats-latest-bits
    -->
    <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
    <style>
      html, body { height: 100% }
      body { margin: 0 }
      #webchat {
        height: 100%;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="webchat" role="main"></div>
    <script type="text/babel">
      (async function () {
        'use strict';

        const { connectToWebChat, ReactWebChat } = window.WebChat;
        const { css } = window.Glamor;
        const { useState } = window.React;
        const { simpleUpdateIn } = window;
        const counterStyling = css({
          fontFamily: 'inherit',

          '& > .count': {
            fontSize: '1.3em',
            padding: '15px',
            textAlign: 'center'

          },
          '& > .buttons': {
            alignItems: 'stretch',
            display: 'flex',
            padding: '0 15px',

            '& > button': {
              flex: 1,
              color: '#0063B1',
              backgroundColor: 'white',
              borderStyle: 'solid',
              borderWidth: '1px',
              fontWeight: '600',
              padding: '10px'
            }, 
            '& > button + button': {
              marginLeft: '5px'
            }
          }
        });

        const attachmentMiddleware = () => next => card => {
          switch (card.attachment.contentType) {
            case 'application/vnd.microsoft.card.adaptive':
                const [count, setCount] = useState(0);

                const increase = () => setCount(count + 1);
                const decrease = () => count > 0 && setCount(count - 1);

                return (
                  <div className={counterStyling}>
                    <div className='count'>Count: <b>{count}</b></div>
                    <div className='ac-actionSet buttons'>
                      <button className={'ac-pushButton style-default'} type='button' onClick={ decrease }>Decrease</button>
                      <button className={'ac-pushButton style-default'} type='button' onClick={ increase }>Increase</button>
                    </div>
                    { next(card) }
                  </div>
                )

            default:
                return next(card);
          }
        };
        const store = createStore(
          {},
          ({ getState }) => next => action => {
            if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
              const { activities } = getState();
              const { from: { role: lastRole } = {}} = activities.filter(({ type }) => type === 'message')[activities.length - 1] || {}; 
              const { from: { role: incomingRole }} = action.payload.activity;
              action = simpleUpdateIn(action, ['payload', 'activity', 'channelData', 'showDisplayName'], () => incomingRole === 'bot' && lastRole !== 'bot')
            }
            return next(action)
          }
        );

        // In this demo, we are using Direct Line token from MockBot.
        // To talk to your bot, you should use the token exchanged using your Direct Line secret.
        // You should never put the Direct Line secret in the browser or client app.
        // https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
        const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
        const { token } = await res.json();
        window.ReactDOM.render(
          <ReactWebChat
            attachmentMiddleware={ attachmentMiddleware }
            store={store}
            directLine={ window.WebChat.createDirectLine({ token }) }
          />,
          document.getElementById('webchat')
        );
        document.querySelector('#webchat > *').focus();
      })().catch(err => console.error(err));
    </script>
  </body>
</html>

Screen Capture

enter image description here

Hope this helps.

tdurnford
  • 3,632
  • 2
  • 6
  • 15
0

The only way to achieve this is by updating the card, after every button click.. It is not possible for an Adaptive Card to update itself. You would have to listen for the button press event and update the card.

You should use updateActivity() to change the card content. Have a look at this related question, which has a very comprehensive answer.

Mick
  • 2,946
  • 14
  • 19