tview
tview copied to clipboard
Get table row and column from inputfield
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)
}
}
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)
}
}
@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)
}
}