VladimirMarkelov / clui

Command Line User Interface (Console UI inspired by TurboVision)
MIT License
670 stars 50 forks source link

Another question about editing database fields #128

Closed MostHated closed 5 years ago

MostHated commented 5 years ago

Thanks again for the info on editing the data table, it worked out great when I tried it in a small demo I put together to try things out.

I also wanted to try and use the cached one in the demo and I was able to almost get it working, but I am missing something when trying to write the value back. I can get the data just fine so it displays when you hit F2/Enter to edit the field, but when you try to apply it I was able to get it so every field all changed at once, or no fields changed at all. So, I guess I am stuck somewhat in the middle, lol.

Are you able to spot what I might have been doing wrong? I tried to comment a few of the different things I have tried, but over the afternoon I have tried so many things that what's there probably doesn't even make sense anymore, lol. as Thanks! -MH

func CreateTableDialog(btn *ui.Button, tableTitle string) {
    tableDialog := new(TableDialog)

    cw, ch := term.Size()

    tableDialog.View = ui.AddWindow(cw/2-75, ch/2-16, ui.AutoSize, ui.AutoSize, TxtAssetCodes)
    ui.WindowManager().BeginUpdate()
    defer ui.WindowManager().EndUpdate()
    tableDialog.View.SetGaps(1, ui.KeepValue)
    tableDialog.View.SetModal(true)
    tableDialog.View.SetPack(ui.Vertical)

    tableDialog.Frame = NewFramedWindowInput(tableDialog.View, tableTitle, nil)

    // --- Create data table ---------------------------------------------
    td := ui.CreateTableView(tableDialog.Frame, 145, 15, 1)
    ui.ActivateControl(tableDialog.Frame, td)

    cache := &dbCache{firstRow: -1}
    rowCount := len(Ad)
    td.SetShowLines(true)
    td.SetShowRowNumber(true)
    td.SetRowCount(rowCount)

    cols := []ui.Column{
        ui.Column{Title: "Asset Code", Width: 5, Alignment: ui.AlignLeft},
        ui.Column{Title: "Asset Name", Width: 50, Alignment: ui.AlignRight},
        ui.Column{Title: "Asset APIKey", Width: 30, Alignment: ui.AlignCenter},
        ui.Column{Title: "Asset RoleId", Width: 20, Alignment: ui.AlignLeft},
        ui.Column{Title: "Version", Width: 7, Alignment: ui.AlignLeft},
        ui.Column{Title: "Replaced?", Width: 10, Alignment: ui.AlignLeft},
        ui.Column{Title: "Replace Date", Width: 12, Alignment: ui.AlignLeft},
    }
    td.SetColumns(cols)
    td.OnBeforeDraw(func(col, row, colCnt, rowCnt int) {
        cache.preload(row, rowCnt)
        l, t, w, h := td.VisibleArea()
        tableDialog.Frame.SetTitle(fmt.Sprintf("Caching: %d:%d - %dx%d", l, t, w, h))
    })
    td.OnDrawCell(func(info *ui.ColumnDrawInfo) {
        info.Text = cache.value(info.Row, info.Col)
    })

    td.OnAction(func(ev ui.TableEvent) {
        btns := []string{"Close", "Dismiss"}
        var action string
        switch ev.Action {
        case ui.TableActionSort:
            action = "Sort table"
        case ui.TableActionEdit:
            c := ev.Col
            r := ev.Row

            // --- Get location vars in CDI to pass it into OnDrawCell? -----------------------------------------------
            var newInfo = ui.ColumnDrawInfo{
                Row: r, Col: c,
            }
            // --- Get old value ------------
            var oldVal string
            (func(info *ui.ColumnDrawInfo) {
                oldVal = cache.value(info.Row, info.Col)
            })(&newInfo)

            dlg := ui.CreateEditDialog(
                // --- This shows correct old value ------------
                fmt.Sprintf("Editing value: %s", oldVal), "New value", oldVal,
            )
            dlg.OnClose(func() {
                switch dlg.Result() {
                case ui.DialogButton1:

                    // --- Several things I was trying, but none work right ------------------------------------------------
                    //newText := dlg.EditResult()
                    // --- Nothing -------------
                    //var data *dbCache
                    //info.Text = data.Newvalue(r, c, newText)

                    // --- Variations of this ended up changing all values or none. So sort of closer. -------
                    //td.OnDrawCell(func(info *ui.ColumnDrawInfo) {
                    //  info.Text = cache.value(info.Row, info.Col)
                    //})

                    //newInfo.Text = dlg.EditResult()
                    //func(info *ui.ColumnDrawInfo) {
                    //   info.Text = cache.value(newInfo.Row, newInfo.Col)
                    //})(&newInfo)

                    ui.PutEvent(ui.Event{Type: ui.EventRedraw})
                }
            })
            return
        case ui.TableActionNew:
            action = "Add new row"
        case ui.TableActionDelete:
            action = "Delete row"
        default:
            action = "Unknown action"
        }

        dlg := ui.CreateConfirmationDialog(
            "<c:blue>"+action,
            "Click any button or press <c:yellow>SPACE<c:> to close the dialog",
            btns, ui.DialogButton1)
        dlg.OnClose(func() {})
    })
MostHated commented 5 years ago

Getting closer. It took me long than it should have to realize that OnDrawCell seems like it does each cell individually, which would explain why all of them changed when I tried to do something with it. I simplified it down to about as basic as it could be.

I implemented a small new function:

func (d *dbCache) NewValue(row, col int, newText string) {
    d.data[row][col] = newText
}

Then did:

            dlg.OnClose(func() {
                switch dlg.Result() {
                case ui.DialogButton1:
                    newText := dlg.EditResult()
                    cache.NewValue(c, r, newText)
                    ui.PutEvent(ui.Event{Type: ui.EventRedraw})
                }
            })

It writes back, but it seems to shift columns. Definitely much closer than I was, though.

MostHated commented 5 years ago

I got it. I had col and row mixed up in the new value >_<