Search code examples
c#botframeworkformflow

Hide "No Preference" button only in the change prompt


I would like to remove the "No Preference" only in the "Change prompt" in the formflow or at least change it text only for the confirmation prompt leaving the of the form with "No Preference" option.

I was able to change its text, but it changed the whole form and didn't work for me.

enter image description here

public static IForm<PromoBot> BuildForm()
    var form = new FormBuilder<PromoBot>()
        .Message("Hi......!")
        .Field(nameof(Nome), validate: async (state, value) =>
            {
                ..........
                result.IsValid = true;
                return result;
            }, active: state => true)
        .Message("xxxxxx")
        .Field(nameof(CEP)
        .Field(nameof(Estados))
        .Confirm(async (state) =>
        {
            return new PromptAttribute("You have selected the following:  \n {*} "Is this correct?{||}");
        })
        .Message("Excelente! Agora vou precisar de alguns segundos para encontrar o melhor plano para sua empresa… já volto!")
        .OnCompletion(OnComplete);

    var noPreferenceStrings = new string[] { "New Text" };
    form.Configuration.Templates.Single(t => t.Usage == TemplateUsage.NoPreference).Patterns = noPreferenceStrings;
    form.Configuration.NoPreference = noPreferenceStrings;

    return form.Build();
}

Solution

  • Ordinarily you can use a template attribute to modify FormFlow's behavior, but the navigation step is sort of finicky. I think the best thing to do in this situation is provide your form with a custom prompter.

    In your case, the code could look something like this:

    public static IForm<MyClass> BuildForm()
    {
        var formBuilder = new FormBuilder<MyClass>()
            .Field(nameof(FirstName))
            .Field(nameof(LastName))
            .Confirm("Is this okay? {*}")
            .Prompter(PromptAsync)
            ;
    
        return formBuilder.Build();
    }
    
    /// <summary>
    /// Here is the method we're using for the PromptAsyncDelgate.
    /// </summary>
    private static async Task<FormPrompt> PromptAsync(IDialogContext context, FormPrompt prompt,
        MyClass state, IField<MyClass> field)
    {
        var preamble = context.MakeMessage();
        var promptMessage = context.MakeMessage();
    
        // Check to see if the form is on the navigation step
        if (field.Name.Contains("navigate") && prompt.Buttons.Any())
        {
            // If it's on the navigation step,
            // we want to change or remove the No Preference line
    
            if (you_want_to_change_it)
            {
                var noPreferenceButton = prompt.Buttons.Last();
                // Make sure the Message stays the same or else
                // FormFlow won't know what to do when this button is clicked
                noPreferenceButton.Message = noPreferenceButton.Description;
                noPreferenceButton.Description = "Back"; 
            }
            else if(you_want_to_remove_it)
            {
                prompt.Buttons.RemoveAt(prompt.Buttons.Count - 1);
            }
        }
    
        if (prompt.GenerateMessages(preamble, promptMessage))
        {
            await context.PostAsync(preamble);
        }
    
        await context.PostAsync(promptMessage);
    
        return prompt;
    }
    

    One additional note: "Back" is actually a special command in FormFlow. Whereas "No Preference" will take you back to the confirmation step, "Back" will take you to the last field in the form. If you want to actually put a back button in your navigation step, you can leave out this line:

    noPreferenceButton.Message = noPreferenceButton.Description;