[GH-ISSUE #725] Get table row and column from inputfield #530

Closed
opened 2026-03-04 01:05:47 +03:00 by kerem · 2 comments
Owner

Originally created by @jacques-andre on GitHub (Apr 18, 2022).
Original GitHub issue: https://github.com/rivo/tview/issues/725

I am creating a Sudoku game where a user is able to select a cell in a table and using a inputField able to input a value for that cell.

I am having difficulties getting the selected row and column from the user and passing it to my inputField.

I want my inputField to be able to change the current cell's value.

package main

import (
	"strconv"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

func main() {
	grid := [9][9]int{}

	app := tview.NewApplication()
	test := tview.NewTextView()
	table := tview.NewTable().SetBorders(true)
	table.SetSelectable(true, true)

	// create a table
	for row := 0; row < len(grid); row++ {
		for col := 0; col < len(grid[row]); col++ {
			currentBoardValue := grid[row][col]
			newCell := tview.NewTableCell(strconv.Itoa(currentBoardValue))

			// add new cell to table
			table.SetCell(row, col, newCell)
		}
	}

	// create inputField with titles
	inputField := tview.NewInputField().
		SetLabel("Enter a number: ").
		SetFieldWidth(10).
		SetAcceptanceFunc(tview.InputFieldInteger)

	// When enter is pressed on input
	inputField.SetDoneFunc(func(key tcell.Key) {
		app.SetFocus(table)
		// how can i get the table row and col here?

		test.SetText(inputField.GetText())
		inputField.SetText("")
	})

	tviewGrid := tview.NewGrid().SetBorders(true)

	tviewGrid.AddItem(table, 0, 0, 2, 1, 1, 1, true)
	tviewGrid.AddItem(inputField, 2, 0, 2, 1, 1, 1, false)
	tviewGrid.AddItem(test, 0, 1, 2, 1, 1, 1, false)

	// when cell is selected
	table.SetSelectedFunc(func(row int, col int) {

		// set the focus to input
		app.SetFocus(inputField)

		// I want to be able to update the selcted cell based off inputField, this doesn't work

		table.GetCell(row, col).SetText(inputField.GetText())

	})
	// run the app
	err := app.SetRoot(tviewGrid, true).EnableMouse(false).Run()
	if err != nil {
		panic(err)
	}
}
Originally created by @jacques-andre on GitHub (Apr 18, 2022). Original GitHub issue: https://github.com/rivo/tview/issues/725 I am creating a Sudoku game where a user is able to select a cell in a table and using a inputField able to input a value for that cell. I am having difficulties getting the selected row and column from the user and passing it to my inputField. I want my inputField to be able to change the current cell's value. ```go package main import ( "strconv" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) func main() { grid := [9][9]int{} app := tview.NewApplication() test := tview.NewTextView() table := tview.NewTable().SetBorders(true) table.SetSelectable(true, true) // create a table for row := 0; row < len(grid); row++ { for col := 0; col < len(grid[row]); col++ { currentBoardValue := grid[row][col] newCell := tview.NewTableCell(strconv.Itoa(currentBoardValue)) // add new cell to table table.SetCell(row, col, newCell) } } // create inputField with titles inputField := tview.NewInputField(). SetLabel("Enter a number: "). SetFieldWidth(10). SetAcceptanceFunc(tview.InputFieldInteger) // When enter is pressed on input inputField.SetDoneFunc(func(key tcell.Key) { app.SetFocus(table) // how can i get the table row and col here? test.SetText(inputField.GetText()) inputField.SetText("") }) tviewGrid := tview.NewGrid().SetBorders(true) tviewGrid.AddItem(table, 0, 0, 2, 1, 1, 1, true) tviewGrid.AddItem(inputField, 2, 0, 2, 1, 1, 1, false) tviewGrid.AddItem(test, 0, 1, 2, 1, 1, 1, false) // when cell is selected table.SetSelectedFunc(func(row int, col int) { // set the focus to input app.SetFocus(inputField) // I want to be able to update the selcted cell based off inputField, this doesn't work table.GetCell(row, col).SetText(inputField.GetText()) }) // run the app err := app.SetRoot(tviewGrid, true).EnableMouse(false).Run() if err != nil { panic(err) } } ```
kerem closed this issue 2026-03-04 01:05:47 +03:00
Author
Owner

@moson-mo commented on GitHub (Jun 6, 2022):

Hi,

// how can i get the table row and col here?
r, c := table.GetSelection()       // returns selected cell coordinates
cell := table.GetCell(r, c)        // gets cell from coordinates
cell.SetText(inputField.GetText()) // set cell value from input field
// I want to be able to update the selcted cell based off inputField, this doesn't work

table.GetCell(row, col).SetText(inputField.GetText())

With the change above you probably don't want to do this at all...

Full code
package main

import (
	"strconv"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

func main() {
	grid := [9][9]int{}

	app := tview.NewApplication()
	test := tview.NewTextView()
	table := tview.NewTable().SetBorders(true)
	table.SetSelectable(true, true)

	// create a table
	for row := 0; row < len(grid); row++ {
		for col := 0; col < len(grid[row]); col++ {
			currentBoardValue := grid[row][col]
			newCell := tview.NewTableCell(strconv.Itoa(currentBoardValue))

			// add new cell to table
			table.SetCell(row, col, newCell)
		}
	}

	// create inputField with titles
	inputField := tview.NewInputField().
		SetLabel("Enter a number: ").
		SetFieldWidth(10).
		SetAcceptanceFunc(tview.InputFieldInteger)

	// When enter is pressed on input
	inputField.SetDoneFunc(func(key tcell.Key) {
		app.SetFocus(table)
		r, c := table.GetSelection()       // returns selected cell coordinates
		cell := table.GetCell(r, c)        // gets cell from coordinates
		cell.SetText(inputField.GetText()) // set cell value from input
	})

	tviewGrid := tview.NewGrid().SetBorders(true)

	tviewGrid.AddItem(table, 0, 0, 2, 1, 1, 1, true)
	tviewGrid.AddItem(inputField, 2, 0, 2, 1, 1, 1, false)
	tviewGrid.AddItem(test, 0, 1, 2, 1, 1, 1, false)

	// when cell is selected
	table.SetSelectedFunc(func(row int, col int) {

		// set the focus to input
		app.SetFocus(inputField)

		// I want to be able to update the selcted cell based off inputField, this doesn't work

		//table.GetCell(row, col).SetText(inputField.GetText())

	})
	// run the app
	err := app.SetRoot(tviewGrid, true).EnableMouse(false).Run()
	if err != nil {
		panic(err)
	}
}
<!-- gh-comment-id:1147849464 --> @moson-mo commented on GitHub (Jun 6, 2022): Hi, > ```go > // how can i get the table row and col here? > ``` ```go r, c := table.GetSelection() // returns selected cell coordinates cell := table.GetCell(r, c) // gets cell from coordinates cell.SetText(inputField.GetText()) // set cell value from input field ``` > ```go > // I want to be able to update the selcted cell based off inputField, this doesn't work > >table.GetCell(row, col).SetText(inputField.GetText()) > ``` With the change above you probably don't want to do this at all... <details><summary>Full code</summary> ```go package main import ( "strconv" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) func main() { grid := [9][9]int{} app := tview.NewApplication() test := tview.NewTextView() table := tview.NewTable().SetBorders(true) table.SetSelectable(true, true) // create a table for row := 0; row < len(grid); row++ { for col := 0; col < len(grid[row]); col++ { currentBoardValue := grid[row][col] newCell := tview.NewTableCell(strconv.Itoa(currentBoardValue)) // add new cell to table table.SetCell(row, col, newCell) } } // create inputField with titles inputField := tview.NewInputField(). SetLabel("Enter a number: "). SetFieldWidth(10). SetAcceptanceFunc(tview.InputFieldInteger) // When enter is pressed on input inputField.SetDoneFunc(func(key tcell.Key) { app.SetFocus(table) r, c := table.GetSelection() // returns selected cell coordinates cell := table.GetCell(r, c) // gets cell from coordinates cell.SetText(inputField.GetText()) // set cell value from input }) tviewGrid := tview.NewGrid().SetBorders(true) tviewGrid.AddItem(table, 0, 0, 2, 1, 1, 1, true) tviewGrid.AddItem(inputField, 2, 0, 2, 1, 1, 1, false) tviewGrid.AddItem(test, 0, 1, 2, 1, 1, 1, false) // when cell is selected table.SetSelectedFunc(func(row int, col int) { // set the focus to input app.SetFocus(inputField) // I want to be able to update the selcted cell based off inputField, this doesn't work //table.GetCell(row, col).SetText(inputField.GetText()) }) // run the app err := app.SetRoot(tviewGrid, true).EnableMouse(false).Run() if err != nil { panic(err) } } ``` </details>
Author
Owner

@rivo commented on GitHub (Jun 10, 2022):

@jacques-andre You're setting the text of the table cell too early. When the selected func is executed, there is no text yet in the input field. You have to wait for the user to enter it. There are many ways to solve this. Here's one way:

package main

import (
	"strconv"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

func main() {
	grid := [9][9]int{}

	app := tview.NewApplication()
	test := tview.NewTextView()
	table := tview.NewTable().SetBorders(true)
	table.SetSelectable(true, true)

	// create a table
	for row := 0; row < len(grid); row++ {
		for col := 0; col < len(grid[row]); col++ {
			currentBoardValue := grid[row][col]
			newCell := tview.NewTableCell(strconv.Itoa(currentBoardValue))

			// add new cell to table
			table.SetCell(row, col, newCell)
		}
	}

	// create inputField with titles
	inputField := tview.NewInputField().
		SetLabel("Enter a number: ").
		SetFieldWidth(10).
		SetAcceptanceFunc(func(text string, ch rune) bool {
			return len(text) <= 1 && ch >= '1' && ch <= '9' // Sudoku only allows 1-9.
		})

	tviewGrid := tview.NewGrid().SetBorders(true)

	tviewGrid.AddItem(table, 0, 0, 2, 1, 1, 1, true)
	tviewGrid.AddItem(inputField, 2, 0, 2, 1, 1, 1, false)
	tviewGrid.AddItem(test, 0, 1, 2, 1, 1, 1, false)

	// when cell is selected
	table.SetSelectedFunc(func(row int, col int) {

		inputField.SetText("")
		app.SetFocus(inputField)

		inputField.SetDoneFunc(func(key tcell.Key) {
			table.GetCell(row, col).SetText(inputField.GetText())
			inputField.SetText("")
			app.SetFocus(table)
		})

	})
	// run the app
	err := app.SetRoot(tviewGrid, true).EnableMouse(false).Run()
	if err != nil {
		panic(err)
	}
}
<!-- gh-comment-id:1152490818 --> @rivo commented on GitHub (Jun 10, 2022): @jacques-andre You're setting the text of the table cell too early. When the `selected func` is executed, there is no text yet in the input field. You have to wait for the user to enter it. There are many ways to solve this. Here's one way: ```go package main import ( "strconv" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) func main() { grid := [9][9]int{} app := tview.NewApplication() test := tview.NewTextView() table := tview.NewTable().SetBorders(true) table.SetSelectable(true, true) // create a table for row := 0; row < len(grid); row++ { for col := 0; col < len(grid[row]); col++ { currentBoardValue := grid[row][col] newCell := tview.NewTableCell(strconv.Itoa(currentBoardValue)) // add new cell to table table.SetCell(row, col, newCell) } } // create inputField with titles inputField := tview.NewInputField(). SetLabel("Enter a number: "). SetFieldWidth(10). SetAcceptanceFunc(func(text string, ch rune) bool { return len(text) <= 1 && ch >= '1' && ch <= '9' // Sudoku only allows 1-9. }) tviewGrid := tview.NewGrid().SetBorders(true) tviewGrid.AddItem(table, 0, 0, 2, 1, 1, 1, true) tviewGrid.AddItem(inputField, 2, 0, 2, 1, 1, 1, false) tviewGrid.AddItem(test, 0, 1, 2, 1, 1, 1, false) // when cell is selected table.SetSelectedFunc(func(row int, col int) { inputField.SetText("") app.SetFocus(inputField) inputField.SetDoneFunc(func(key tcell.Key) { table.GetCell(row, col).SetText(inputField.GetText()) inputField.SetText("") app.SetFocus(table) }) }) // run the app err := app.SetRoot(tviewGrid, true).EnableMouse(false).Run() if err != nil { panic(err) } } ```
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#530
No description provided.