Compare commits
3 commits
master
...
script-enh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f868e3e3f8 | ||
|
|
b6233a2a96 | ||
|
|
cd8d08c0a5 |
9 changed files with 411 additions and 34 deletions
|
|
@ -55,10 +55,12 @@ var re = regexp.MustCompile(`\s+`)
|
|||
func compareIgnoreSpaces(t *testing.T, actual, expected string) {
|
||||
expected = strings.ReplaceAll(expected, "\n", "")
|
||||
expected = strings.ReplaceAll(expected, "\t", "")
|
||||
expected = re.ReplaceAllString(expected, " ")
|
||||
actual = strings.ReplaceAll(actual, "\n", "")
|
||||
actual = strings.ReplaceAll(actual, "\t", "")
|
||||
actual = re.ReplaceAllString(actual, " ")
|
||||
spaceRegex := regexp.MustCompile(`\s+`)
|
||||
actual = strings.TrimSpace(spaceRegex.ReplaceAllString(actual, ""))
|
||||
expected = strings.TrimSpace(spaceRegex.ReplaceAllString(expected, ""))
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
|
|
@ -75,11 +77,11 @@ func TestJsEval(t *testing.T) {
|
|||
}
|
||||
|
||||
compareIgnoreSpaces(t, renderJs(t, EvalJsOnParent("element.style.display = 'none'")), `
|
||||
if(!self.parentElement) { return; } let element = self.parentElement; element.style.display = 'none'
|
||||
if(self.parentElement) { let element = self.parentElement; element.style.display = 'none' }
|
||||
`)
|
||||
|
||||
compareIgnoreSpaces(t, renderJs(t, EvalJsOnSibling("button", "element.style.display = 'none'")), `
|
||||
if(!self.parentElement) { return; }let siblings = self.parentElement.querySelectorAll('button');siblings.forEach(function(element) {element.style.display = 'none'});
|
||||
if(self.parentElement) { let siblings = self.parentElement.querySelectorAll('button');siblings.forEach(function(element) {element.style.display = 'none'}); }
|
||||
`)
|
||||
|
||||
}
|
||||
|
|
@ -145,13 +147,13 @@ func TestToggleClassOnElement(t *testing.T) {
|
|||
|
||||
func TestSetClassOnParent(t *testing.T) {
|
||||
compareIgnoreSpaces(t, renderJs(t, SetClassOnParent("active")), `
|
||||
if(!self.parentElement) { return; } let element = self.parentElement; element.classList.add('active')
|
||||
if(self.parentElement) { let element = self.parentElement; element.classList.add('active') }
|
||||
`)
|
||||
}
|
||||
|
||||
func TestRemoveClassOnParent(t *testing.T) {
|
||||
compareIgnoreSpaces(t, renderJs(t, RemoveClassOnParent("active")), `
|
||||
if(!self.parentElement) { return; } let element = self.parentElement; element.classList.remove('active')
|
||||
if(self.parentElement) { let element = self.parentElement; element.classList.remove('active') }
|
||||
`)
|
||||
}
|
||||
|
||||
|
|
@ -174,20 +176,28 @@ func TestRemoveClassOnChildren(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSetClassOnSibling(t *testing.T) {
|
||||
compareIgnoreSpaces(t, renderJs(t, SetClassOnSibling("button", "selected")), `
|
||||
if(!self.parentElement) { return; }let siblings = self.parentElement.querySelectorAll('button');
|
||||
siblings.forEach(function(element) {
|
||||
element.classList.add('selected')
|
||||
});
|
||||
compareIgnoreSpaces(t, renderJs(t, SetClassOnSibling("button", "selected")),
|
||||
// language=JavaScript
|
||||
`
|
||||
if(self.parentElement) {
|
||||
let siblings = self.parentElement.querySelectorAll('button');
|
||||
siblings.forEach(function(element) {
|
||||
element.classList.add('selected')
|
||||
});
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func TestRemoveClassOnSibling(t *testing.T) {
|
||||
compareIgnoreSpaces(t, renderJs(t, RemoveClassOnSibling("button", "selected")), `
|
||||
if(!self.parentElement) { return; }let siblings = self.parentElement.querySelectorAll('button');
|
||||
siblings.forEach(function(element) {
|
||||
element.classList.remove('selected')
|
||||
});
|
||||
compareIgnoreSpaces(t, renderJs(t, RemoveClassOnSibling("button", "selected")),
|
||||
// language=JavaScript
|
||||
`
|
||||
if(self.parentElement) {
|
||||
let siblings = self.parentElement.querySelectorAll('button');
|
||||
siblings.forEach(function(element) {
|
||||
element.classList.remove('selected')
|
||||
});
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
|
|
@ -226,3 +236,148 @@ func TestInjectScriptIfNotExist(t *testing.T) {
|
|||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func TestEvalCommands(t *testing.T) {
|
||||
t.Parallel()
|
||||
div := Div(Id("test"))
|
||||
result := Render(EvalCommands(div,
|
||||
SetText("hello"),
|
||||
EvalJs(`
|
||||
alert('test')
|
||||
`),
|
||||
SetClassOnParent("myclass"),
|
||||
SetClassOnSibling("div", "myclass"),
|
||||
))
|
||||
|
||||
evalId := ""
|
||||
for _, child := range div.children {
|
||||
switch child.(type) {
|
||||
case *AttributeR:
|
||||
attr := child.(*AttributeR)
|
||||
if attr.Name == "data-eval-commands-id" {
|
||||
evalId = attr.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
let element = document.querySelector("[data-eval-commands-id='%s']");
|
||||
if(!element) {return;}
|
||||
self = element;
|
||||
self.innerText = 'hello'
|
||||
alert('test')
|
||||
if(self.parentElement) {
|
||||
element = self.parentElement;
|
||||
element.classList.add('myclass')
|
||||
}
|
||||
if(self.parentElement) {
|
||||
let siblings = self.parentElement.querySelectorAll('div');
|
||||
siblings.forEach(function(element) {
|
||||
element.classList.add('myclass')
|
||||
});
|
||||
}
|
||||
`, evalId))
|
||||
}
|
||||
|
||||
func TestToggleText(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleText("hello", "world"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
if(self.innerText === "hello") {
|
||||
self.innerText = "world";
|
||||
} else {
|
||||
self.innerText = "hello";
|
||||
}
|
||||
`))
|
||||
}
|
||||
|
||||
func TestToggleTextOnSibling(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleTextOnSibling("div", "hello", "world"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
if(self.parentElement) {
|
||||
let siblings = self.parentElement.querySelectorAll('div');
|
||||
siblings.forEach(function(element){
|
||||
if(element.innerText === "hello"){
|
||||
element.innerText= "world";
|
||||
} else {
|
||||
element.innerText= "hello";
|
||||
}
|
||||
});
|
||||
}
|
||||
`))
|
||||
}
|
||||
|
||||
func TestToggleTextOnChildren(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleTextOnChildren("div", "hello", "world"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
let children = self.querySelectorAll('div');
|
||||
children.forEach(function(element) {
|
||||
if(element.innerText === "hello") {
|
||||
element.innerText = "world";
|
||||
} else {
|
||||
element.innerText = "hello";
|
||||
}
|
||||
});
|
||||
`))
|
||||
}
|
||||
|
||||
func TestToggleTextOnParent(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleTextOnParent("hello", "world"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
if(self.parentElement) {
|
||||
let element = self.parentElement;
|
||||
|
||||
if(element.innerText === "hello") {
|
||||
element.innerText = "world";
|
||||
} else {
|
||||
element.innerText = "hello";
|
||||
}
|
||||
}
|
||||
`))
|
||||
}
|
||||
|
||||
func TestToggleClassOnChildren(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleClassOnChildren("div", "hidden"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
let children = self.querySelectorAll('div');
|
||||
children.forEach(function(element) {
|
||||
element.classList.toggle('hidden')
|
||||
});
|
||||
`))
|
||||
}
|
||||
|
||||
func TestToggleClassOnParent(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleClassOnParent("hidden"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
if(self.parentElement) {
|
||||
let element = self.parentElement;
|
||||
element.classList.toggle('hidden')
|
||||
}
|
||||
`))
|
||||
}
|
||||
|
||||
func TestToggleClassOnSibling(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := Render(ToggleClassOnSibling("div", "hidden"))
|
||||
//language=JavaScript
|
||||
compareIgnoreSpaces(t, result, fmt.Sprintf(`
|
||||
if(self.parentElement) {
|
||||
let siblings = self.parentElement.querySelectorAll('div');
|
||||
siblings.forEach(function(element) {
|
||||
element.classList.toggle('hidden')
|
||||
});
|
||||
}
|
||||
`))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package h
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"github.com/maddalax/htmgo/framework/hx"
|
||||
"github.com/maddalax/htmgo/framework/internal/util"
|
||||
"strings"
|
||||
|
|
@ -233,6 +234,54 @@ func ToggleClass(class string) SimpleJsCommand {
|
|||
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.toggle('%s')", class)}
|
||||
}
|
||||
|
||||
// ToggleText toggles the given text on the element.
|
||||
func ToggleText(text string, textTwo string) Command {
|
||||
// language=JavaScript
|
||||
return EvalJs(fmt.Sprintf(`
|
||||
if(self.innerText === "%s") {
|
||||
self.innerText = "%s";
|
||||
} else {
|
||||
self.innerText = "%s";
|
||||
}
|
||||
`, text, textTwo, text))
|
||||
}
|
||||
|
||||
// ToggleTextOnSibling toggles the given text on the siblings of the element.
|
||||
func ToggleTextOnSibling(selector, text string, textTwo string) Command {
|
||||
// language=JavaScript
|
||||
return EvalJsOnSibling(selector, fmt.Sprintf(`
|
||||
if(element.innerText === "%s") {
|
||||
element.innerText = "%s";
|
||||
} else {
|
||||
element.innerText = "%s";
|
||||
}
|
||||
`, text, textTwo, text))
|
||||
}
|
||||
|
||||
// ToggleTextOnChildren toggles the given text on the children of the element.
|
||||
func ToggleTextOnChildren(selector, text string, textTwo string) Command {
|
||||
// language=JavaScript
|
||||
return EvalJsOnChildren(selector, fmt.Sprintf(`
|
||||
if(element.innerText === "%s") {
|
||||
element.innerText = "%s";
|
||||
} else {
|
||||
element.innerText = "%s";
|
||||
}
|
||||
`, text, textTwo, text))
|
||||
}
|
||||
|
||||
// ToggleTextOnParent toggles the given text on the parent of the element.
|
||||
func ToggleTextOnParent(text string, textTwo string) Command {
|
||||
// language=JavaScript
|
||||
return EvalJsOnParent(fmt.Sprintf(`
|
||||
if(element.innerText === "%s") {
|
||||
element.innerText = "%s";
|
||||
} else {
|
||||
element.innerText = "%s";
|
||||
}
|
||||
`, text, textTwo, text))
|
||||
}
|
||||
|
||||
// ToggleClassOnElement toggles the given class on the elements returned by the selector.
|
||||
func ToggleClassOnElement(selector, class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
|
|
@ -247,9 +296,10 @@ func ToggleClassOnElement(selector, class string) ComplexJsCommand {
|
|||
func EvalJsOnParent(js string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJs(fmt.Sprintf(`
|
||||
if(!self.parentElement) { return; }
|
||||
let element = self.parentElement;
|
||||
%s
|
||||
if(self.parentElement) {
|
||||
let element = self.parentElement;
|
||||
%s
|
||||
}
|
||||
`, js))
|
||||
}
|
||||
|
||||
|
|
@ -268,32 +318,51 @@ func EvalJsOnChildren(selector, js string) ComplexJsCommand {
|
|||
func EvalJsOnSibling(selector, js string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJs(fmt.Sprintf(`
|
||||
if(!self.parentElement) { return; }
|
||||
let siblings = self.parentElement.querySelectorAll('%s');
|
||||
siblings.forEach(function(element) {
|
||||
%s
|
||||
});
|
||||
if(self.parentElement) {
|
||||
let siblings = self.parentElement.querySelectorAll('%s');
|
||||
siblings.forEach(function(element) {
|
||||
%s
|
||||
});
|
||||
}
|
||||
`, selector, js))
|
||||
}
|
||||
|
||||
// SetClassOnParent sets the given class on the parent of the element. Reference the element using 'element'.
|
||||
// SetClassOnParent sets the given class on the parent of the element.
|
||||
func SetClassOnParent(class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJsOnParent(fmt.Sprintf("element.classList.add('%s')", class))
|
||||
}
|
||||
|
||||
// RemoveClassOnParent removes the given class from the parent of the element. Reference the element using 'element'.
|
||||
// RemoveClassOnParent removes the given class from the parent of the element.
|
||||
func RemoveClassOnParent(class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJsOnParent(fmt.Sprintf("element.classList.remove('%s')", class))
|
||||
}
|
||||
|
||||
// SetClassOnChildren sets the given class on the children of the element. Reference the element using 'element'.
|
||||
// SetClassOnChildren sets the given class on the children of the element.
|
||||
func SetClassOnChildren(selector, class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJsOnChildren(selector, fmt.Sprintf("element.classList.add('%s')", class))
|
||||
}
|
||||
|
||||
// ToggleClassOnChildren toggles the given class on the children of the element.
|
||||
func ToggleClassOnChildren(selector, class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJsOnChildren(selector, fmt.Sprintf("element.classList.toggle('%s')", class))
|
||||
}
|
||||
|
||||
// ToggleClassOnParent toggles the given class on the parent of the element.
|
||||
func ToggleClassOnParent(class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJsOnParent(fmt.Sprintf("element.classList.toggle('%s')", class))
|
||||
}
|
||||
|
||||
// ToggleClassOnSibling toggles the given class on the siblings of the element.
|
||||
func ToggleClassOnSibling(selector, class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
return EvalJsOnSibling(selector, fmt.Sprintf("element.classList.toggle('%s')", class))
|
||||
}
|
||||
|
||||
// SetClassOnSibling sets the given class on the siblings of the element. Reference the element using 'element'.
|
||||
func SetClassOnSibling(selector, class string) ComplexJsCommand {
|
||||
// language=JavaScript
|
||||
|
|
@ -330,6 +399,36 @@ func EvalJs(js string) ComplexJsCommand {
|
|||
return NewComplexJsCommand(js)
|
||||
}
|
||||
|
||||
func EvalCommandsOnSelector(selector string, cmds ...Command) ComplexJsCommand {
|
||||
lines := make([]string, len(cmds))
|
||||
for i, cmd := range cmds {
|
||||
lines[i] = Render(cmd)
|
||||
lines[i] = strings.ReplaceAll(lines[i], "this.", "self.")
|
||||
// some commands set the element we need to fix it so we arent redeclaring it
|
||||
lines[i] = strings.ReplaceAll(lines[i], "let element =", "element =")
|
||||
}
|
||||
code := strings.Join(lines, "\n")
|
||||
return EvalJs(fmt.Sprintf(`
|
||||
let element = document.querySelector("%s");
|
||||
|
||||
if(!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
self = element;
|
||||
%s
|
||||
`, selector, code))
|
||||
}
|
||||
|
||||
func EvalCommands(element *Element, cmds ...Command) ComplexJsCommand {
|
||||
id := strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
element.AppendChildren(
|
||||
Attribute("data-eval-commands-id", id),
|
||||
)
|
||||
return EvalCommandsOnSelector(
|
||||
fmt.Sprintf(`[data-eval-commands-id='%s']`, id), cmds...)
|
||||
}
|
||||
|
||||
// PreventDefault prevents the default action of the event.
|
||||
func PreventDefault() SimpleJsCommand {
|
||||
// language=JavaScript
|
||||
|
|
|
|||
|
|
@ -35,9 +35,15 @@ var voidTags = map[string]bool{
|
|||
"wbr": true,
|
||||
}
|
||||
|
||||
type ScriptEntry struct {
|
||||
Body string
|
||||
ChildOf *Element
|
||||
}
|
||||
|
||||
type RenderContext struct {
|
||||
builder *strings.Builder
|
||||
scripts []string
|
||||
builder *strings.Builder
|
||||
scripts []ScriptEntry
|
||||
currentElement *Element
|
||||
}
|
||||
|
||||
func (ctx *RenderContext) AddScript(funcName string, body string) {
|
||||
|
|
@ -48,7 +54,11 @@ func (ctx *RenderContext) AddScript(funcName string, body string) {
|
|||
%s
|
||||
}
|
||||
</script>`, funcName, funcName, body)
|
||||
ctx.scripts = append(ctx.scripts, script)
|
||||
|
||||
ctx.scripts = append(ctx.scripts, ScriptEntry{
|
||||
Body: script,
|
||||
ChildOf: ctx.currentElement,
|
||||
})
|
||||
}
|
||||
|
||||
func (node *Element) Render(context *RenderContext) {
|
||||
|
|
@ -56,6 +66,8 @@ func (node *Element) Render(context *RenderContext) {
|
|||
return
|
||||
}
|
||||
|
||||
context.currentElement = node
|
||||
|
||||
if node.tag == CachedNodeTag {
|
||||
meta := node.meta.(*CachedNode)
|
||||
meta.Render(context)
|
||||
|
|
@ -147,7 +159,7 @@ func (node *Element) Render(context *RenderContext) {
|
|||
}
|
||||
|
||||
if node.tag != "" {
|
||||
renderScripts(context)
|
||||
renderScripts(context, node)
|
||||
if !voidTags[node.tag] {
|
||||
context.builder.WriteString("</")
|
||||
context.builder.WriteString(node.tag)
|
||||
|
|
@ -156,11 +168,19 @@ func (node *Element) Render(context *RenderContext) {
|
|||
}
|
||||
}
|
||||
|
||||
func renderScripts(context *RenderContext) {
|
||||
for _, script := range context.scripts {
|
||||
context.builder.WriteString(script)
|
||||
func renderScripts(context *RenderContext, parent *Element) {
|
||||
if len(context.scripts) == 0 {
|
||||
return
|
||||
}
|
||||
context.scripts = []string{}
|
||||
notWritten := make([]ScriptEntry, 0)
|
||||
for _, script := range context.scripts {
|
||||
if script.ChildOf == parent {
|
||||
context.builder.WriteString(script.Body)
|
||||
} else {
|
||||
notWritten = append(notWritten, script)
|
||||
}
|
||||
}
|
||||
context.scripts = notWritten
|
||||
}
|
||||
|
||||
func (a *AttributeR) Render(context *RenderContext) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ var SetDisabled = h.SetDisabled
|
|||
var RemoveClass = h.RemoveClass
|
||||
var Alert = h.Alert
|
||||
var SetClassOnChildren = h.SetClassOnChildren
|
||||
var ToggleClassOnChildren = h.ToggleClassOnChildren
|
||||
var ToggleClassOnParent = h.ToggleClassOnParent
|
||||
var SetClassOnParent = h.SetClassOnParent
|
||||
var RemoveClassOnParent = h.RemoveClassOnParent
|
||||
var ToggleClassOnSibling = h.ToggleClassOnSibling
|
||||
var RemoveClassOnChildren = h.RemoveClassOnChildren
|
||||
var EvalJsOnChildren = h.EvalJsOnChildren
|
||||
var EvalJsOnSibling = h.EvalJsOnSibling
|
||||
|
|
@ -23,6 +28,8 @@ var RemoveClassOnSibling = h.RemoveClassOnSibling
|
|||
var Remove = h.Remove
|
||||
var PreventDefault = h.PreventDefault
|
||||
var EvalJs = h.EvalJs
|
||||
var EvalCommands = h.EvalCommands
|
||||
var EvalCommandsOnSelector = h.EvalCommandsOnSelector
|
||||
var ConsoleLog = h.ConsoleLog
|
||||
var SetValue = h.SetValue
|
||||
var SubmitFormOnEnter = h.SubmitFormOnEnter
|
||||
|
|
@ -36,3 +43,7 @@ var GetWithQs = h.GetWithQs
|
|||
var PostWithQs = h.PostWithQs
|
||||
var ToggleClass = h.ToggleClass
|
||||
var ToggleClassOnElement = h.ToggleClassOnElement
|
||||
var ToggleText = h.ToggleText
|
||||
var ToggleTextOnSibling = h.ToggleTextOnSibling
|
||||
var ToggleTextOnChildren = h.ToggleTextOnChildren
|
||||
var ToggleTextOnParent = h.ToggleTextOnParent
|
||||
|
|
|
|||
|
|
@ -70,9 +70,31 @@ var ClickToEditSnippet = Snippet{
|
|||
partial: snippets.ClickToEdit,
|
||||
}
|
||||
|
||||
var JsSetTextOnClick = Snippet{
|
||||
category: "Interactivity (JS)",
|
||||
name: "Set Element Text On Click",
|
||||
description: "A simple example of how to use htmgo with javascript",
|
||||
sidebarName: "Set Text On Click",
|
||||
path: "/examples/js-set-text-on-click",
|
||||
partial: snippets.SetTextOnClick,
|
||||
}
|
||||
|
||||
var JsHideChildrenOnClick = Snippet{
|
||||
category: "Interactivity (JS)",
|
||||
name: "Hide / Show Children On Click",
|
||||
description: "Use JS to hide and show children elements on click",
|
||||
sidebarName: "Hide / Show Children",
|
||||
path: "/examples/js-hide-children-on-click",
|
||||
partial: snippets.JsHideChildrenOnClick,
|
||||
}
|
||||
|
||||
var examples = []Snippet{
|
||||
FormWithLoadingStateSnippet,
|
||||
ClickToEditSnippet,
|
||||
|
||||
JsSetTextOnClick,
|
||||
JsHideChildrenOnClick,
|
||||
|
||||
UserAuthSnippet,
|
||||
ChatSnippet,
|
||||
HackerNewsSnippet,
|
||||
|
|
|
|||
10
htmgo-site/pages/examples/js-hide-children-on-click.go
Normal file
10
htmgo-site/pages/examples/js-hide-children-on-click.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package examples
|
||||
|
||||
import (
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
)
|
||||
|
||||
func JsHideChildrenOnClickPage(ctx *h.RequestContext) *h.Page {
|
||||
SetSnippet(ctx, &JsHideChildrenOnClick)
|
||||
return Index(ctx)
|
||||
}
|
||||
10
htmgo-site/pages/examples/js-set-text-on-click.go
Normal file
10
htmgo-site/pages/examples/js-set-text-on-click.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package examples
|
||||
|
||||
import (
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
)
|
||||
|
||||
func JsSetTextOnClickPage(ctx *h.RequestContext) *h.Page {
|
||||
SetSnippet(ctx, &JsSetTextOnClick)
|
||||
return Index(ctx)
|
||||
}
|
||||
32
htmgo-site/partials/snippets/js-hide-children-on-click.go
Normal file
32
htmgo-site/partials/snippets/js-hide-children-on-click.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package snippets
|
||||
|
||||
import (
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/js"
|
||||
)
|
||||
|
||||
func JsHideChildrenOnClick(ctx *h.RequestContext) *h.Partial {
|
||||
text := h.Pf("- Parent")
|
||||
return h.NewPartial(
|
||||
h.Div(
|
||||
text,
|
||||
h.Class("cursor-pointer"),
|
||||
h.Id("js-test"),
|
||||
h.OnClick(
|
||||
js.ToggleClassOnChildren("div", "hidden"),
|
||||
js.EvalCommands(
|
||||
text,
|
||||
js.ToggleText("+ Parent", "- Parent"),
|
||||
),
|
||||
),
|
||||
h.Div(
|
||||
h.Class("ml-4"),
|
||||
h.Text("Child 1"),
|
||||
),
|
||||
h.Div(
|
||||
h.Class("ml-4"),
|
||||
h.Text("Child 2"),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
18
htmgo-site/partials/snippets/js-set-text-on-click.go
Normal file
18
htmgo-site/partials/snippets/js-set-text-on-click.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package snippets
|
||||
|
||||
import (
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/js"
|
||||
)
|
||||
|
||||
func SetTextOnClick(ctx *h.RequestContext) *h.Partial {
|
||||
return h.NewPartial(
|
||||
h.Button(
|
||||
h.Text("Click to set text"),
|
||||
h.Class("bg-slate-900 text-white py-2 px-4 rounded"),
|
||||
h.OnClick(
|
||||
js.SetText("Hello World"),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
Loading…
Reference in a new issue