diff --git a/examples/credit-card-form/main.go b/examples/credit-card-form/main.go index e40de7d215..f4a9293654 100644 --- a/examples/credit-card-form/main.go +++ b/examples/credit-card-form/main.go @@ -3,6 +3,8 @@ package main import ( "fmt" "log" + "strconv" + "strings" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" @@ -42,6 +44,55 @@ type model struct { err error } +// Validator functions to ensure valid input +func ccnValidator(s string) error { + // Credit Card Number should a string less than 20 digits + // It should include 16 integers and 3 spaces + if len(s) > 16+3 { + return fmt.Errorf("CCN is too long") + } + + // The last digit should be a number unless it is a multiple of 4 in which + // case it should be a space + if len(s)%5 == 0 && s[len(s)-1] != ' ' { + return fmt.Errorf("CCN must separate groups with spaces") + } + if len(s)%5 != 0 && (s[len(s)-1] < '0' || s[len(s)-1] > '9') { + return fmt.Errorf("CCN is invalid") + } + + // The remaining digits should be integers + c := strings.ReplaceAll(s, " ", "") + _, err := strconv.ParseInt(c, 10, 64) + + return err +} + +func expValidator(s string) error { + // The 3 character should be a slash (/) + // The rest thould be numbers + e := strings.ReplaceAll(s, "/", "") + _, err := strconv.ParseInt(e, 10, 64) + if err != nil { + return fmt.Errorf("EXP is invalid") + } + + // There should be only one slash and it should be in the 2nd index (3rd character) + if len(s) >= 3 && (strings.Index(s, "/") != 2 || strings.LastIndex(s, "/") != 2) { + return fmt.Errorf("EXP is invalid") + } + + return nil +} + +func cvvValidator(s string) error { + // The CVV should be a number of 3 digits + // Since the input will already ensure that the CVV is a string of length 3, + // All we need to do is check that it is a number + _, err := strconv.ParseInt(s, 10, 64) + return err +} + func initialModel() model { var inputs []textinput.Model = make([]textinput.Model, 3) inputs[ccn] = textinput.New() @@ -50,18 +101,21 @@ func initialModel() model { inputs[ccn].CharLimit = 20 inputs[ccn].Width = 30 inputs[ccn].Prompt = "" + inputs[ccn].Validate = ccnValidator inputs[exp] = textinput.New() inputs[exp].Placeholder = "MM/YY " inputs[exp].CharLimit = 5 inputs[exp].Width = 5 inputs[exp].Prompt = "" + inputs[exp].Validate = expValidator inputs[cvv] = textinput.New() inputs[cvv].Placeholder = "XXX" inputs[cvv].CharLimit = 3 inputs[cvv].Width = 5 inputs[cvv].Prompt = "" + inputs[cvv].Validate = cvvValidator return model{ inputs: inputs, diff --git a/examples/go.mod b/examples/go.mod index 7851f35f21..54d3cc6a7e 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,7 +3,7 @@ module examples go 1.13 require ( - github.com/charmbracelet/bubbles v0.11.0 + github.com/charmbracelet/bubbles v0.11.1-0.20220610161724-e57fd292cc68 github.com/charmbracelet/bubbletea v0.21.0 github.com/charmbracelet/glamour v0.5.0 github.com/charmbracelet/lipgloss v0.5.0 diff --git a/examples/go.sum b/examples/go.sum index 19af6250a3..b5de6a0084 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -6,6 +6,8 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/charmbracelet/bubbles v0.11.0 h1:fBLyY0PvJnd56Vlu5L84JJH6f4axhgIJ9P3NET78f0Q= github.com/charmbracelet/bubbles v0.11.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= +github.com/charmbracelet/bubbles v0.11.1-0.20220610161724-e57fd292cc68 h1:oDxdCcM/JreVa7RTt2NQLdp06PwkApSL3huTwrOl/ww= +github.com/charmbracelet/bubbles v0.11.1-0.20220610161724-e57fd292cc68/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= github.com/charmbracelet/glamour v0.5.0 h1:wu15ykPdB7X6chxugG/NNfDUbyyrCLV9XBalj5wdu3g= github.com/charmbracelet/glamour v0.5.0/go.mod h1:9ZRtG19AUIzcTm7FGLGbq3D5WKQ5UyZBbQsMQN0XIqc= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=