• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fyne-io / fyne / 15043757579

15 May 2025 10:25AM UTC coverage: 62.358% (+0.01%) from 62.346%
15043757579

Pull #5741

github

jimorc
Support form validation of widgets other than Entry

Add FormValidatable interface definition. Modify Entry to implement interface.
Modify Form to validate widgets that implement FormValidatable interface.
This removes Entry specific code from Form.
Pull Request #5741: Support form validation of widgets other than Entry

30 of 33 new or added lines in 4 files covered. (90.91%)

4 existing lines in 1 file now uncovered.

25151 of 40333 relevant lines covered (62.36%)

718.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/widget/date_entry.go
1
package widget
2

3
import (
4
        "time"
5

6
        "fyne.io/fyne/v2"
7
        "fyne.io/fyne/v2/theme"
8
)
9

10
// DateEntry is an input field which supports selecting from a fixed set of options.
11
//
12
// Since: 2.6
13
type DateEntry struct {
14
        Entry
15
        Date      *time.Time
16
        OnChanged func(*time.Time) `json:"-"`
17

18
        dropDown *Calendar
19
        popUp    *PopUp
20
}
21

22
// NewDateEntry creates a date input where the date can be selected or typed.
23
//
24
// Since: 2.6
25
func NewDateEntry() *DateEntry {
×
26
        e := &DateEntry{}
×
27
        e.ExtendBaseWidget(e)
×
28
        e.Wrapping = fyne.TextWrap(fyne.TextTruncateClip)
×
29
        return e
×
30
}
×
31

32
// CreateRenderer returns a new renderer for this select entry.
33
//
34
// Implements: fyne.Widget
35
func (e *DateEntry) CreateRenderer() fyne.WidgetRenderer {
×
36
        e.ExtendBaseWidget(e)
×
37

×
38
        dateFormat := getLocaleDateFormat()
×
NEW
39
        e.SetValidator(func(in string) error {
×
40
                _, err := time.Parse(dateFormat, in)
×
41
                return err
×
NEW
42
        })
×
43
        e.Entry.OnChanged = func(in string) {
×
44
                if in == "" {
×
45
                        e.Date = nil
×
46

×
47
                        if f := e.OnChanged; f != nil {
×
48
                                f(nil)
×
49
                        }
×
50
                }
51
                t, err := time.Parse(dateFormat, in)
×
52
                if err != nil {
×
53
                        return
×
54
                }
×
55

56
                e.Date = &t
×
57

×
58
                if f := e.OnChanged; f != nil {
×
59
                        f(&t)
×
60
                }
×
61
        }
62

63
        if e.ActionItem == nil {
×
64
                e.ActionItem = e.setupDropDown()
×
65
                if e.Disabled() {
×
66
                        e.ActionItem.(fyne.Disableable).Disable()
×
67
                }
×
68
        }
69

70
        return e.Entry.CreateRenderer()
×
71
}
72

73
// Enable this widget, updating any style or features appropriately.
74
//
75
// Implements: fyne.DisableableWidget
76
func (e *DateEntry) Enable() {
×
77
        if e.ActionItem != nil {
×
78
                if d, ok := e.ActionItem.(fyne.Disableable); ok {
×
79
                        d.Enable()
×
80
                }
×
81
        }
82
        e.Entry.Enable()
×
83
}
84

85
// Disable this widget so that it cannot be interacted with, updating any style appropriately.
86
//
87
// Implements: fyne.DisableableWidget
88
func (e *DateEntry) Disable() {
×
89
        if e.ActionItem != nil {
×
90
                if d, ok := e.ActionItem.(fyne.Disableable); ok {
×
91
                        d.Disable()
×
92
                }
×
93
        }
94
        e.Entry.Disable()
×
95
}
96

97
// MinSize returns the minimal size of the select entry.
98
//
99
// Implements: fyne.Widget
100
func (e *DateEntry) MinSize() fyne.Size {
×
101
        e.ExtendBaseWidget(e)
×
102
        return e.Entry.MinSize()
×
103
}
×
104

105
// Move changes the relative position of the date entry.
106
//
107
// Implements: fyne.Widget
108
func (e *DateEntry) Move(pos fyne.Position) {
×
109
        e.Entry.Move(pos)
×
110
        if e.popUp != nil {
×
111
                e.popUp.Move(e.popUpPos())
×
112
        }
×
113
}
114

115
// Resize changes the size of the date entry.
116
//
117
// Implements: fyne.Widget
118
func (e *DateEntry) Resize(size fyne.Size) {
×
119
        e.Entry.Resize(size)
×
120
        if e.popUp != nil {
×
121
                e.popUp.Resize(fyne.NewSize(size.Width, e.popUp.Size().Height))
×
122
        }
×
123
}
124

125
// SetDate will update the widget to a specific date.
126
// You can pass nil to unselect a date.
127
func (e *DateEntry) SetDate(d *time.Time) {
×
128
        if d == nil {
×
129
                e.Date = nil
×
130
                e.Entry.SetText("")
×
131

×
132
                return
×
133
        }
×
134

135
        e.setDate(*d)
×
136
}
137

138
func (e *DateEntry) popUpPos() fyne.Position {
×
139
        entryPos := fyne.CurrentApp().Driver().AbsolutePositionForObject(e.super())
×
140
        return entryPos.Add(fyne.NewPos(0, e.Size().Height-e.Theme().Size(theme.SizeNameInputBorder)))
×
141
}
×
142

143
func (e *DateEntry) setDate(d time.Time) {
×
144
        e.Date = &d
×
145
        if e.popUp != nil {
×
146
                e.popUp.Hide()
×
147
        }
×
148

149
        e.Entry.SetText(d.Format(getLocaleDateFormat()))
×
150
}
151

152
func (e *DateEntry) setupDropDown() *Button {
×
153
        if e.dropDown == nil {
×
154
                e.dropDown = NewCalendar(time.Now(), e.setDate)
×
155
        }
×
156
        dropDownButton := NewButton("", func() {
×
157
                c := fyne.CurrentApp().Driver().CanvasForObject(e.super())
×
158

×
159
                e.popUp = NewPopUp(e.dropDown, c)
×
160
                e.popUp.ShowAtPosition(e.popUpPos())
×
161
                e.popUp.Resize(fyne.NewSize(e.Size().Width, e.popUp.MinSize().Height))
×
162
        })
×
163
        dropDownButton.Importance = LowImportance
×
164
        dropDownButton.SetIcon(e.Theme().Icon(theme.IconNameCalendar))
×
165
        return dropDownButton
×
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc