Open compulim opened 5 years ago
will it also include disabling cards and buttons in it after submitting? Cos now its not very obvios after button click that it was actually cliked and if clicked twice by default we have 2 events and messages dublicated. There's a backend workaround for that: https://stackoverflow.com/questions/51701003/microsoft-bot-framework-webchat-disable-adaptivecards-submit-buttons-of-previou , but it seems very hacky. Thanks
Is there any update on this? @compulim @Unders0n I am using adaptive cards inside waterfall dialog exactly like prompt choices, Once the button is clicked it has to be disabled or made obsolete. If there is an update please tell me how do I do it in node js, because the above C# solution is not working for me.
Any updated solution for disabling a adaptive card button totally once its clicked once ?
Any updates ?
The only way I found was to use a custom activityMiddleware where I draw my own message header and actions. As the web-chat component is written in React, I used class state to draw/not draw children (action buttons). This however leads to manual parsing of adaptive cards from card attachments coming into activity middleware.
Documentation: https://github.com/microsoft/BotFramework-WebChat#web-chat-api-reference
activityMiddleware | A chain of middleware, modeled after Redux middleware, that allows the developer to add new DOM components on the currently existing DOM of Activities. The middleware signature is the following: options => next => card => children => next(card)(children).
Hi, any updates on this feature. We have observed that users always try to scroll up to click on hero card buttons when the response is no longer expected. If would be great if hero card was disabled once it is not longer last activity element.
Hi @dkonyayev, we do not have updates at this time. Others who are looking for this feature are welcome to add their +1 to increase traction.
+1
+1
On Thu, 7 Nov 2019, 6:44 am ManjulaMalaiarasan, notifications@github.com wrote:
+1
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/microsoft/BotFramework-WebChat/issues/1427?email_source=notifications&email_token=ADJISRLIWOGTEOVRXJC74J3QSNTXZA5CNFSM4GH4SBP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDIRTMY#issuecomment-550574515, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADJISRJD4IR4UUDP7M5XIADQSNTXZANCNFSM4GH4SBPQ .
In our project this was a must have feature. We made a workaround with our Redux store to save last message id (activity.id).In a React component we would check if it is the last message so we do not show the action buttons and those cannot be pressed twice (e.g. authentication).
+1 any update on this yet?
+1
@avilde Can u please show a sample of how u checked if the activity.id is the last message received?
In my case, I will have to only enable the last adaptive card received and disable all the others so that the user can't click on a previously rendered adaptive card and disturb the flow.
Thanks in advance.
+1
+1
+1
+1
Will do it this week. 😉
Teaser...
There are still some kinks but reasonable okay as this will be a sample, not production code. I want to spend some more time think about this approach.
Kinks:
disabled
attribute on <audio>
/<video>
tag)action.isPrimary
to true
on submitOne primary goal in this sample, make sure keyboard focus is set correctly after buttons are disabled.
The sample code roughly looks like this and it requires the next version of Web Chat.
const attachmentMiddleware = () => next => ({ activity, attachment, ...others }) => {
const { activities } = store.getState();
const messageActivities = activities.filter(activity => activity.type === 'message');
const recentBotMessage = messageActivities.pop() === activity;
switch (attachment.contentType) {
case 'application/vnd.microsoft.card.adaptive':
return <AdaptiveCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.animation':
return <AnimationCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.audio':
return <AudioCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.hero':
return <HeroCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.oauth':
return <OAuthCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.receipt':
return <ReceiptCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.signin':
return <SignInCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.thumbnail':
return <ThumbnailCardContent content={attachment.content} disabled={!recentBotMessage} />;
case 'application/vnd.microsoft.card.video':
return <VideoCardContent content={attachment.content} disabled={!recentBotMessage} />;
default:
return next({ activity, attachment, ...others });
}
};
const cardActionMiddleware = () => next => ({ cardAction, target, ...others }) => {
target.isPrimary = true;
return next({ cardAction, target, ...others });
};
// let styleSet = createStyleSet({ hideSendBox: true });
let styleSet = createStyleSet();
styleSet = {
...styleSet,
adaptiveCardRenderer: {
...styleSet.adaptiveCardRenderer,
'& .ac-pushButton:disabled:not(.primary)': { backgroundColor: '#F7F7F7', color: '#717171' },
'& .ac-pushButton.primary:disabled': { backgroundColor: '#0078D7', color: 'White' }
}
};
window.ReactDOM.render(
<ReactWebChat
attachmentMiddleware={attachmentMiddleware}
cardActionMiddleware={cardActionMiddleware}
directLine={window.WebChat.createDirectLine({ token })}
store={store}
styleSet={styleSet}
/>,
document.getElementById('webchat')
);
Working on the tab order of "New message" button after the AC card is disabled. It's not trivial as we are not allowed to touch tabindex
. We can only influence by reordering DOM nodes.
tabindex
is global and introduce pollutions. tl;dr we are component, not app, so we don't own the global environment, we must not pollute it. One reason why components are much harder to write than apps.
p.s. love to see my customers are so excited when I am fixing bugs. The little 🚀 made my day.
Hi compulim,
thank you very much for your work. I have a question, is it possible to disable only some type of card action? For example, if I want to keep enabled OpenUrl action because it doesn't change the flow.
Thanks a lot, Andrea
@BeeMaia it will be quite difficult to do it today. Will you consider using Markdown to present an hyperlink to the user?
Are you rendering a hero card or Adaptive Cards?
I am still working on the tab order and completed the code to reorder DOM node. Scroll-to-bottom is difficult. 😑
Note: Instead of clicking on the "New messages" button, I press TAB to move the focus to the most recent card. So the scroll view move to the bottom.
The "New message" button didn't go away. I am working on this now. Chrome didn't fire scroll
event when a new element is added, and the scroll-to-bottom component didn't update its saved scrollHeight
value.
@BeeMaia it will be quite difficult to do it today. Will you consider using Markdown to present an hyperlink to the user?
Are you rendering a hero card or Adaptive Cards?
@compulim we are using hero card and adaptive cards.
Still working on focus management, understanding cross browser behavioral differences to see if this sample will work on daily UX.
In the animation below, we will focus on the element but not clicking on them. Yellow indicate what elements has the focus. And we want to see:
Looks like we should disable only the non-selected buttons, and leave the button clicked continue to be enabled and focusable.
Chrome did remember the focus on the disabled element. So TAB will go to the next focusable element after the disabled element.
Firefox did not remember the focus of the disabled element. TAB will go to the scroll view (i.e. the parent container of the disabled element).
Also note that Firefox can TAB to the scroll view if it does not have tabindex="-1"
. Scroll view in other browsers are not focusable.
Edge UWP is similar to Firefox, did not remember the focus of the disabled element. But TAB will go to first focusable element after document root.
Going to finish the day here. I think we go down the wrong path. In accessibility, disabled button should still be able to TAB to it, shouldn't lose focus.
I would also upvote for @BeeMaia's idea not to disable OpenURL buttons in the adaptive card.
Reopening this as we are still pending for README.md
for this (rushy) sample.
Thanks everyone for the input. @beemaia and @sw353552, could you open a new issue on "do not disable openUrl
buttons"? And could you share why "links in Markdown" is not sufficient replacement for openUrl
buttons? Would love to start a new user story based on your experience.
This sample is unexpectedly challenging because "making an accessible button which can be disabled dynamically" is a topic surprisingly no one visited. IMO, Firefox and Safari did the best job. For details, please read https://github.com/microsoft/BotFramework-WebChat/blob/master/docs/ACCESSIBILITY.md#additional-context. As always, accessibility is our top priority.
If you are interested in bringing this feature to production (i.e. without copying from the sample code), please create a new "feature enhancement" issue and vote. We need data from your feedback to plan our road map. 😉
To smooth out kinks in our UX, please also share reasons why you are not using Suggested Actions but Adaptive Cards for the user to answer questions.
Thanks for everyone's interested in this topic.
I understood and got the solution. But can you explain how to do disable previous/obsolte card using Angular9, I'm tring to achive the same thing with Angular9 but getting nowhere.
yes. Bot language does not affect the client behavior. Please use sample provided above.
Hi @compulim, We are referring above sample link to disable adaptive card. But we are getting disabled card for recent message. and hence not able to fill details. botframework version we are using : 4.11
Screenshot for reference:
I have tried providing disabled={recentBotMessage} in element but after doing that card is not getting disabled.
<Components.AdaptiveCardContent actionPerformedClassName="card__action--performed"
content={attachment.content}
disabled={recentBotMessage}
/>
is anyone facing similar issue? or can help with this.
@jayarau - In the sample, line 115 we have disabled={!recentBotMessage}
but in your example you don't have the (!) in front of recentMessage. Could you recheck?
Hi @Kaiqb, Yes we have tried with disabled={!recentBotMessage} initially, but with that we are getting disabled card even for recent message and hence not able to fill card and submit it. As shown in screenshot above.
Hi @compulim / @Kaiqb , do we have any update on this?
Hi @compulim , I see this issue is in dev discussions from long, do we have any update on it?
For everyone who is waiting for this, we will be in planning mode soon. We know this is what our customer want: using AC as an one-off input.
On the other hand, the root cause is in the AC library, https://github.com/microsoft/AdaptiveCards/issues/1512.
Will be great if everyone here could help sending feedbacks to the root cause to get it solved.
Hi @compulim, We are referring above sample link to disable adaptive card. But we are getting disabled card for recent message. and hence not able to fill details. botframework version we are using : 4.11
Screenshot for reference:
I have tried providing disabled={recentBotMessage} in element but after doing that card is not getting disabled.
<Components.AdaptiveCardContent actionPerformedClassName="card__action--performed" content={attachment.content} disabled={recentBotMessage} />
is anyone facing similar issue? or can help with this.
Update on this: I am able to disable adaptive cards once action taken. Solution: function check(act){return (act.type === 'message'&&act.hasOwnProperty('attachments'))}; var { activities } = this.store.getState(); var messageActivities=activities.filter(check) var recentBotMessage = messageActivities.pop() === activity;
return (
<Components.AdaptiveCardContent actionPerformedClassName="card__action--performed"
content={attachment.content}
disabled={!recentBotMessage}/>
);
+1. How could this be implemented via Bot framework composer?
+1. How could this be implemented via Bot framework composer?
Any updates about this?
Goals
Non-goals
It should not use jQuery or any other DOM-manipulating libraries to achieve the goal. It must use pure React.
Reference
We have a sample named "presentation mode". It showed the ability to disable interactivity of the whole Web Chat UI, including Adaptive Card content. The implementer can look into that to understand how to disable interactivity for just a specific attachment