自适应卡在提交时清除输入

时间:2019-09-10 11:40:46

标签: javascript node.js botframework microsoft-teams adaptive-cards

我从Microsoft Teams机器人发送了一个Adaptive Card,其中包含输入字段和一个Submit操作。当用户单击Submit时,我收到了输入的数据,但表单字段已清除。

这是为什么?我究竟做错了什么?这种行为非常令人讨厌,因为我无法验证输入并要求用户进行更正。

这发生在桌面上的Teams应用程序,浏览器中的Teams,网页中的Teams网络聊天以及Bot仿真器中。在仿真器中,该字段足以释放焦点。

如果有问题,我可以使用nodejs。

2 个答案:

答案 0 :(得分:2)

您没有做错任何事情。这就是自适应卡在团队中的工作方式,也许是表示数据已成功发送到机器人的一种方式。不过,您可能可以采取一些措施来解决问题。

自适应卡输入字段具有value属性,可让您指定字段的初始值。如果您将卡片发送给用户,并且输入字段的value属性已填充,则这些字段不会为空。这意味着您可以发送卡片作为更新而不是新活动,并且看起来该卡片已被修改,因为Teams支持更新活动。如果更新使用的是同一张卡,但用户输入的值相同,则该卡看起来将保持不变,这将解决您的值消失的问题。

有一个关于将输入字段动态添加到自适应卡的问题,answer包含保留输入字段值的示例代码:

var inputId = `text${i}`;
body.push({
    type: "Input.Text",
    id: inputId,
    value: cardData[inputId] // This is where the value is preserved
});

如果您希望通过可安装在NuGet软件包中的预构建代码简化整个过程,请在GitHub上表达对这些想法的支持:
Bot.Builder.Community.AdaptiveCards
AdaptiveCard Prompt

答案 1 :(得分:0)

我在等待问题的答案时,我得出的结论与上述凯尔·德莱尼(Kyle Delaney)大致相同,但您必须重新发送输入的数据。

因此,我开始摆弄代码,并提出了此解决方案,但不确定这是最好的方法。

作为瀑布步骤的一部分:

   async W2_showCard(step) {
        const card = CardFactory.adaptiveCard(this.makeFormCard());
        return await step.prompt('formPrompt', { prompt: MessageFactory.attachment(card) });
    }

诀窍在formPrompt中,这还可以确保用户提交表单而不是做其他事情。

       // 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;

        }));