我们可以动态添加文本字段吗 [英] Can we add text field dynamically

查看:51
本文介绍了我们可以动态添加文本字段吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的聊天机器人中创建了一个自适应卡(使用json),该卡可以接收用户的输入.我想添加一个按钮,使用户每次单击插入字段时都可以添加一个新的文本字段. (即用户可以点击插入"按钮以输入受教育程度(学校,大学等)的详细信息)

I've created an adaptive card(using json) in my chatbot that takes input from users. I want to add a button that enables the user to add a new text field every time the user clicks on the insert field. (i.e., the user can click on insert button to enter details of education (school, college etc.))

这可以在自适应卡中实现吗?

Can this be achieved in adaptive cards?

我还想知道,自适应卡可以用任何其他语言(不包括json)进行设计吗?

I also wanted to know, can adaptive cards be designed in any other language (excluding json)

推荐答案

最简单的方法是使用Action.ShowCard:

{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "Input.Text",
      "placeholder": "Placeholder 1",
      "id": "text1"
    }
  ],
  "actions": [
    {
      "type": "Action.ShowCard",
      "title": "Add field",
      "card": {
        "type": "AdaptiveCard",
        "body": [
          {
            "type": "Input.Text",
            "placeholder": "Placeholder 2",
            "id": "text2"
          }
        ],
        "actions": [
          {
            "type": "Action.ShowCard",
            "title": "Add field",
            "card": {
              "type": "AdaptiveCard",
              "body": [
                {
                  "type": "Input.Text",
                  "placeholder": "Placeholder 3",
                  "id": "text3"
                }
              ],
              "actions": [
                {
                  "type": "Action.ShowCard",
                  "title": "Add field",
                  "card": {
                    "type": "AdaptiveCard",
                    "body": [
                      {
                        "type": "Input.Text",
                        "placeholder": "Placeholder 4",
                        "id": "text4"
                      }
                    ],
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
                  }
                }
              ],
              "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
            }
          }
        ],
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
      }
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.0"
}

您可能不喜欢这种外观,但是有另一种选择. Microsoft Teams允许您更新消息,因此您可以使用更多输入字段来更新卡,以响应提交操作.首先,您需要一种保存卡状态的方法,以便您可以更新卡的活动.在C#中,您可以像这样声明状态属性访问器:

You may not like the way that looks, but there is an alternative. Microsoft Teams allows you to update messages, so you can update the card with more input fields in response to a submit action. First, you'll need a way of saving state for your card so you can update the card's activity. In C# you can declare a state property accessor like this:

public IStatePropertyAccessor<Dictionary<string, (string ActivityId, int InputCount)>> InputCardStateAccessor { get; internal set; }

然后您可以像这样实例化它:

Then you can instantiate it like this:

InputCardStateAccessor = _conversationState.CreateProperty<Dictionary<string, (string, int)>>("cardState");

在Node.js中,您不需要声明任何内容,但是可以像这样实例化它:

In Node.js you won't need to declare anything but you can instantiate it like this:

this.inputCardState = this.conversationState.createProperty('cardState');

您将需要一种一致的方式来生成卡,该方法可在您最初发送卡和更新卡时使用.我在C#中使用AdaptiveCards NuGet包:

You'll want a consistent way to generate your card that you can use when you send the card initially and when you update the card. I'm using the AdaptiveCards NuGet package in C#:

public static IActivity GenerateAdaptiveCardActivityWithInputs(int inputCount, object valueObject)
{
    var cardData = JObject.FromObject(valueObject);
    var cardId = Convert.ToString(cardData[KEYCARDID]);

    var card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0))
    {
        Body = Enumerable.Range(0, inputCount).Select(i =>
        {
            var inputId = $"text{i}";

            return new AdaptiveTextInput
            {
                Id = inputId,
                Value = Convert.ToString(cardData[inputId]),
            };
        }).ToList<AdaptiveElement>(),
        Actions = new List<AdaptiveAction>
        {
            new AdaptiveSubmitAction
            {
                Title = "Add field",
                Data = new Dictionary<string, string>
                {
                    { KEYCARDID, cardId },
                    { KEYSUBMITACTIONID, ACTIONSUBMITADDFIELD },
                },
            },
            new AdaptiveSubmitAction
            {
                Title = "Submit",
            },
        },
    };

    return MessageFactory.Attachment(new Attachment(AdaptiveCard.ContentType, content: JObject.FromObject(card)));
}

