fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
24.87k stars 1.38k forks source link

Form dialog validation becomes valid if one input field is valid #5006

Open ThomasCode92 opened 2 months ago

ThomasCode92 commented 2 months ago

Checklist

Describe the bug

In Fyne version 2.4.5, the dialog form validation behavior has changed compared to version 2.2.0. In version 2.2.0, the form remains invalid until all input fields are valid. However, in version 2.4.5, the form becomes valid if at least one input field is valid, which is not the expected behavior.

How to reproduce

  1. Create a form with multiple input fields. (dialog.NewForm)
  2. Set up validation for each field.
  3. Run the application using Fyne version 2.4.5.
  4. Observe that the form is marked as valid if at least one input field is valid.

Screenshots

Empty Dialog Form (version 2.4.5) Screenshot from 2024-07-18 08-07-23

Valid Form, with one valid input (version 2.4.5) Screenshot from 2024-07-18 08-07-35

Invalid Form, with on valid input (version 2.2.0) Screenshot from 2024-07-18 08-08-29

Example code

The complete project can be found on my GitHub Page.

The function to create the Dialog Form, in toolbar.go:

func (app *Config) addHoldingsDialog() {
    addAmountEntry := widget.NewEntry()
    purchaseDateEntry := widget.NewEntry()
    purchasePriceEntry := widget.NewEntry()

    app.AddHoldingsPurchaseAmountEntry = addAmountEntry
    app.AddHoldingsPurchaseDateEntry = purchaseDateEntry
    app.AddHoldingsPurchasePriceEntry = purchasePriceEntry

    dateValidator := func(s string) error {
        if _, err := time.Parse("2006-01-02", s); err != nil {
            return err
        }
        return nil
    }
    purchaseDateEntry.Validator = dateValidator

    isIntValidator := func(s string) error {
        if _, err := strconv.Atoi(s); err != nil {
            return err
        }
        return nil
    }
    addAmountEntry.Validator = isIntValidator

    isFloatValidator := func(s string) error {
        if _, err := strconv.ParseFloat(s, 32); err != nil {
            return err
        }
        return nil
    }
    purchasePriceEntry.Validator = isFloatValidator
    purchaseDateEntry.PlaceHolder = "YYYY-MM-DD"

    // create a dialog
    addForm := dialog.NewForm("Add Holding", "Add", "Cancel", []*widget.FormItem{
        {Text: "Amount in toz", Widget: addAmountEntry},
        {Text: "Purchase Price", Widget: purchasePriceEntry},
        {Text: "Purchase Date", Widget: purchaseDateEntry},
    }, func(valid bool) {
        if valid {
            amount, _ := strconv.Atoi(addAmountEntry.Text)
            purchaseDate, _ := time.Parse("2006-01-02", purchaseDateEntry.Text)
            purchasePrice, _ := strconv.ParseFloat(purchasePriceEntry.Text, 32)

            holding := repository.Holdings{Amount: amount, PurchaseDate: purchaseDate, PurchasePrice: int(purchasePrice)}

            _, err := app.DB.InsertHolding(holding)
            if err != nil {
                app.ErrorLog.Println(err)
            }

            app.refreshHoldingsTable()
        }
    }, app.MainWindow)

    //size and show the dialog
    addForm.Resize(fyne.Size{Width: 400})
    addForm.Show()
}

Fyne version

2.4.5

Go compiler version

1.22.4

Operating system and version

Ubuntu 22.04.4 LTS

Additional Information

No response

Jacalz commented 2 months ago

This is a known bug that only affects the form dialog, related to the solution for https://github.com/fyne-io/fyne/issues/4147 apparently triggering some bug inside the .SetOnValidationChanged() handling inside the form widget. I’ve looked into it but haven’t found the underlying reason that it happens. I think it is time to work around this issue until a real fix is in place.

PS: Please provide a simpler code example and not a snippet from another project, per the issue template. Example code should be as simple as possible and a single package main file that can just be copied over and run directly by us maintainers.