Skip to content

Commit

Permalink
dialog/form: update to handle HintText and validation errors
Browse files Browse the repository at this point in the history
Fixes #2781
  • Loading branch information
lucor committed Nov 7, 2022
1 parent cae867c commit 1adeb8a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 12 deletions.
16 changes: 4 additions & 12 deletions dialog/form.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ func (d *formDialog) validateItems(err error) {
//
// Since: 2.0
func NewForm(title, confirm, dismiss string, items []*widget.FormItem, callback func(bool), parent fyne.Window) Dialog {
var itemObjects = make([]fyne.CanvasObject, len(items)*2)
for i, item := range items {
itemObjects[i*2] = widget.NewLabel(item.Text)
itemObjects[i*2+1] = item.Widget
}
content := container.New(layout.NewFormLayout(), itemObjects...)
form := widget.NewForm(items...)

d := &dialog{content: content, callback: callback, title: title, parent: parent}
d := &dialog{content: form, callback: callback, title: title, parent: parent}
d.layout = &dialogLayout{d: d}
d.dismiss = &widget.Button{Text: dismiss, Icon: theme.CancelIcon(),
OnTapped: d.Hide,
Expand All @@ -70,11 +65,8 @@ func NewForm(title, confirm, dismiss string, items []*widget.FormItem, callback

formDialog.validateItems(nil)

for _, item := range items {
if validatable, ok := item.Widget.(fyne.Validatable); ok {
validatable.SetOnValidationChanged(formDialog.validateItems)
}
}
form.SetOnValidationChanged(formDialog.validateItems)

d.create(container.NewHBox(layout.NewSpacer(), d.dismiss, confirmBtn, layout.NewSpacer()))
return formDialog
}
Expand Down
62 changes: 62 additions & 0 deletions dialog/form_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/test"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// formDialogResult is the result of the test form dialog callback.
Expand Down Expand Up @@ -81,6 +83,42 @@ func TestFormDialog_CanCancelNoValidation(t *testing.T) {
assert.Equal(t, formDialogCancel, result, "Expected cancel result")
}

func TestFormDialog_Hints(t *testing.T) {

test.NewApp()
defer test.NewApp()
test.ApplyTheme(t, theme.LightTheme())
w := test.NewWindow(nil)
w.SetFullScreen(true)

var result formDialogResult
fd := hintsFormDialog(&result, w)
w.Resize(fd.MinSize())
fd.Show()
assert.False(t, fd.win.Hidden)

assert.True(t, fd.confirm.Disabled(), "Confirm button should be disabled due to validation state")

test.AssertImageMatches(t, "form/hint_initial.png", w.Canvas().Capture())

validatingEntry, ok := fd.items[0].Widget.(*widget.Entry)
require.True(t, ok, "First item's widget should be an Entry (check hintsFormDialog)")

validatingEntry.SetText("n")
test.AssertImageMatches(t, "form/hint_invalid.png", w.Canvas().Capture())
assert.True(t, fd.confirm.Disabled())

validatingEntry.SetText("abc")
test.AssertImageMatches(t, "form/hint_valid.png", w.Canvas().Capture())
assert.False(t, fd.confirm.Disabled())

test.Tap(fd.confirm)
assert.Equal(t, formDialogConfirm, result, "Valid form should be able to be confirmed")

test.Tap(fd.dismiss)
assert.Equal(t, formDialogCancel, result, "Expected cancel result")
}

func validatingFormDialog(result *formDialogResult, parent fyne.Window) *formDialog {
validatingEntry := widget.NewEntry()
validatingEntry.Validator = func(input string) error {
Expand Down Expand Up @@ -129,3 +167,27 @@ func controlFormDialog(result *formDialogResult, parent fyne.Window) *formDialog
}
}, parent).(*formDialog)
}

func hintsFormDialog(result *formDialogResult, parent fyne.Window) *formDialog {
validatingEntry := widget.NewEntry()
validatingEntry.Validator = func(input string) error {
if input != "abc" {
return errors.New("only accepts 'abc'")
}
return nil
}
validatingItem := &widget.FormItem{
Text: "Only accepts 'abc'",
Widget: validatingEntry,
HintText: "Type abc",
}

items := []*widget.FormItem{validatingItem}
return NewForm("Validating Form Dialog With Hints", "Submit", "Cancel", items, func(confirm bool) {
if confirm {
*result = formDialogConfirm
} else {
*result = formDialogCancel
}
}, parent).(*formDialog)
}
Binary file added dialog/testdata/form/hint_initial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dialog/testdata/form/hint_invalid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dialog/testdata/form/hint_valid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1adeb8a

Please sign in to comment.