some cleanup, alias funcs in js package to know which commands can be used with lifecycle
This commit is contained in:
parent
94f7d53a0d
commit
a58cb051e8
16 changed files with 74 additions and 97 deletions
|
|
@ -28,17 +28,17 @@ func Button(props ButtonProps) h.Ren {
|
|||
text := h.Text(props.Text)
|
||||
|
||||
lifecycle := h.NewLifeCycle().
|
||||
BeforeRequest(
|
||||
HxBeforeRequest(
|
||||
h.AddAttribute("disabled", "true"),
|
||||
h.SetText("Loading..."),
|
||||
h.AddClass("bg-gray-400"),
|
||||
).
|
||||
AfterRequest(
|
||||
HxAfterRequest(
|
||||
h.RemoveAttribute("disabled"),
|
||||
h.RemoveClass("bg-gray-400"),
|
||||
h.SetText(props.Text),
|
||||
).
|
||||
OnMutationError(
|
||||
HxOnMutationError(
|
||||
h.SetText("failed"),
|
||||
h.AddClass("bg-red-400"),
|
||||
h.RemoveAttribute("disabled"),
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package h
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
"github.com/maddalax/htmgo/framework/hx"
|
||||
"github.com/maddalax/htmgo/framework/util/process"
|
||||
"github.com/maddalax/htmgo/framework/internal/process"
|
||||
"github.com/maddalax/htmgo/framework/service"
|
||||
"log/slog"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -82,7 +82,7 @@ func (a App) start() {
|
|||
}
|
||||
})
|
||||
|
||||
if a.Opts.LiveReload {
|
||||
if a.Opts.LiveReload && IsDevelopment() {
|
||||
AddLiveReloadHandler("/dev/livereload", a.Echo)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,23 +51,23 @@ func (l *LifeCycle) OnEvent(event hx.Event, cmd ...Command) *LifeCycle {
|
|||
return l
|
||||
}
|
||||
|
||||
func (l *LifeCycle) BeforeRequest(cmd ...Command) *LifeCycle {
|
||||
func OnLoad(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().OnEvent(hx.LoadDomEvent, cmd...)
|
||||
}
|
||||
|
||||
func (l *LifeCycle) HxBeforeRequest(cmd ...Command) *LifeCycle {
|
||||
l.OnEvent(hx.BeforeRequestEvent, cmd...)
|
||||
return l
|
||||
}
|
||||
|
||||
func OnLoad(cmd ...Command) *LifeCycle {
|
||||
func HxOnLoad(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().OnEvent(hx.LoadEvent, cmd...)
|
||||
}
|
||||
|
||||
func OnAfterSwap(cmd ...Command) *LifeCycle {
|
||||
func HxOnAfterSwap(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().OnEvent(hx.AfterSwapEvent, cmd...)
|
||||
}
|
||||
|
||||
func OnTrigger(trigger string, cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().OnEvent(hx.NewStringTrigger(trigger).ToString(), cmd...)
|
||||
}
|
||||
|
||||
func OnClick(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().OnEvent(hx.ClickEvent, cmd...)
|
||||
}
|
||||
|
|
@ -76,24 +76,24 @@ func OnEvent(event hx.Event, cmd ...Command) *LifeCycle {
|
|||
return NewLifeCycle().OnEvent(event, cmd...)
|
||||
}
|
||||
|
||||
func BeforeRequest(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().BeforeRequest(cmd...)
|
||||
func HxBeforeRequest(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().HxBeforeRequest(cmd...)
|
||||
}
|
||||
|
||||
func AfterRequest(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().AfterRequest(cmd...)
|
||||
func HxAfterRequest(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().HxAfterRequest(cmd...)
|
||||
}
|
||||
|
||||
func OnMutationError(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().OnMutationError(cmd...)
|
||||
func HxOnMutationError(cmd ...Command) *LifeCycle {
|
||||
return NewLifeCycle().HxOnMutationError(cmd...)
|
||||
}
|
||||
|
||||
func (l *LifeCycle) AfterRequest(cmd ...Command) *LifeCycle {
|
||||
func (l *LifeCycle) HxAfterRequest(cmd ...Command) *LifeCycle {
|
||||
l.OnEvent(hx.AfterRequestEvent, cmd...)
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *LifeCycle) OnMutationError(cmd ...Command) *LifeCycle {
|
||||
func (l *LifeCycle) HxOnMutationError(cmd ...Command) *LifeCycle {
|
||||
l.OnEvent(hx.OnMutationErrorEvent, cmd...)
|
||||
return l
|
||||
}
|
||||
|
|
@ -109,6 +109,11 @@ type ComplexJsCommand struct {
|
|||
TempFuncName string
|
||||
}
|
||||
|
||||
func NewComplexJsCommand(command string) ComplexJsCommand {
|
||||
name := fmt.Sprintf("__eval_%s", util.RandSeq(6))
|
||||
return ComplexJsCommand{Command: command, TempFuncName: name}
|
||||
}
|
||||
|
||||
func SetText(text string) SimpleJsCommand {
|
||||
// language=JavaScript
|
||||
return SimpleJsCommand{Command: fmt.Sprintf("this.innerText = '%s'", text)}
|
||||
|
|
@ -177,18 +182,17 @@ func Alert(text string) SimpleJsCommand {
|
|||
}
|
||||
|
||||
func EvalJs(js string) ComplexJsCommand {
|
||||
name := fmt.Sprintf("__eval_%s", util.RandSeq(6))
|
||||
return ComplexJsCommand{Command: js, TempFuncName: name}
|
||||
return NewComplexJsCommand(js)
|
||||
}
|
||||
|
||||
func InjectScript(src string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return ComplexJsCommand{Command: fmt.Sprintf(`
|
||||
return NewComplexJsCommand(fmt.Sprintf(`
|
||||
var script = document.createElement('script');
|
||||
script.src = '%s';
|
||||
src.async = true;
|
||||
script.async = true;
|
||||
document.head.appendChild(script);
|
||||
`, src)}
|
||||
`, src))
|
||||
}
|
||||
|
||||
func InjectScriptIfNotExist(src string) ComplexJsCommand {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ func TestRender(t *testing.T) {
|
|||
"data-attr-3": "value",
|
||||
"data-attr-4": "value",
|
||||
}),
|
||||
BeforeRequest(
|
||||
HxBeforeRequest(
|
||||
SetText("before request"),
|
||||
),
|
||||
AfterRequest(
|
||||
HxAfterRequest(
|
||||
SetText("after request"),
|
||||
),
|
||||
Children(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
)
|
||||
|
||||
func JsonSerialize(data any) string {
|
||||
func JsonSerializeOrEmpty(data any) string {
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return ""
|
||||
|
|
@ -30,6 +30,10 @@ func Post(url string, trigger ...string) *AttributeMap {
|
|||
return AttributeList(Attribute(hx.PostAttr, url), TriggerString(trigger...))
|
||||
}
|
||||
|
||||
func PostWithQs(url string, qs *Qs, trigger string) *AttributeMap {
|
||||
return Post(SetQueryParams(url, qs), trigger)
|
||||
}
|
||||
|
||||
func PostOnClick(url string) *AttributeMap {
|
||||
return Post(url, hx.ClickEvent)
|
||||
}
|
||||
|
|
|
|||
25
framework/js/commands.go
Normal file
25
framework/js/commands.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package js
|
||||
|
||||
import "github.com/maddalax/htmgo/framework/h"
|
||||
|
||||
var AddAttribute = h.AddAttribute
|
||||
var RemoveAttribute = h.RemoveAttribute
|
||||
var AddClass = h.AddClass
|
||||
var SetText = h.SetText
|
||||
var Increment = h.Increment
|
||||
var SetInnerHtml = h.SetInnerHtml
|
||||
var SetOuterHtml = h.SetOuterHtml
|
||||
var SetDisabled = h.SetDisabled
|
||||
var RemoveClass = h.RemoveClass
|
||||
var Alert = h.Alert
|
||||
var EvalJs = h.EvalJs
|
||||
var InjectScript = h.InjectScript
|
||||
var InjectScriptIfNotExist = h.InjectScriptIfNotExist
|
||||
var GetPartial = h.GetPartial
|
||||
var GetPartialWithQs = h.GetPartialWithQs
|
||||
var PostPartial = h.PostPartial
|
||||
var PostPartialWithQs = h.PostPartialWithQs
|
||||
var GetWithQs = h.GetWithQs
|
||||
var PostWithQs = h.PostWithQs
|
||||
var ToggleClass = h.ToggleClass
|
||||
var ToggleClassOnElement = h.ToggleClassOnElement
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package httpjson
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var client *http.Client
|
||||
var once sync.Once
|
||||
|
||||
func getClient() *http.Client {
|
||||
once.Do(func() {
|
||||
tr := &http.Transport{
|
||||
MaxIdleConns: 10,
|
||||
IdleConnTimeout: 15 * time.Second,
|
||||
ResponseHeaderTimeout: 15 * time.Second,
|
||||
DisableKeepAlives: false,
|
||||
}
|
||||
httpClient := &http.Client{
|
||||
Transport: tr,
|
||||
}
|
||||
client = httpClient
|
||||
})
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func Get[T any](url string) (T, error) {
|
||||
resp, err := getClient().Get(url)
|
||||
if err != nil {
|
||||
return *new(T), err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
return *new(T), errors.New(fmt.Sprintf("get to %s failed with %d code", url, resp.StatusCode))
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return *new(T), err
|
||||
}
|
||||
d := new(T)
|
||||
err = json.Unmarshal(body, &d)
|
||||
if err != nil {
|
||||
return *new(T), err
|
||||
}
|
||||
|
||||
if d == nil {
|
||||
return *new(T), errors.New("failed to create T")
|
||||
}
|
||||
|
||||
return *d, nil
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"embed"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
"github.com/maddalax/htmgo/framework/service"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"htmgo-site/internal/markdown"
|
||||
"htmgo-site/pages"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package pages
|
|||
import (
|
||||
"embed"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
"github.com/maddalax/htmgo/framework/service"
|
||||
"htmgo-site/internal/markdown"
|
||||
"htmgo-site/pages/base"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func IndexPage(c echo.Context) *h.Page {
|
|||
func Button() h.Ren {
|
||||
return h.Button(h.Class("btn bg-green-500 p-4 rounded text-white"),
|
||||
h.Text("my button"),
|
||||
h.AfterRequest(
|
||||
h.HxAfterRequest(
|
||||
h.SetDisabled(true),
|
||||
h.RemoveClass("bg-red-600"),
|
||||
h.AddClass("bg-gray-500"),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package tasks
|
|||
import (
|
||||
"context"
|
||||
"github.com/google/uuid"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
"github.com/maddalax/htmgo/framework/service"
|
||||
"time"
|
||||
"todolist/ent"
|
||||
"todolist/ent/predicate"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
"github.com/maddalax/htmgo/framework/service"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"todolist/ent"
|
||||
"todolist/infrastructure/db"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"github.com/maddalax/htmgo/framework/js"
|
||||
"todolist/pages/base"
|
||||
"todolist/partials/task"
|
||||
|
||||
|
|
@ -19,6 +20,12 @@ func TaskListPage(ctx *h.RequestContext) *h.Page {
|
|||
h.Div(
|
||||
h.Class("flex flex-col gap-6 p-4 items-center max-w-xl mx-auto pb-12"),
|
||||
title,
|
||||
h.Button(
|
||||
h.Text("Add Task"),
|
||||
h.OnClick(
|
||||
js.InjectScript("https://htmgo.dev"),
|
||||
),
|
||||
),
|
||||
task.Card(ctx),
|
||||
h.Children(
|
||||
h.Div(h.Text("Double-click to edit a todo")),
|
||||
|
|
|
|||
Loading…
Reference in a new issue