Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Commit

Permalink
[Feature] [#273] Improve select all and select none in multiselect pr…
Browse files Browse the repository at this point in the history
…ompt. (#296)

* Improve select all and select none in multiselect prompt.

* Update readme multiselect.

Co-authored-by: Fabiano Chiareto Fernandes <fabiano.fernandes@zup.com.br>
  • Loading branch information
chiaretto and fabianofernandeszup committed Aug 3, 2020
1 parent 0257161 commit 863da4d
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ survey.AskOne(prompt, &days, survey.WithPageSize(10))

### MultiSelect

<img src="https://thumbs.gfycat.com/SharpTameAntelope-size_restricted.gif" width="450px"/>
![Example](img/multi-select-all-none.gif)

```golang
days := []string{}
Expand Down
Binary file added img/multi-select-all-none.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion multiselect.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var MultiSelectQuestionTemplate = `
{{- color "default+hb"}}{{ .Message }}{{ .FilterMessage }}{{color "reset"}}
{{- if .ShowAnswer}}{{color "cyan"}} {{.Answer}}{{color "reset"}}{{"\n"}}
{{- else }}
{{- " "}}{{- color "cyan"}}[Use arrows to move, space to select, type to filter{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
{{- " "}}{{- color "cyan"}}[Use arrows to move, space to select, <right> to all, <left> to none, type to filter{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
{{- "\n"}}
{{- range $ix, $option := .PageEntries}}
{{- if eq $ix $.SelectedIndex }}{{color $.Config.Icons.SelectFocus.Format }}{{ $.Config.Icons.SelectFocus.Text }}{{color "reset"}}{{else}} {{end}}
Expand Down Expand Up @@ -118,6 +118,20 @@ func (m *MultiSelect) OnChange(key rune, config *PromptConfig) {
} else if key >= terminal.KeySpace {
m.filter += string(key)
m.VimMode = false
} else if key == terminal.KeyArrowRight {
for _, v := range options {
m.checked[v.Index] = true
}
if !config.KeepFilter {
m.filter = ""
}
} else if key == terminal.KeyArrowLeft {
for _, v := range options {
m.checked[v.Index] = false
}
if !config.KeepFilter {
m.filter = ""
}
}

m.FilterMessage = ""
Expand Down
144 changes: 129 additions & 15 deletions multiselect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestMultiSelectRender(t *testing.T) {
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
Expand Down Expand Up @@ -81,7 +81,7 @@ func TestMultiSelectRender(t *testing.T) {
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, type to filter, %s for more help]", defaultIcons().Question.Text, string(defaultPromptConfig().HelpInput)),
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter, %s for more help]", defaultIcons().Question.Text, string(defaultPromptConfig().HelpInput)),
fmt.Sprintf(" %s foo", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
Expand All @@ -102,7 +102,7 @@ func TestMultiSelectRender(t *testing.T) {
strings.Join(
[]string{
fmt.Sprintf("%s This is helpful", defaultIcons().Help.Text),
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf(" %s foo", defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s bar", defaultIcons().MarkedOption.Text),
fmt.Sprintf("%s %s baz", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
Expand All @@ -121,7 +121,7 @@ func TestMultiSelectRender(t *testing.T) {
},
strings.Join(
[]string{
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf("%s Pick your words: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]", defaultIcons().Question.Text),
fmt.Sprintf("%s %s bar", defaultIcons().SelectFocus.Text, defaultIcons().UnmarkedOption.Text),
fmt.Sprintf(" %s baz", defaultIcons().UnmarkedOption.Text),
},
Expand Down Expand Up @@ -163,7 +163,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Select Monday.
c.Send(string(terminal.KeyArrowDown))
c.SendLine(" ")
Expand All @@ -179,7 +179,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Default: []string{"Tuesday", "Thursday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
c.SendLine("")
c.ExpectEOF()
},
Expand All @@ -196,7 +196,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Default: []int{2, 4},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
c.SendLine("")
c.ExpectEOF()
},
Expand All @@ -213,7 +213,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Default: []string{"Tuesday", "Thursday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Deselect Tuesday.
c.Send(string(terminal.KeyArrowDown))
c.Send(string(terminal.KeyArrowDown))
Expand All @@ -230,7 +230,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Help: "Saturday is best",
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter, ? for more help]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter, ? for more help]")
c.Send("?")
c.ExpectString("Saturday is best")
// Select Saturday
Expand All @@ -248,7 +248,7 @@ func TestMultiSelectPrompt(t *testing.T) {
PageSize: 1,
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Select Monday.
c.Send(string(terminal.KeyArrowDown))
c.SendLine(" ")
Expand All @@ -264,7 +264,7 @@ func TestMultiSelectPrompt(t *testing.T) {
VimMode: true,
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Select Tuesday.
c.Send("jj ")
// Select Thursday.
Expand All @@ -287,7 +287,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Filter down to Tuesday.
c.Send("Tues")
// Select Tuesday.
Expand All @@ -304,7 +304,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Filter down to Tuesday.
c.Send("tues")
// Select Tuesday.
Expand Down Expand Up @@ -341,7 +341,7 @@ func TestMultiSelectPrompt(t *testing.T) {
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Filter down to Tuesday.
c.Send("Tues")
// Select Tuesday.
Expand All @@ -355,6 +355,120 @@ func TestMultiSelectPrompt(t *testing.T) {
},
[]core.OptionAnswer{},
},
{
"select all",
&MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Select all
c.Send(string(terminal.KeyArrowRight))
c.SendLine("")
c.ExpectEOF()
},
[]core.OptionAnswer{
core.OptionAnswer{Value: "Sunday", Index: 0},
core.OptionAnswer{Value: "Monday", Index: 1},
core.OptionAnswer{Value: "Tuesday", Index: 2},
core.OptionAnswer{Value: "Wednesday", Index: 3},
core.OptionAnswer{Value: "Thursday", Index: 4},
core.OptionAnswer{Value: "Friday", Index: 5},
core.OptionAnswer{Value: "Saturday", Index: 6},
},
},
{
"select none",
&MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Select first
c.Send(" ")
// Select second
c.Send(string(terminal.KeyArrowDown))
c.Send(" ")
// Deselect all
c.Send(string(terminal.KeyArrowLeft))
c.SendLine("")
c.ExpectEOF()
},
[]core.OptionAnswer{},
},
{
"select all with filter",
&MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Send filter
c.Send("tu")
// Select all
c.Send(string(terminal.KeyArrowRight))
c.SendLine("")
c.ExpectEOF()
},
[]core.OptionAnswer{
core.OptionAnswer{Value: "Tuesday", Index: 2},
core.OptionAnswer{Value: "Saturday", Index: 6},
},
},
{
"select all with filter and select others without filter",
&MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Select first
c.Send(" ")
// Select second
c.Send(string(terminal.KeyArrowDown))
c.Send(" ")
// Send filter
c.Send("tu")
// Select all
c.Send(string(terminal.KeyArrowRight))
c.SendLine("")
c.ExpectEOF()
},
[]core.OptionAnswer{
core.OptionAnswer{Value: "Sunday", Index: 0},
core.OptionAnswer{Value: "Monday", Index: 1},
core.OptionAnswer{Value: "Tuesday", Index: 2},
core.OptionAnswer{Value: "Saturday", Index: 6},
},
},
{
"select all with filter and deselect one without filter",
&MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
},
func(c *expect.Console) {
c.ExpectString("What days do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Send filter
c.Send("tu")
// Select all
c.Send(string(terminal.KeyArrowRight))
// Deselect second
c.Send(string(terminal.KeyArrowDown))
c.Send(string(terminal.KeyArrowDown))
c.Send(" ")
c.SendLine("")
c.ExpectEOF()
},
[]core.OptionAnswer{
core.OptionAnswer{Value: "Saturday", Index: 6},
},
},

}

for _, test := range tests {
Expand All @@ -373,7 +487,7 @@ func TestMultiSelectPromptKeepFilter(t *testing.T) {
Options: []string{"green", "red", "light-green", "blue", "black", "yellow", "purple"},
},
func(c *expect.Console) {
c.ExpectString("What color do you prefer: [Use arrows to move, space to select, type to filter]")
c.ExpectString("What color do you prefer: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]")
// Filter down to green
c.Send("green")
// Select green.
Expand Down

0 comments on commit 863da4d

Please sign in to comment.