Reputation: 1140
From a Microsoft Teams bot I send an Adaptive Card
with input fields and a Submit
action. When the user clicks Submit
I receive the data entered but the form fields are cleared.
Why is this? What am I doing wrong? This behavior is extremely annoying as I can't verify the input and ask the user to correct it.
This happens in the desktop Teams app, Teams in a browser, Teams webchat in a web page and the Bot Emulator. In the Emulator it suffices for the field to loose focus.
In case it matters I use nodejs.
Upvotes: 2
Views: 2343
Reputation: 1140
While I was waiting for an answer to my question I came pretty much to the same conclusion as Kyle Delaney outlined above, you have to resend the data entered.
So I started to fiddle with my code and came up with this solution, not sure this is the best way.
As part of a waterfall step:
async W2_showCard(step) {
const card = CardFactory.adaptiveCard(this.makeFormCard());
return await step.prompt('formPrompt', { prompt: MessageFactory.attachment(card) });
}
The trick is in formPrompt
which also ensures the user submits the form instead of doing something else.
// Workaround to make user click Submit or cancel dialog
this.dialogs.add(new ActivityPrompt('formPrompt', async prompt => {
const recognizedValue = prompt.recognized.value;
if (recognizedValue.type === ActivityTypes.Message) {
if (recognizedValue.value) {
const replyToId = recognizedValue.replyToId;
var oldCard = prompt.options.prompt.attachments[0];
var validated = true;
oldCard.content.body.forEach((item, i, body) => {
if (item.type === "Input.Text" || item.type === "Input.ChoiceSet") {
// preserve the user input
const newValue = recognizedValue.value[item.id];
item.value = newValue;
// some rudimentary input validation:
// assumes there is a corresponding text field just
// prior to the input field (input fields
// can't change their color)
if (newValue == '') {
body[i - 1].color = 'Attention';
body[i - 1].weight = 'Bolder';
validated = false;
} else {
delete body[i - 1].color;
delete body[i - 1].weight;
}
}
});
if( validated ) {
// remove the submit and cancel actions (not required, debatable)
delete oldCard.content.actions;
}
// update the card
const activity = prompt.context.activity;
activity.attachments = [oldCard];
activity.id = replyToId;
await prompt.context.updateActivity(activity);
if (validated) {
// this is to make input available in next waterfall step
prompt.recognized.value = recognizedValue.value;
return true;
} else {
await prompt.context.sendActivity(`Please check the form. Some values are missing`);
}
} else {
await prompt.context.sendActivity(`Please fill out form and press *"submit"* button or type *"cancel"* to stop.`);
}
}
return false;
}));
Upvotes: 1
Reputation: 12264
You're not doing anything wrong. That's just how Adaptive Cards work in Teams, perhaps as a way to signify that the data has been sent to the bot successfully. There may be something you can do to fix your problem though.
Adaptive Card input fields have a value
property that allows you to specify the field's initial value. If you send a card to the user and the input fields' value
properties are populated, the fields won't be empty. This means you can send such a card as an update instead of a new activity and it will look like the card has been modified in place, since Teams supports updating activities. If the update uses the same card but with the values the user entered then it will look like the card remains unchanged, which would fix your problem of the values disappearing.
There was a question about dynamically adding input fields to Adaptive Cards, and the answer contains sample code that preserves input field values:
var inputId = `text${i}`; body.push({ type: "Input.Text", id: inputId, value: cardData[inputId] // This is where the value is preserved });
If you want this whole process to be made easier with prebuilt code that you can install in NuGet packages, feel free to voice your support for these ideas on GitHub:
Bot.Builder.Community.AdaptiveCards
AdaptiveCard Prompt
Upvotes: 3