[GH-ISSUE #397] #Question, how to add add screen elements dynamically #291

Closed
opened 2026-03-04 01:03:39 +03:00 by kerem · 4 comments
Owner

Originally created by @shaunenslin on GitHub (Feb 7, 2020).
Original GitHub issue: https://github.com/rivo/tview/issues/397

Hi

I am battling to get this right. I have a flex grid on the screen and am asking them to make a choice. So, in essence

I create a flex and in it, put a dropdown.
Based on the dropdown answer, I want to ask a different question, but want to simply add the next question to the flex.

eg. Kind of like below, so when a selection is made on the ssdropdown, I want to add the ltdropdown to the flexgrid. I have used app.Draw() to try refresh the screen, but the ltdropdown never appears on the screen

func a() {
	app := tview.NewApplication()
	flex := tview.NewFlex()
	ssdropdown := tview.NewDropDown().
		SetLabel("Select from the available source systems: (hit Enter): ").
		SetOptions(strings.Split("Syspro,Pastel", ","), nil)
	ssdropdown.SetSelectedFunc(func(text string, index int) {
		ltdropdown := tview.NewDropDown().
			SetLabel("Will this be a live or test system? (hit Enter): ").
			SetOptions([]string{"TEST", "QA", "LIVE"}, nil)
		flex.AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
			AddItem(ltdropdown, 1, 0, true),
			1, 0, false)
		app.Draw()
	})
	if err := app.SetRoot(flex, true).SetFocus(ssdropdown).Run(); err != nil {
		panic(err)
	}
}
Originally created by @shaunenslin on GitHub (Feb 7, 2020). Original GitHub issue: https://github.com/rivo/tview/issues/397 Hi I am battling to get this right. I have a flex grid on the screen and am asking them to make a choice. So, in essence I create a flex and in it, put a dropdown. Based on the dropdown answer, I want to ask a different question, but want to simply add the next question to the flex. eg. Kind of like below, so when a selection is made on the ssdropdown, I want to add the ltdropdown to the flexgrid. I have used app.Draw() to try refresh the screen, but the ltdropdown never appears on the screen ``` func a() { app := tview.NewApplication() flex := tview.NewFlex() ssdropdown := tview.NewDropDown(). SetLabel("Select from the available source systems: (hit Enter): "). SetOptions(strings.Split("Syspro,Pastel", ","), nil) ssdropdown.SetSelectedFunc(func(text string, index int) { ltdropdown := tview.NewDropDown(). SetLabel("Will this be a live or test system? (hit Enter): "). SetOptions([]string{"TEST", "QA", "LIVE"}, nil) flex.AddItem(tview.NewFlex().SetDirection(tview.FlexRow). AddItem(ltdropdown, 1, 0, true), 1, 0, false) app.Draw() }) if err := app.SetRoot(flex, true).SetFocus(ssdropdown).Run(); err != nil { panic(err) } } ```
kerem closed this issue 2026-03-04 01:03:40 +03:00
Author
Owner

@agruenberg commented on GitHub (Feb 10, 2020):

Try this:

func main() {
	app := tview.NewApplication()
	flex := tview.NewFlex()
	ssdropdown := tview.NewDropDown().
		SetLabel("Select from the available source systems: (hit Enter): ").
		SetOptions(strings.Split("Syspro,Pastel", ","), nil)
	ssdropdown.SetSelectedFunc(func(text string, index int) {
		ltdropdown := tview.NewDropDown().
			SetLabel("Will this be a live or test system? (hit Enter): ").
			SetOptions([]string{"TEST", "QA", "LIVE"}, nil)
		flex.AddItem(ltdropdown, 0, 1, true)
		app.SetFocus(ltdropdown)
	})
	flex.SetDirection(tview.FlexRow)
	flex.AddItem(ssdropdown,0,1,true)
	if err := app.SetRoot(flex, true).SetFocus(ssdropdown).Run(); err != nil {
		panic(err)
	}
}

It's not a pretty GUI design, but it works.

<!-- gh-comment-id:584145536 --> @agruenberg commented on GitHub (Feb 10, 2020): Try this: ``` func main() { app := tview.NewApplication() flex := tview.NewFlex() ssdropdown := tview.NewDropDown(). SetLabel("Select from the available source systems: (hit Enter): "). SetOptions(strings.Split("Syspro,Pastel", ","), nil) ssdropdown.SetSelectedFunc(func(text string, index int) { ltdropdown := tview.NewDropDown(). SetLabel("Will this be a live or test system? (hit Enter): "). SetOptions([]string{"TEST", "QA", "LIVE"}, nil) flex.AddItem(ltdropdown, 0, 1, true) app.SetFocus(ltdropdown) }) flex.SetDirection(tview.FlexRow) flex.AddItem(ssdropdown,0,1,true) if err := app.SetRoot(flex, true).SetFocus(ssdropdown).Run(); err != nil { panic(err) } } ``` It's not a pretty GUI design, but it works.
Author
Owner

@rivo commented on GitHub (Feb 19, 2020):

@agruenberg is right. Your Flex is empty because you never add ssdropdown to it.

Also, app.Draw() is not required, see here for details.

Even in @agruenberg's answer, a new DropDown will be added every time a selection is made in ssdropdown. Depending on what you want to do, this may still need more work.

Please let me know if this answers your question.

<!-- gh-comment-id:588225251 --> @rivo commented on GitHub (Feb 19, 2020): @agruenberg is right. Your `Flex` is empty because you never add `ssdropdown` to it. Also, `app.Draw()` is not required, see [here](https://github.com/rivo/tview/wiki/Concurrency) for details. Even in @agruenberg's answer, a new `DropDown` will be added every time a selection is made in `ssdropdown`. Depending on what you want to do, this may still need more work. Please let me know if this answers your question.
Author
Owner

@shaunenslin commented on GitHub (Feb 19, 2020):

Worked like a charm, thanks so much

<!-- gh-comment-id:588279468 --> @shaunenslin commented on GitHub (Feb 19, 2020): Worked like a charm, thanks so much
Author
Owner

@shaunenslin commented on GitHub (Feb 19, 2020):

Worked like a charm, thanks so much

<!-- gh-comment-id:588279616 --> @shaunenslin commented on GitHub (Feb 19, 2020): Worked like a charm, thanks so much
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#291
No description provided.