messing around with field level validations
This commit is contained in:
parent
ea600bc0fa
commit
d84c8b5552
12 changed files with 89 additions and 42 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
4
h/tag.go
4
h/tag.go
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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" {
|
||||||
|
|
|
||||||
2
justfile
2
justfile
|
|
@ -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
|
||||||
|
|
|
||||||
4
main.go
4
main.go
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package partials
|
package load
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"mhtml/h"
|
"mhtml/h"
|
||||||
"mhtml/partials/sheet"
|
"mhtml/partials/sheet"
|
||||||
"mhtml/ui"
|
"mhtml/ui"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -64,6 +65,31 @@ 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(),
|
||||||
|
|
@ -73,12 +99,14 @@ func addPatientForm() h.Renderable {
|
||||||
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",
|
||||||
|
|
@ -89,6 +117,7 @@ func addPatientForm() h.Renderable {
|
||||||
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",
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
23
ui/input.go
23
ui/input.go
|
|
@ -8,22 +8,35 @@ type InputProps struct {
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue