mirror of
https://github.com/rivo/tview.git
synced 2024-11-15 06:12:46 +00:00
Add FormItem field validation
This commit is contained in:
parent
06a95af2a2
commit
733e0871e4
@ -228,6 +228,11 @@ EventLoop:
|
|||||||
a.Stop()
|
a.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow a validation to short-circuit input handling
|
||||||
|
if !a.ValidatePrimitive(p, event) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Pass other key events to the currently focused primitive.
|
// Pass other key events to the currently focused primitive.
|
||||||
if p != nil {
|
if p != nil {
|
||||||
if handler := p.InputHandler(); handler != nil {
|
if handler := p.InputHandler(); handler != nil {
|
||||||
@ -503,3 +508,52 @@ func (a *Application) QueueEvent(event tcell.Event) *Application {
|
|||||||
a.events <- event
|
a.events <- event
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidatePrimitive will call a validation function specific to
|
||||||
|
// a FormItem set using the SetValidateFunc() methods when one of
|
||||||
|
// the field exit keys — Enter, Tab, Backtab, or Escape — is used.
|
||||||
|
// If the validation function returns false the focus will stay on
|
||||||
|
// the non-valid form field.
|
||||||
|
func (a *Application) ValidatePrimitive(p Primitive, event *tcell.EventKey) bool {
|
||||||
|
switch event.Key() {
|
||||||
|
case tcell.KeyEnter, tcell.KeyTab, tcell.KeyBacktab, tcell.KeyEscape:
|
||||||
|
// We will check validation below
|
||||||
|
default:
|
||||||
|
// No need to check
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch p.(type) {
|
||||||
|
case *InputField:
|
||||||
|
i := p.(*InputField)
|
||||||
|
if i.valid == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return i.valid(i, event)
|
||||||
|
|
||||||
|
case *DropDown:
|
||||||
|
dd := p.(*DropDown)
|
||||||
|
if dd.valid == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return dd.valid(dd, event)
|
||||||
|
|
||||||
|
case *Checkbox:
|
||||||
|
cb := p.(*Checkbox)
|
||||||
|
if cb.valid == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return cb.valid(cb, event)
|
||||||
|
|
||||||
|
default:
|
||||||
|
b, ok := p.(*Box)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if b.valid == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return b.valid(p, event)
|
||||||
|
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
13
box.go
13
box.go
@ -58,6 +58,11 @@ type Box struct {
|
|||||||
|
|
||||||
// An optional function which is called before the box is drawn.
|
// An optional function which is called before the box is drawn.
|
||||||
draw func(screen tcell.Screen, x, y, width, height int) (int, int, int, int)
|
draw func(screen tcell.Screen, x, y, width, height int) (int, int, int, int)
|
||||||
|
|
||||||
|
// A callback function to be called when one of the field exit keys — Enter,
|
||||||
|
// Tab, Backtab, or Escape — is used. If this callback returns false it will
|
||||||
|
// bypass the input handler and leave the focus on the non-valid field.
|
||||||
|
valid func(Primitive, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBox returns a Box without a border.
|
// NewBox returns a Box without a border.
|
||||||
@ -231,6 +236,14 @@ func (b *Box) SetTitleAlign(align int) *Box {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetValidateFunc sets a callback to be called when one of the field exit keys —
|
||||||
|
// Enter, Tab, Backtab, or Escape — is used. If this callback returns false it
|
||||||
|
// will stop the input handler from moving focus to a different field.
|
||||||
|
func (b *Box) SetValidateFunc(handler func(Primitive, *tcell.EventKey) bool) *Box {
|
||||||
|
b.valid = handler
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
func (b *Box) Draw(screen tcell.Screen) {
|
func (b *Box) Draw(screen tcell.Screen) {
|
||||||
// Don't draw anything if there is no space.
|
// Don't draw anything if there is no space.
|
||||||
|
24
checkbox.go
24
checkbox.go
@ -42,6 +42,11 @@ type Checkbox struct {
|
|||||||
// A callback function set by the Form class and called when the user leaves
|
// A callback function set by the Form class and called when the user leaves
|
||||||
// this form item.
|
// this form item.
|
||||||
finished func(tcell.Key)
|
finished func(tcell.Key)
|
||||||
|
|
||||||
|
// A callback function to be called when one of the field exit keys — Enter,
|
||||||
|
// Tab, Backtab, or Escape — is used. If this callback returns false it will
|
||||||
|
// bypass the input handler and leave the focus on the non-valid field.
|
||||||
|
valid func(*Checkbox, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCheckbox returns a new input field.
|
// NewCheckbox returns a new input field.
|
||||||
@ -142,6 +147,14 @@ func (c *Checkbox) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetValidateFunc sets a callback to be called when one of the field exit keys —
|
||||||
|
// Enter, Tab, Backtab, or Escape — is used. If this callback returns false it
|
||||||
|
// will stop the input handler from moving focus to a different field.
|
||||||
|
func (c *Checkbox) SetValidateFunc(handler func(*Checkbox, *tcell.EventKey) bool) *Checkbox {
|
||||||
|
c.valid = handler
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
func (c *Checkbox) Draw(screen tcell.Screen) {
|
func (c *Checkbox) Draw(screen tcell.Screen) {
|
||||||
c.Box.Draw(screen)
|
c.Box.Draw(screen)
|
||||||
@ -254,11 +267,16 @@ type CheckboxArgs struct {
|
|||||||
// returns the event to be forwarded to the primitive's default
|
// returns the event to be forwarded to the primitive's default
|
||||||
// input handler (nil if nothing should be forwarded).
|
// input handler (nil if nothing should be forwarded).
|
||||||
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
||||||
|
|
||||||
|
// A callback function to be called when one of the field exit keys — Enter,
|
||||||
|
// Tab, Backtab, or Escape — is used. If this callback returns false it will
|
||||||
|
// bypass the input handler and leave the focus on the non-valid field.
|
||||||
|
ValidateFunc func(*Checkbox, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyArgs applies the values from a CheckboxArgs{} struct to the
|
// ApplyArgs applies the values from a CheckboxArgs{} struct to the
|
||||||
// associated properties of the Checkbox.
|
// associated properties of the Checkbox.
|
||||||
func (c *Checkbox) ApplyArgs(args *CheckboxArgs) *Checkbox{
|
func (c *Checkbox) ApplyArgs(args *CheckboxArgs) *Checkbox {
|
||||||
|
|
||||||
c.SetLabel(args.Label)
|
c.SetLabel(args.Label)
|
||||||
c.SetChecked(args.Checked)
|
c.SetChecked(args.Checked)
|
||||||
@ -288,9 +306,11 @@ func (c *Checkbox) ApplyArgs(args *CheckboxArgs) *Checkbox{
|
|||||||
if args.FinishedFunc != nil {
|
if args.FinishedFunc != nil {
|
||||||
c.SetFinishedFunc(args.FinishedFunc)
|
c.SetFinishedFunc(args.FinishedFunc)
|
||||||
}
|
}
|
||||||
|
if args.ValidateFunc != nil {
|
||||||
|
c.SetValidateFunc(args.ValidateFunc)
|
||||||
|
}
|
||||||
if args.InputCaptureFunc != nil {
|
if args.InputCaptureFunc != nil {
|
||||||
c.SetInputCapture(args.InputCaptureFunc)
|
c.SetInputCapture(args.InputCaptureFunc)
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
dropdown.go
20
dropdown.go
@ -70,6 +70,11 @@ type DropDown struct {
|
|||||||
// A callback function which is called when the user changes the drop-down's
|
// A callback function which is called when the user changes the drop-down's
|
||||||
// selection.
|
// selection.
|
||||||
selected func(text string, index int)
|
selected func(text string, index int)
|
||||||
|
|
||||||
|
// A callback function to be called when one of the field exit keys — Enter,
|
||||||
|
// Tab, Backtab, or Escape — is used. If this callback returns false it will
|
||||||
|
// bypass the input handler and leave the focus on the non-valid field.
|
||||||
|
valid func(*DropDown, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDropDown returns a new drop-down.
|
// NewDropDown returns a new drop-down.
|
||||||
@ -256,6 +261,14 @@ func (d *DropDown) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetValidateFunc sets a callback to be called when one of the field exit keys —
|
||||||
|
// Enter, Tab, Backtab, or Escape — is used. If this callback returns false it
|
||||||
|
// will stop the input handler from moving focus to a different field.
|
||||||
|
func (d *DropDown) SetValidateFunc(handler func(*DropDown, *tcell.EventKey) bool) *DropDown {
|
||||||
|
d.valid = handler
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
func (d *DropDown) Draw(screen tcell.Screen) {
|
func (d *DropDown) Draw(screen tcell.Screen) {
|
||||||
d.Box.Draw(screen)
|
d.Box.Draw(screen)
|
||||||
@ -499,8 +512,10 @@ type DropDownArgs struct {
|
|||||||
// returns the event to be forwarded to the primitive's default
|
// returns the event to be forwarded to the primitive's default
|
||||||
// input handler (nil if nothing should be forwarded).
|
// input handler (nil if nothing should be forwarded).
|
||||||
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
||||||
}
|
|
||||||
|
|
||||||
|
// An optional function which is called before the box is drawn.
|
||||||
|
ValidateFunc func(*DropDown, *tcell.EventKey) bool
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyArgs applies the values from a DropDownArgs{} struct to the
|
// ApplyArgs applies the values from a DropDownArgs{} struct to the
|
||||||
// associated properties of the DropDown.
|
// associated properties of the DropDown.
|
||||||
@ -537,6 +552,9 @@ func (d *DropDown) ApplyArgs(args *DropDownArgs) *DropDown {
|
|||||||
if args.FinishedFunc != nil {
|
if args.FinishedFunc != nil {
|
||||||
d.SetFinishedFunc(args.FinishedFunc)
|
d.SetFinishedFunc(args.FinishedFunc)
|
||||||
}
|
}
|
||||||
|
if args.ValidateFunc != nil {
|
||||||
|
d.SetValidateFunc(args.ValidateFunc)
|
||||||
|
}
|
||||||
if args.InputCaptureFunc != nil {
|
if args.InputCaptureFunc != nil {
|
||||||
d.SetInputCapture(args.InputCaptureFunc)
|
d.SetInputCapture(args.InputCaptureFunc)
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,11 @@ type InputField struct {
|
|||||||
// A callback function set by the Form class and called when the user leaves
|
// A callback function set by the Form class and called when the user leaves
|
||||||
// this form item.
|
// this form item.
|
||||||
finished func(tcell.Key)
|
finished func(tcell.Key)
|
||||||
|
|
||||||
|
// A callback function to be called when one of the field exit keys — Enter,
|
||||||
|
// Tab, Backtab, or Escape — is used. If this callback returns false it will
|
||||||
|
// bypass the input handler and leave the focus on the non-valid field.
|
||||||
|
valid func(*InputField, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputField returns a new input field.
|
// NewInputField returns a new input field.
|
||||||
@ -226,6 +231,14 @@ func (i *InputField) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetValidateFunc sets a callback to be called when one of the field exit keys —
|
||||||
|
// Enter, Tab, Backtab, or Escape — is used. If this callback returns false it
|
||||||
|
// will stop the input handler from moving focus to a different field.
|
||||||
|
func (i *InputField) SetValidateFunc(handler func(*InputField, *tcell.EventKey) bool) *InputField {
|
||||||
|
i.valid = handler
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
func (i *InputField) Draw(screen tcell.Screen) {
|
func (i *InputField) Draw(screen tcell.Screen) {
|
||||||
i.Box.Draw(screen)
|
i.Box.Draw(screen)
|
||||||
@ -507,6 +520,9 @@ type InputFieldArgs struct {
|
|||||||
// returns the event to be forwarded to the primitive's default
|
// returns the event to be forwarded to the primitive's default
|
||||||
// input handler (nil if nothing should be forwarded).
|
// input handler (nil if nothing should be forwarded).
|
||||||
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
||||||
|
|
||||||
|
// An optional function which is called before the box is drawn.
|
||||||
|
ValidateFunc func(*InputField, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyArgs applies the values from a InputFieldArgs{} or PasswordFieldArgs{}
|
// ApplyArgs applies the values from a InputFieldArgs{} or PasswordFieldArgs{}
|
||||||
@ -563,10 +579,11 @@ func (i *InputField) applyInputFieldArgs(args *InputFieldArgs) *InputField {
|
|||||||
if args.FinishedFunc != nil {
|
if args.FinishedFunc != nil {
|
||||||
i.SetFinishedFunc(args.FinishedFunc)
|
i.SetFinishedFunc(args.FinishedFunc)
|
||||||
}
|
}
|
||||||
|
if args.ValidateFunc != nil {
|
||||||
|
i.SetValidateFunc(args.ValidateFunc)
|
||||||
|
}
|
||||||
if args.InputCaptureFunc != nil {
|
if args.InputCaptureFunc != nil {
|
||||||
i.SetInputCapture(args.InputCaptureFunc)
|
i.SetInputCapture(args.InputCaptureFunc)
|
||||||
}
|
}
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,6 +64,9 @@ type PasswordFieldArgs struct {
|
|||||||
// returns the event to be forwarded to the primitive's default
|
// returns the event to be forwarded to the primitive's default
|
||||||
// input handler (nil if nothing should be forwarded).
|
// input handler (nil if nothing should be forwarded).
|
||||||
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
InputCaptureFunc func(event *tcell.EventKey) *tcell.EventKey
|
||||||
|
|
||||||
|
// An optional function which is called before the box is drawn.
|
||||||
|
ValidateFunc func(*InputField, *tcell.EventKey) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyPasswordFieldArgs applies the values from a PasswordFieldArgs{}
|
// applyPasswordFieldArgs applies the values from a PasswordFieldArgs{}
|
||||||
@ -99,9 +102,11 @@ func (i *InputField) applyPasswordFieldArgs(args *PasswordFieldArgs) *InputField
|
|||||||
if args.FinishedFunc != nil {
|
if args.FinishedFunc != nil {
|
||||||
i.SetFinishedFunc(args.FinishedFunc)
|
i.SetFinishedFunc(args.FinishedFunc)
|
||||||
}
|
}
|
||||||
|
if args.ValidateFunc != nil {
|
||||||
|
i.SetValidateFunc(args.ValidateFunc)
|
||||||
|
}
|
||||||
if args.InputCaptureFunc != nil {
|
if args.InputCaptureFunc != nil {
|
||||||
i.SetInputCapture(args.InputCaptureFunc)
|
i.SetInputCapture(args.InputCaptureFunc)
|
||||||
}
|
}
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
validation.go
Normal file
7
validation.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package tview
|
||||||
|
|
||||||
|
import "github.com/gdamore/tcell"
|
||||||
|
|
||||||
|
type PrimitiveValidationHandler interface {
|
||||||
|
Validate(p Primitive, key *tcell.EventKey) bool
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user