spectre.console icon indicating copy to clipboard operation
spectre.console copied to clipboard

SelectionPrompt - Set default value not available

Open vanheesk opened this issue 2 years ago • 14 comments

Is your feature request related to a problem? Please describe. SelectionPrompt does not contain a "Select" -method. It is however available on MultiSelectionPrompt.

Describe the solution you'd like Option 1: Add the same "Select" and "IsSelected" -methods (as available in MultiSelectionPromptExtensions) to the SelectionPromptExtensions -class.

Option 2: Add a "DefaultValue" (as available in TextPrompt) to the SelectionPromptExtensions -class.

Describe alternatives you've considered I'm currently planning to work around this by setting the selected item as the first one in the list of choices. But that might be confusing for users.


Please upvote :+1: this issue if you are interested in it.

vanheesk avatar Aug 09 '21 10:08 vanheesk

@vanheesk SelectionPrompt does not have a default value, since that would mean that the selection prompt is never shown. Could you explain a bit more in detail what your use case is? Maybe I'm misunderstanding something.

patriksvensson avatar Aug 09 '21 11:08 patriksvensson

Say I have a SelectionPrompt asking "What is your favorite fruit", and I provide the user with a list of choices. (Apple, Banana, Cherry, Coconut, Dragonfruit). I select "Cherry" and store this somewhere. Now, I'm asking the user that same question again and I want to put the cursor on his/her previously selected item, so they know what was previously selected, but can still change it.

vanheesk avatar Aug 09 '21 11:08 vanheesk

I second this. I use MultiSelectionPrompt to ask the user for a list of permission assigned to a role. When the user is editing the role, I do want to have the already-assigned permissions checked by default.

What would be the best way to implement that? I can write the code and make a pull request.

ancailliau avatar Sep 29 '21 08:09 ancailliau

You can pre-check items. However, you have to add the items one by one. In my code I use something like this:

var prompt = new MultiSelectionPrompt<MyItem>()
    .Title("Choose items:")
    .UseConverter(item => item.Name);
foreach (var item in myItems)
{
    if (IsChecked(item))
        prompt.AddChoices(item, r => r.Select());
    else
        prompt.AddChoices(item);
}

thoemmi avatar Sep 29 '21 09:09 thoemmi

The original question was about SingleSelect specifically, which I solved / worked around using:

var singleSelect = new SelectionPrompt<string>();

var singleSelectOptions = options;
if (currentValue != null)
{
    singleSelectOptions = new Dictionary<string, string>();

    // Add the selected item first, then add the other options as provided
    singleSelectOptions.Add(currentValue, options[currentValue]);
    foreach (var entry in options)
    {
        if (entry.Key == currentValue)
            continue;

        singleSelectOptions.Add(entry.Key, entry.Value);
     }
}

singleSelect.AddChoices(singleSelectOptions.Values);

var selection = AnsiConsole.Prompt(singleSelect);
var optionId = options.FirstOrDefault(x => x.Value == selection).Key;

return new List<string> { optionId };

vanheesk avatar Sep 29 '21 09:09 vanheesk

I would like to see that feature, too. My usecase is: I'm showing a "menu" usign the Single-Selection-Feature. When a user selects an entry some action is executed. After the execution the menu is shown again where last action executed is selected

Scordo avatar Mar 24 '22 07:03 Scordo

I would also love the support of Select or DefaultValue on the SelectionPrompt. My use case involves a list of items (5 in my case) where a selection of a single item of the list is required as they are all mutually exclusive. Re-ordering the list is not an option for given the desire to have the options listed alphabetically.

The workaround for us is a bit ugly since we're also having to drop the previous option on the prompt and force the user to verify the select before pressing enter and again at the end of the workflow before changes are saved.

Just including a DefaultValue would help alleviate these issues.

For reference this is what we're having to do at the prompt (simplified)

// Omitted is some reflection iterating over custom attributes on a settings DTO style object.
var previous = (bool?)propertyInfo.GetValue(config);
var promptTitle = $"{attribute.QueryPrompt ?? "MISSING: QueryPrompt attribute value"} [green](Previously: {previous})[/]";

var prompt = new SelectionPrompt<string>()
                        .Title(promptTitle)
                        .AddChoices(attribute.QueryExclusiveOptions);

var newValue = AnsiConsole.Prompt(prompt);

propertyInfo.SetValue(config, newValue);

this.AnsiConsole.MarkupLine($"{prompt}: {newValue}");

Once all the settings have been re-confirmed a table is once again displayed with the options from before and after. We're highlighting the "after" options that differ from the originals in yellow and asking the users to verify before selecting yes to save. It's a less than ideal solution but given some users like to use the wizard vs set individual options having a way to default a single select list would be greatly impactful.

fritogotlayed avatar Apr 01 '23 15:04 fritogotlayed

First of all, thanks for a wonderful library! It's working really well.

Being able to set a selection default would be really helpful for my purposes too. I'm creating a tool that helps generate StateSmith state machine projects and I want to remember the user's choices from last time.

My current thinking for a workaround is to put it at the top with a "remembered" prefix or postfix.

image

image

adamfk avatar Aug 05 '23 14:08 adamfk

Are you accepting pull requests for this? I've prototyped a change, and it works well (plus it's a reasonably small change!). It adds a DefaultValue property and extension method to SelectionPrompt.

var prompt = new SelectionPrompt<string>()
        .Title("Select one")
        .AddChoices("First", "Second", "Third")
        .DefaultValue("Second");

AnsiConsole.Prompt(prompt);
Select one
              
  First   
> Second  
  Third   

reduckted avatar Nov 09 '23 12:11 reduckted

@patriksvensson Are you accepting pull requests for this?

reduckted avatar Dec 20 '23 10:12 reduckted