Node.js:

generateAdaptiveCardActivityWithInputs(inputCount, cardData) {
    var cardId = cardData[KEYCARDID];
    var body = [];

    for (let i = 0; i < inputCount; i++) {
        var inputId = `text${i}`;
        body.push({
            type: "Input.Text",
            id: inputId,
            value: cardData[inputId]
        });
    }

    var card = {
        type: "AdaptiveCard",
        $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
        version: "1.0",
        body,
        actions: [
            {
                type: "Action.Submit",
                title: "Add field",
                data: {
                    [KEYCARDID]: cardId,
                    [KEYSUBMITACTIONID]: ACTIONSUBMITADDFIELD
                },
            },
            {
                type: "Action.Submit",
                title: "Submit",
            }
        ]
    };

    return MessageFactory.attachment(CardFactory.adaptiveCard(card));
}

使用此功能,您可以首先在C#中像这样发送卡:

Using this function, you can send the card initially like this in C#:

var inputCount = 1;
var cardId = Guid.NewGuid().ToString();
var reply = GenerateAdaptiveCardActivityWithInputs(inputCount, new Dictionary<string, string> { { KEYCARDID, cardId } });
var response = await turnContext.SendActivityAsync(reply, cancellationToken);
var dict = await InputCardStateAccessor.GetAsync(turnContext, () => new Dictionary<string, (string, int)>(), cancellationToken);

dict[cardId] = (response.Id, inputCount);

Node.js:

var inputCount = 1;
var cardId = Date.now().toString();
var reply = this.generateAdaptiveCardActivityWithInputs(inputCount, { [KEYCARDID]: cardId });
var response = await turnContext.sendActivity(reply);
var dict = await this.inputCardState.get(turnContext, {});
dict[cardId] = {
    activityId: response.id,
    inputCount: inputCount
};
await this.inputCardState.set(turnContext, dict);

您可以更新卡片,以响应卡片的添加字段"在C#中提交这样的操作:

And you can update the card in response to the card's "add field" submit action like this in C#:

private async Task AddFieldAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
    var activity = turnContext.Activity;

    if (activity.ChannelId == Channels.Msteams)
    {
        var value = JObject.FromObject(activity.Value);
        var cardId = Convert.ToString(value[KEYCARDID]);
        var dict = await InputCardStateAccessor.GetAsync(turnContext, () => new Dictionary<string, (string, int)>(), cancellationToken);

        if (dict.TryGetValue(cardId, out var cardInfo))
        {
            var update = GenerateAdaptiveCardActivityWithInputs(++cardInfo.InputCount, value);

            update.Id = cardInfo.ActivityId;
            update.Conversation = activity.Conversation;

            await turnContext.UpdateActivityAsync(update, cancellationToken);

            dict[cardId] = cardInfo;
        }
    }
}

Node.js:

async addField(turnContext) {
    var activity = turnContext.activity;

    if (activity.channelId == 'msteams') {
        var value = activity.value;
        var cardId = value[KEYCARDID];
        var dict = await this.inputCardState.get(turnContext, {});
        var cardInfo = dict[cardId];

        if (cardInfo) {
            var update = this.generateAdaptiveCardActivityWithInputs(++cardInfo.inputCount, value);

            update.id = cardInfo.activityId;
            update.conversation = activity.conversation;
            update.serviceUrl = activity.serviceUrl;

            dict[cardId] = cardInfo;

            await this.inputCardState.set(turnContext, dict);
            await turnContext.updateActivity(update);
        }
    }
}

这篇关于我们可以动态添加文本字段吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