Obter entrada do usuário com formulários

Anterior: Exibir conteúdo de marcação

Agora que sabemos como apresentar conteúdo básico de markdown, vamos tentar mostrar algo mais significativo aproveitando o poder de Cartões Adaptativos. Isso é útil para criar formulários ou para exibir conteúdo mais complexo.

Trabalhar com formulários

Você pode criar um cartão na Paleta de Comandos com a IFormContent interface (consulte FormContent para a implementação do kit de ferramentas). Isso permite que você forneça o JSON do Adaptive Card e a Paleta de Comandos o renderizará para você. Quando o utilizador submeter o formulário, a Paleta de Comandos chamará o método SubmitForm no seu formulário, com o conjunto de dados JSON e as entradas do formulário.

Sugestão

As cargas úteis adaptáveis do cartão podem ser criadas usando o Adaptive Card Designer. Você pode projetar o seu cartão lá e, em seguida, copiar o conteúdo JSON para a sua extensão.

  1. Pages No diretório, adicione uma nova classe
  2. Nomeie a classe FormPage
  3. Atualize a FormPage classe:
internal sealed partial class FormPage : ContentPage
{
    private readonly SampleContentForm sampleForm = new();

    public override IContent[] GetContent() => [sampleForm];

    public FormPage()
    {
        Name = "Open";
        Title = "Sample Content";
        Icon = new IconInfo("\uECA5"); // Tiles
    }
}

O FormPage é uma página de conteúdo que exibe um formulário (SampleContentForm) para o usuário. Cria uma instância de SampleContentForm, que é um formulário (definido posteriormente) que descreve a interface do utilizador e a lógica de um formulário de entrada de utilizador.

  1. Na parte inferior do arquivo (sob a FormPage classe) adicione:
internal sealed partial class SampleContentForm : FormContent
{
    public SampleContentForm()
    {
        TemplateJson = $$"""
{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.6",
    "body": [
        {
            "type": "TextBlock",
            "size": "medium",
            "weight": "bolder",
            "text": " Sample",
            "horizontalAlignment": "center",
            "wrap": true,
            "style": "heading"
        },
        {
            "type": "Input.Text",
            "label": "Name",
            "style": "text",
            "id": "SimpleVal",
            "isRequired": true,
            "errorMessage": "Name is required",
            "placeholder": "Enter your name"
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Submit",
            "data": {
                "id": "1234567890"
            }
        }
    ]
}
""";

    }

    public override CommandResult SubmitForm(string payload)
    {
        var formInput = JsonNode.Parse(payload)?.AsObject();
        Debug.WriteLine($"Form submitted with formInput: {formInput}");
        if (formInput == null)
        {
            return CommandResult.GoHome();
        }
        ConfirmationArgs confirmArgs = new()
        {
            PrimaryCommand = new AnonymousCommand(
                () =>
                {
                    string? name = formInput["Name"]?.ToString();
                    ToastStatusMessage t = new($"Hi {name}" ?? "No name entered");
                    t.Show();
                })
            {
                Name = "Confirm",
                 Result = CommandResult.KeepOpen(),
            },
            Title = "You can set a title for the dialog",
            Description = "Are you really sure you want to do the thing?",
        };
        return CommandResult.Confirm(confirmArgs);
    }
}

O SampleContentForm contém o formulário e a lógica de envio do formulário. O TemplateJson contém a estrutura do formulário e ações. Este exemplo contém apenas uma entrada de texto que tem o id de "Name" e tem uma ação de envio do formulário. O SubmitForm lida com a análise da carga útil; se for inválida, retornará ao comando inicial e, caso contrário, exibirá uma caixa de diálogo de confirmação e uma notificação flutuante.

  1. Abrir <ExtensionName>CommandsProvider.cs
  2. Substitua o MarkdownPage por FormPage:
public <ExtensionName>CommandsProvider()
{
    DisplayName = "My sample extension";
    Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
    _commands = [
+       new CommandItem(new FormPage()) { Title = DisplayName },
    ];
}
  1. Implante sua extensão
  2. Na Paleta de Comandos, Reload

Captura de tela da extensão usando ContentPage para formulário simples

