messing around with field level validations

This commit is contained in:
maddalax 2024-09-12 13:13:15 -05:00
parent ea600bc0fa
commit d84c8b5552
12 changed files with 89 additions and 42 deletions

View file

@ -7,7 +7,7 @@ tmp_dir = "tmp"
bin = "./tmp/main" bin = "./tmp/main"
cmd = "go build -o ./tmp/main ." cmd = "go build -o ./tmp/main ."
delay = 1000 delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"] exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules", "js"]
exclude_file = [] exclude_file = []
exclude_regex = ["_test.go"] exclude_regex = ["_test.go"]
exclude_unchanged = false exclude_unchanged = false

View file

@ -453,6 +453,10 @@ func IfElseLazy(condition bool, cb1 func() Renderable, cb2 func() Renderable) Re
} }
} }
func GetTriggerName(ctx *fiber.Ctx) string {
return ctx.Get("HX-Trigger-Name")
}
func IfHtmxRequest(ctx *fiber.Ctx, node Renderable) Renderable { func IfHtmxRequest(ctx *fiber.Ctx, node Renderable) Renderable {
if ctx.Get("HX-Request") != "" { if ctx.Get("HX-Request") != "" {
return node return node

View file

@ -1,6 +1,6 @@
import * as htmx from "htmx.org"; import * as htmx from "htmx.org";
import "./extensions/pathdeps"; import "./extensions/pathdeps";
import "./extensions/triggerchildren"; import "./extensions/trigger-children";
import "./extensions/debug"; import "./extensions/debug";
declare module "htmx.org" { declare module "htmx.org" {

View file

@ -1,6 +1,6 @@
# Command to run and watch the Go application using Air # Command to run and watch the Go application using Air
run-app: run-app:
air just run-gen && air & just watch-js & just watch-gen
run-gen: run-gen:
go run ./tooling/astgen go run ./tooling/astgen

View file

@ -6,7 +6,7 @@ import (
"log" "log"
"mhtml/h" "mhtml/h"
"mhtml/pages" "mhtml/pages"
"mhtml/partials" "mhtml/partials/load"
"time" "time"
) )
@ -40,7 +40,7 @@ func main() {
return err return err
}) })
partials.RegisterPartials(f) load.RegisterPartials(f)
pages.RegisterPages(f) pages.RegisterPages(f)
h.Start(f, h.App{ h.Start(f, h.App{

View file

@ -1,18 +1,19 @@
// Package partials THIS FILE IS GENERATED. DO NOT EDIT. // Package partials THIS FILE IS GENERATED. DO NOT EDIT.
package partials package load
import "mhtml/h" import "mhtml/h"
import "github.com/gofiber/fiber/v2" import "github.com/gofiber/fiber/v2"
import "mhtml/partials"
import "mhtml/partials/patient" import "mhtml/partials/patient"
import "mhtml/partials/sheet" import "mhtml/partials/sheet"
func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial { func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial {
path := ctx.Path() path := ctx.Path()
if path == "NewsSheet" || path == "/mhtml/partials.NewsSheet" { if path == "NewsSheet" || path == "/mhtml/partials.NewsSheet" {
return NewsSheet(ctx) return partials.NewsSheet(ctx)
} }
if path == "NewsSheetOpenCount" || path == "/mhtml/partials.NewsSheetOpenCount" { if path == "NewsSheetOpenCount" || path == "/mhtml/partials.NewsSheetOpenCount" {
return NewsSheetOpenCount(ctx) return partials.NewsSheetOpenCount(ctx)
} }
if path == "Create" || path == "/mhtml/partials/patient.Create" { if path == "Create" || path == "/mhtml/partials/patient.Create" {
return patient.Create(ctx) return patient.Create(ctx)
@ -23,6 +24,9 @@ func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial {
if path == "AddPatientSheetPartial" || path == "/mhtml/partials/patient.AddPatientSheetPartial" { if path == "AddPatientSheetPartial" || path == "/mhtml/partials/patient.AddPatientSheetPartial" {
return patient.AddPatientSheetPartial(ctx) return patient.AddPatientSheetPartial(ctx)
} }
if path == "ValidateForm" || path == "/mhtml/partials/patient.ValidateForm" {
return patient.ValidateForm(ctx)
}
if path == "Close" || path == "/mhtml/partials/sheet.Close" { if path == "Close" || path == "/mhtml/partials/sheet.Close" {
return sheet.Close(ctx) return sheet.Close(ctx)
} }

View file

@ -1,4 +1,4 @@
package partials package load
import ( import (
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"

View file

@ -6,6 +6,7 @@ import (
"mhtml/h" "mhtml/h"
"mhtml/partials/sheet" "mhtml/partials/sheet"
"mhtml/ui" "mhtml/ui"
"strings"
"time" "time"
) )
@ -64,21 +65,48 @@ func AddPatientSheet(onClosePath string) h.Renderable {
}) })
} }
func ValidateForm(ctx *fiber.Ctx) *h.Partial {
trigger := h.GetTriggerName(ctx)
value := ctx.FormValue(trigger)
if trigger == "name" {
if strings.ToLower(value) == "sydne" {
return h.NewPartial(h.P("that name is reserved"))
}
}
if trigger == "reason-for-visit" {
if strings.ToLower(value) == "arm hurts" {
return h.NewPartial(h.P("lol that reason is fake"))
}
}
if trigger == "location-name" {
if strings.ToLower(value) == "hospital" {
return h.NewPartial(h.P("that location is reserved"))
}
}
return h.NewPartial(h.Fragment())
}
func addPatientForm() h.Renderable { func addPatientForm() h.Renderable {
return h.Form( return h.Form(
h.TriggerChildren(), h.TriggerChildren(),
h.Post(h.GetPartialPath(Create)), h.Post(h.GetPartialPath(Create)),
h.Class("flex flex-col gap-2"), h.Class("flex flex-col gap-2"),
ui.Input(ui.InputProps{ ui.Input(ui.InputProps{
Type: "text", Type: "text",
Label: "Name", Label: "Name",
Name: "name", Name: "name",
DefaultValue: "fart", DefaultValue: "",
ValidationPath: h.GetPartialPath(ValidateForm),
}), }),
ui.Input(ui.InputProps{ ui.Input(ui.InputProps{
Type: "text", Type: "text",
Label: "Reason for visit", Label: "Reason for visit",
Name: "reason-for-visit", Name: "reason-for-visit",
ValidationPath: h.GetPartialPath(ValidateForm),
}), }),
ui.Input(ui.InputProps{ ui.Input(ui.InputProps{
Type: "date", Type: "date",
@ -86,9 +114,10 @@ func addPatientForm() h.Renderable {
Name: "appointment-date", Name: "appointment-date",
}), }),
ui.Input(ui.InputProps{ ui.Input(ui.InputProps{
Type: "text", Type: "text",
Label: "Location Name", Label: "Location Name",
Name: "location-name", Name: "location-name",
ValidationPath: h.GetPartialPath(ValidateForm),
}), }),
ui.PrimaryButton(ui.ButtonProps{ ui.PrimaryButton(ui.ButtonProps{
Text: "Add Patient", Text: "Add Patient",

View file

@ -195,11 +195,6 @@ func buildGetPartialFromContext(builder *CodeBuilder, partials []Partial) {
caller := fmt.Sprintf("%s.%s", f.Package, f.FuncName) caller := fmt.Sprintf("%s.%s", f.Package, f.FuncName)
path := fmt.Sprintf("/mhtml/%s.%s", f.Import, f.FuncName) path := fmt.Sprintf("/mhtml/%s.%s", f.Import, f.FuncName)
if f.Package == "partials" {
caller = f.FuncName
path = fmt.Sprintf("/mhtml/partials.%s", f.FuncName)
}
body += fmt.Sprintf(` body += fmt.Sprintf(`
if path == "%s" || path == "%s" { if path == "%s" || path == "%s" {
return %s(ctx) return %s(ctx)
@ -234,19 +229,21 @@ func writePartialsFile() {
builder := NewCodeBuilder(nil) builder := NewCodeBuilder(nil)
builder.AppendLine(`// Package partials THIS FILE IS GENERATED. DO NOT EDIT.`) builder.AppendLine(`// Package partials THIS FILE IS GENERATED. DO NOT EDIT.`)
builder.AppendLine("package partials") builder.AppendLine("package load")
builder.AddImport("mhtml/h") builder.AddImport("mhtml/h")
builder.AddImport("github.com/gofiber/fiber/v2") builder.AddImport("github.com/gofiber/fiber/v2")
for _, partial := range partials { for _, partial := range partials {
if partial.Import != "partials" { if partial.Import == "partials/load" {
builder.AddImport(fmt.Sprintf(`mhtml/%s`, partial.Import)) continue
} }
fmt.Println(partial.Import)
builder.AddImport(fmt.Sprintf(`mhtml/%s`, partial.Import))
} }
buildGetPartialFromContext(builder, partials) buildGetPartialFromContext(builder, partials)
WriteFile(filepath.Join("partials", "generated.go"), func(content *ast.File) string { WriteFile(filepath.Join("partials", "load", "generated.go"), func(content *ast.File) string {
return builder.String() return builder.String()
}) })
} }

View file

@ -43,7 +43,7 @@ func WriteFile(path string, cb func(content *ast.File) string) {
} }
bytes = []byte(cb(f)) bytes = []byte(cb(f))
formatEnabled := false formatEnabled := true
if formatEnabled { if formatEnabled {
bytes, err = format.Source(bytes) bytes, err = format.Source(bytes)

View file

@ -3,27 +3,40 @@ package ui
import "mhtml/h" import "mhtml/h"
type InputProps struct { type InputProps struct {
Id string Id string
Label string Label string
Name string Name string
Type string Type string
DefaultValue string DefaultValue string
ValidationPath string
Childen []h.Renderable
} }
func Input(props InputProps) h.Renderable { func Input(props InputProps) h.Renderable {
validation := h.If(props.ValidationPath != "", h.Children(
h.Post(props.ValidationPath),
h.Trigger("change"),
h.Attribute("hx-swap", "innerHTML transition:true"),
h.Attribute("hx-target", "next div"),
))
input := h.Input( input := h.Input(
props.Type, props.Type,
h.Class("border p-2 rounded"), h.Class("border p-2 rounded"),
h.If(props.Id != "", h.Id(props.Id)), h.If(props.Id != "", h.Id(props.Id)),
h.If(props.Name != "", h.Name(props.Name)), h.If(props.Name != "", h.Name(props.Name)),
h.If(props.Childen != nil, h.Children(props.Childen...)),
h.If(props.DefaultValue != "", h.Attribute("value", props.DefaultValue)), h.If(props.DefaultValue != "", h.Attribute("value", props.DefaultValue)),
validation,
) )
if props.Label != "" {
return h.Div( wrapped := h.Div(
h.Class("flex flex-col gap-1"), h.Class("flex flex-col gap-1"),
h.Label(props.Label), h.If(props.Label != "", h.Label(props.Label)),
input, input,
) h.Div(h.Class("text-red-500")),
} )
return input
return wrapped
} }