[GH-ISSUE #424] Question about input handling #308

Closed
opened 2026-03-04 01:03:49 +03:00 by kerem · 1 comment
Owner

Originally created by @holiman on GitHub (Apr 2, 2020).
Original GitHub issue: https://github.com/rivo/tview/issues/424

In the code below, I've 'mashed' together the form-example and the flex-example, so I have a flex primitive showing some empty boxes and some forms.

I'm wondering about the "Correct Way" to manage inputs. From reading the docs, I had expected that in the example code below, the flex view would shift focus betwen the children when the user pressed ghjkl (I've tried the same example using grid): https://github.com/rivo/tview/blob/master/grid.go#L272 . But in the example code, the UI does not react to any key-presses (except ctrl-c), and the focus is not shifted among the components.

Could you please point me in the right direction for how to get basic grix/flex navigation between components to work?

// Demo code for the Form primitive.
package main

import (
	"github.com/rivo/tview"
)

func main() {
	app := tview.NewApplication()
	form1 := tview.NewForm().
		AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil).
		AddInputField("First name", "", 20, nil, nil).
		AddInputField("Last name", "", 20, nil, nil).
		AddCheckbox("Age 18+", false, nil).
		AddPasswordField("Password", "", 10, '*', nil).
		AddButton("Save", nil).
		AddButton("Quit", func() {
			app.Stop()
		})
	form2 := tview.NewForm().
		AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil).
		AddInputField("First name", "", 20, nil, nil).
		AddInputField("Last name", "", 20, nil, nil).
		AddCheckbox("Age 18+", false, nil).
		AddPasswordField("Password", "", 10, '*', nil).
		AddButton("Save", nil).
		AddButton("Quit", func() {
			app.Stop()
		})
	form1.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft)
	form2.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft)

	flex := tview.NewFlex().
		AddItem(tview.NewBox().SetBorder(true).SetTitle("Left (1/2 x width of Top)"), 0, 1, true).
		AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
			AddItem(form1.SetBorder(true).SetTitle("Top"), 0, 1, true).
			AddItem(form2, 0, 3, true).
			AddItem(tview.NewBox().SetBorder(true).SetTitle("Bottom (5 rows)"), 5, 1, true), 0, 2, true).
		AddItem(tview.NewBox().SetBorder(true).SetTitle("Right (20 cols)"), 20, 1, true)
	if err := app.SetRoot(flex, true).Run(); err != nil {
		panic(err)
	}

}

Originally created by @holiman on GitHub (Apr 2, 2020). Original GitHub issue: https://github.com/rivo/tview/issues/424 In the code below, I've 'mashed' together the form-example and the flex-example, so I have a flex primitive showing some empty boxes and some forms. I'm wondering about the "Correct Way" to manage inputs. From reading the docs, I had expected that in the example code below, the flex view would shift focus betwen the children when the user pressed `ghjkl` (I've tried the same example using grid): https://github.com/rivo/tview/blob/master/grid.go#L272 . But in the example code, the UI does not react to any key-presses (except ctrl-c), and the focus is not shifted among the components. Could you please point me in the right direction for how to get basic grix/flex navigation between components to work? ```golang // Demo code for the Form primitive. package main import ( "github.com/rivo/tview" ) func main() { app := tview.NewApplication() form1 := tview.NewForm(). AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil). AddInputField("First name", "", 20, nil, nil). AddInputField("Last name", "", 20, nil, nil). AddCheckbox("Age 18+", false, nil). AddPasswordField("Password", "", 10, '*', nil). AddButton("Save", nil). AddButton("Quit", func() { app.Stop() }) form2 := tview.NewForm(). AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil). AddInputField("First name", "", 20, nil, nil). AddInputField("Last name", "", 20, nil, nil). AddCheckbox("Age 18+", false, nil). AddPasswordField("Password", "", 10, '*', nil). AddButton("Save", nil). AddButton("Quit", func() { app.Stop() }) form1.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft) form2.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft) flex := tview.NewFlex(). AddItem(tview.NewBox().SetBorder(true).SetTitle("Left (1/2 x width of Top)"), 0, 1, true). AddItem(tview.NewFlex().SetDirection(tview.FlexRow). AddItem(form1.SetBorder(true).SetTitle("Top"), 0, 1, true). AddItem(form2, 0, 3, true). AddItem(tview.NewBox().SetBorder(true).SetTitle("Bottom (5 rows)"), 5, 1, true), 0, 2, true). AddItem(tview.NewBox().SetBorder(true).SetTitle("Right (20 cols)"), 20, 1, true) if err := app.SetRoot(flex, true).Run(); err != nil { panic(err) } } ```
kerem closed this issue 2026-03-04 01:03:49 +03:00
Author
Owner

@holiman commented on GitHub (Apr 2, 2020):

Ah, never mind this. I just found that this was answered a couple of days ago already: https://github.com/rivo/tview/issues/421 . That same trick seems to work pretty well.

I guess this ticket can be closed.

<!-- gh-comment-id:608085697 --> @holiman commented on GitHub (Apr 2, 2020): Ah, never mind this. I just found that this was answered a couple of days ago already: https://github.com/rivo/tview/issues/421 . That same trick seems to work pretty well. I guess this ticket can be closed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#308
No description provided.