Cartões Adaptativos pode fazer formulários mais complexos, incluindo usar outro objeto json para criar formas personalizadas de forma dinâmica. Primeiro, você configurará seu formulário com o Adaptive Card Designer e, em seguida, atualizará seu comando.

  1. Abrir https://adaptivecards.io/designer/
  2. Na CARD PAYLOAD EDITOR, substitua o JSON por:
{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.6",
    "body": [
        {
            "type": "TextBlock",
            "size": "medium",
            "weight": "bolder",
            "text": " ${ParticipantInfoForm.title}",
            "horizontalAlignment": "center",
            "wrap": true,
            "style": "heading"
        },
        {
            "type": "Input.Text",
            "label": "Name",
            "style": "text",
            "id": "Name",
            "isRequired": true,
            "errorMessage": "Name is required",
            "placeholder": "Enter your name"
        },
        {
            "type": "TextBlock",
            "size": "medium",
            "weight": "bolder",
            "text": "${Survey.title} ",
            "horizontalAlignment": "center",
            "wrap": true,
            "style": "heading"
        },
        {
            "type": "Input.Toggle",
            "label": "Please accept the terms and conditions:",
            "title": "${Survey.questions[0].question}",
            "valueOn": "true",
            "valueOff": "false",
            "id": "AcceptsTerms",
            "isRequired": true,
            "errorMessage": "Accepting the terms and conditions is required"
        },
        {
            "type": "Input.Toggle",
            "label": "How do you feel about red cars?",
            "title": "${Survey.questions[1].question}",
            "valueOn": "RedCars",
            "valueOff": "NotRedCars",
            "id": "ColorPreference"
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Submit",
            "data": {
                "id": "1234567890"
            }
        }
    ]
}
  1. Na SAMPLE DATA EDITOR, substitua o JSON por:
{
    "ParticipantInfoForm": {
        "title": "Input.Text elements"
    },
    "Survey": {
        "title": "Input Toggle",
        "questions": [
            {
                "question": "I accept the terms and conditions (True/False)"
            },
            {
                "question": "Red cars are better than other cars"
            }
        ]
    }
}

A ferramenta Designer deve ter esta aparência:

Captura de tela de cartões adaptáveis para formulário com botões de alternância

Para adicionar este conteúdo à sua extensão:

  1. Atualizar TemplateJson com o conteúdo de CARD PAYLOAD EDITOR
  2. Em TemplateJson, adicione:
        DataJson = $$"""
{
    "ParticipantInfoForm": {
        "title": "Input.Text elements"
    },
    "Survey": {
        "title": "Input Toggle",
        "questions": [
            {
                "question": "I accept the terms and conditions (True/False)"
            },
            {
                "question": "Red cars are better than other cars"
            }
        ]
    }
}
""";
  1. Implante sua extensão
  2. Na Paleta de Comandos, Reload

Captura de tela da extensão usando ContentPage para formulário com alternâncias

TemplateJson e DataJson trabalham em conjunto para criar formulários dinâmicos e orientados por dados. TemplateJson pode atuar como modelo de formulário e DataJson como fonte de conteúdo dinâmico.

Amostra completa

Para obter um exemplo completo do uso de páginas de Formulários e Conteúdo, vá para SamplePagesExtension/Pages/SampleContentPage.cs.

Itens-chave

  • Defina o layout do seu formulário usando a propriedade TemplateJson do seu FormContent. Esta é a carga JSON do CARD PAYLOAD EDITOR no https://adaptivecards.io/designer/. Isto descreve a estrutura e a UI do seu formulário.

  • Opcionalmente, vincule dados dinâmicos usando a DataJson propriedade. Este é o JSON do SAMPLE DATA EDITOR no Adaptive Card Designer. Permite-lhe injetar valores dinâmicos no seu cartão usando espaços reservados ${...}, facilitando a localização e manutenção dos seus formulários.

  • Gerencie envios de formulários implementando o método SubmitForm. Esse método é chamado quando o usuário envia o formulário. Você receberá a carga útil do formulário como uma cadeia de caracteres JSON, que pode ser analisada e usada para acionar ações, mostrar caixas de diálogo de confirmação ou retornar resultados de navegação.

public override CommandResult SubmitForm(string payload)
{
    var formInput = JsonNode.Parse(payload)?.AsObject();
    if (formInput == null)
    {
        return CommandResult.GoHome();
    }

    // retrieve the value of the input field with the id "name"
    var name = formInput["name"]?.AsString();
        
    // do something with the data

    // and eventually
    return CommandResult.GoBack();
}

Observação

Você pode misturar e combinar diferentes IContent tipos na sua extensão. Por exemplo, você pode usar um MarkdownContent bloco para exibir uma postagem, seguido por um FormContent bloco para coletar uma resposta.