fix todo mvc

This commit is contained in:
maddalax 2024-09-21 12:08:23 -05:00
parent da7e22c446
commit 1f98f49735
6 changed files with 57 additions and 55 deletions

View file

@ -8,8 +8,6 @@ import (
"strings"
)
type Headers = map[string]string
type Partial struct {
Headers *Headers
Root *Element
@ -51,6 +49,13 @@ func NewPartial(root *Element) *Partial {
}
}
func SwapManyPartialWithHeaders(ctx *RequestContext, headers *Headers, swaps ...*Element) *Partial {
return NewPartialWithHeaders(
headers,
SwapMany(ctx, swaps...),
)
}
func SwapManyPartial(ctx *RequestContext, swaps ...*Element) *Partial {
return NewPartial(
SwapMany(ctx, swaps...),

View file

@ -5,10 +5,16 @@ import (
"net/url"
)
type Headers = map[string]string
func ReplaceUrlHeader(url string) *Headers {
return NewHeaders(hx.ReplaceUrlHeader, url)
}
func PushUrlHeader(url string) *Headers {
return NewHeaders(hx.PushUrlHeader, url)
}
func CombineHeaders(headers ...*Headers) *Headers {
m := make(Headers)
for _, h := range headers {

View file

@ -90,28 +90,10 @@ func (m *AttributeMap) Render(builder *strings.Builder) {
}
}
func toHtmxTriggerName(event string) string {
if strings.HasPrefix(event, "htmx:") {
return event[5:]
}
if strings.HasPrefix(event, "on") {
return event[2:]
}
return event
}
func formatEventName(event string, isDomEvent bool) string {
raw := toHtmxTriggerName(event)
if isDomEvent {
return "on" + raw
}
return event
}
func (l *LifeCycle) fromAttributeMap(event string, key string, value string, builder *strings.Builder) {
if key == hx.GetAttr || key == hx.PatchAttr || key == hx.PostAttr {
TriggerString(toHtmxTriggerName(event)).Render(builder)
TriggerString(hx.ToHtmxTriggerName(event)).Render(builder)
}
Attribute(key, value).Render(builder)
@ -125,7 +107,7 @@ func (l *LifeCycle) Render(builder *strings.Builder) {
for _, command := range commands {
switch c := command.(type) {
case JsCommand:
eventName := formatEventName(event, true)
eventName := hx.FormatEventName(event, true)
m[eventName] += fmt.Sprintf("%s;", c.Command)
case *AttributeMap:
for k, v := range c.ToMap() {

View file

@ -13,11 +13,32 @@ type TriggerEvent struct {
modifiers []Modifier
}
func ToHtmxTriggerName(event string) string {
if strings.HasPrefix(event, "htmx:") {
return event[5:]
}
if strings.HasPrefix(event, "on") {
return event[2:]
}
return event
}
func FormatEventName(event string, isDomEvent bool) string {
raw := ToHtmxTriggerName(event)
if isDomEvent {
return "on" + raw
}
return event
}
func NewTrigger(opts ...TriggerEvent) *Trigger {
t := Trigger{
events: make([]TriggerEvent, 0),
}
if len(opts) > 0 {
for i, opt := range opts {
opts[i].event = ToHtmxTriggerName(opt.event)
}
t.events = opts
}
return &t
@ -31,11 +52,7 @@ func NewStringTrigger(trigger string) Trigger {
split := strings.Split(trigger, ", ")
for _, s := range split {
parts := strings.Split(s, " ")
event := parts[0]
if strings.HasPrefix(event, "htmx:") {
event = event[5:]
}
event := ToHtmxTriggerName(parts[0])
modifiers := make([]Modifier, 0)
if len(parts) > 1 {

View file

@ -11,15 +11,6 @@ import (
"todolist/partials/load"
)
type CustomContext struct {
echo.Context
locator *service.Locator
}
func (c *CustomContext) ServiceLocator() *service.Locator {
return c.locator
}
func main() {
locator := service.NewLocator()

View file

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/google/uuid"
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/hx"
"todolist/ent"
"todolist/internal/tasks"
)
@ -55,7 +56,7 @@ func Input(list []*ent.Task) *h.Element {
h.Class("pl-12 text-xl p-4 w-full outline-none focus:outline-2 focus:outline-rose-400"),
h.Placeholder("What needs to be done?"),
h.Post(h.GetPartialPath(Create)),
h.HxTrigger("keyup[keyCode==13]"),
h.HxTrigger(hx.OnEvent(hx.TriggerKeyUpEnter)),
),
CompleteAllIcon(list),
)
@ -70,7 +71,7 @@ func CompleteAllIcon(list []*ent.Task) *h.Element {
h.ClassX("absolute top-0 left-0 p-4 rotate-90 text-2xl cursor-pointer", map[string]bool{
"text-slate-400": notCompletedCount > 0,
}), h.Text(""),
h.PostPartialOnClickQs(CompleteAll, h.Ternary(notCompletedCount > 0, "complete=true", "complete=false")),
h.PostPartialWithQs(CompleteAll, h.NewQs("complete", h.Ternary(notCompletedCount > 0, "true", "false"))),
)
}
@ -92,7 +93,7 @@ func Footer(list []*ent.Task, activeTab Tab) *h.Element {
h.Class("flex items-center gap-4"),
h.List(tabs, func(tab Tab, index int) *h.Element {
return h.P(
h.PostOnClick(h.GetPartialPathWithQs(ChangeTab, "tab="+tab)),
h.PostOnClick(h.GetPartialPathWithQs(ChangeTab, h.NewQs("tab", tab))),
h.ClassX("cursor-pointer px-2 py-1 rounded", map[string]bool{
"border border-rose-600": activeTab == tab,
}),
@ -147,7 +148,7 @@ func Task(task *ent.Task, editing bool) *h.Element {
),
h.Input(
"text",
h.PostPartialOnTrigger(UpdateName, h.TriggerBlur, h.TriggerKeyUpEnter),
h.PostPartial(UpdateName, hx.TriggerBlur, hx.TriggerKeyUpEnter),
h.Attributes(&h.AttributeMap{
"placeholder": "What needs to be done?",
"autofocus": "true",
@ -162,8 +163,7 @@ func Task(task *ent.Task, editing bool) *h.Element {
),
),
h.P(
h.HxTrigger("dblclick"),
h.GetPartialWithQs(EditNameForm, "id="+task.ID.String()),
h.GetPartialWithQs(EditNameForm, h.NewQs("id", task.ID.String()), hx.TriggerDblClick),
h.ClassX("text-xl break-all text-wrap truncate", map[string]bool{
"line-through text-slate-400": task.CompletedAt != nil,
}),
@ -174,8 +174,8 @@ func Task(task *ent.Task, editing bool) *h.Element {
func CompleteIcon(task *ent.Task) *h.Element {
return h.Div(
h.HxTrigger("click"),
h.Post(h.GetPartialPathWithQs(ToggleCompleted, "id="+task.ID.String())),
h.HxTrigger(hx.OnClick()),
h.Post(h.GetPartialPathWithQs(ToggleCompleted, h.NewQs("id", task.ID.String()))),
h.Class("flex items-center justify-center cursor-pointer"),
h.Div(
h.ClassX("w-10 h-10 border rounded-full flex items-center justify-center", map[string]bool{
@ -259,11 +259,11 @@ func ToggleCompleted(ctx *h.RequestContext) *h.Partial {
list, _ := service.List()
return h.NewPartial(h.Fragment(
h.OobSwap(ctx, List(list, getActiveTab(ctx))),
h.OobSwap(ctx, Footer(list, getActiveTab(ctx))),
h.OobSwap(ctx, CompleteAllIcon(list)),
))
return h.SwapManyPartial(ctx,
List(list, getActiveTab(ctx)),
Footer(list, getActiveTab(ctx)),
CompleteAllIcon(list),
)
}
func CompleteAll(ctx *h.RequestContext) *h.Partial {
@ -302,7 +302,9 @@ func Create(ctx *h.RequestContext) *h.Partial {
list, _ := service.List()
return h.NewPartial(h.Fragment(h.OobSwap(ctx, CardBody(list, getActiveTab(ctx)))))
return h.SwapManyPartial(ctx,
CardBody(list, getActiveTab(ctx)),
)
}
func ChangeTab(ctx *h.RequestContext) *h.Partial {
@ -311,10 +313,9 @@ func ChangeTab(ctx *h.RequestContext) *h.Partial {
tab := ctx.QueryParam("tab")
return h.NewPartialWithHeaders(&h.Headers{"hx-push-url": fmt.Sprintf("/tasks?tab=%s", tab)},
h.Fragment(
h.OobSwap(ctx, List(list, tab)),
h.OobSwap(ctx, Footer(list, tab)),
),
return h.SwapManyPartialWithHeaders(ctx,
h.PushUrlHeader(fmt.Sprintf("/tasks?tab=%s", tab)),
List(list, tab),
Footer(list, tab),
)
}