AlecAivazis / survey

A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
MIT License
4.07k stars 350 forks source link

How to filter data from input options? #425

Closed jukie closed 2 years ago

jukie commented 2 years ago

I have a struct that I'd like to display a specific field for users to choose from, is there a way to filter this in the display prompt? For example I only want to show Version from the struct below and have users select one.

type Release struct {
    SomeDetail    bool
    Somethingelse int
    LongMetadata  string
    Version       string
}
mislav commented 2 years ago

Hi, you could collect all the Version values in a string slice and then use those as Options to a Select. The trick is to use an int receiver as the result from the prompt, so that you know the numeric index of the Release that the user has chosen:

releases := []Release{
  {
    Version: "1.2.3"
  },
  {
    Version: "1.0.2"
  },
}

var releaseOptions []string
for _, rel := range releases {
  releaseOptions = append(releaseOptions, rel.Version)
}

prompt := &survey.Select{
    Message: "Choose a release:",
    Options: releaseOptions,
}

var releaseIndex int
survey.AskOne(prompt, &releaseIndex)

// use the index value to reference the original Release struct
chosenRelease := releases[releaseIndex]
jukie commented 2 years ago

I guess that was an obvious alternative but was curious if there's a dynamic way to filter the options as they're presented to the user.

mislav commented 2 years ago

but was curious if there's a dynamic way to filter the options as they're presented to the user.

I'm not sure what you mean by "filtering" the options, but Select and MultiSelect prompts only support a slice of strings as Options, so whatever your data structure is, you always need to convert it to a slice of strings in your app. Survey doesn't handle this at the moment.