Demos needed for dealing UI components from event handler
suntong opened this issue · comments
Please take a look at
https://github.com/suntong/go-app-demos/tree/master/0B2A-codecopy
unfinished refactor from the last good version.
What I want to achieve is to have two code blocks and be able to do code-copy from either of them. Unfinished because I'm not too sure how to move forward, in achieving so.
Moreover, please give demo code how to deal with the UI components from the event handler, of the following scenarios in onButtonClicked()
:
- Just for the showcase, try get the code from the html UI, instead of directly using
m.code[i]
- Change the text of the clicked button from "Copy code" to "Copied", after 2 seconds, change it back.
- And/or, force show tooltip to the clicked button as "Copied", after 2 seconds, force remove the tooltip.
I tried to see from the reference how to access the UI components from the event handler myself but no luck. Please help.
Demo code..
// DisplaySample replaces your (m *codeBlockModel) Render()
func DisplaySample() app.UI {
codeSamples := []string{`
// Code block 1
function helloWorld() {
console.log("Hello, world!");
}
`,
`
// Code block 2
for (let i = 0; i < 5; i++) {
console.log(i);
}
`}
return app.Div().Class("code-container").Body(
app.Range(codeSamples).Slice(func(i int) app.UI {
return &CodeBlock{code: codeSamples[i], id: fmt.Sprintf("codeBlock%02d", i+1)}
}),
)
}
type CodeBlock struct {
app.Compo
id string
code string
}
func (m *CodeBlock) Render() app.UI {
return app.Div().Class("code-block").Body(
copySVG(),
&CopyButton{text: "Copy code", from: m},
app.Pre().Body(
app.Code().ID(m.id).Text(m.code),
),
)
}
// original svg markup had two "class" attributes. in this one they are merged
func copySVG() app.UI {
return app.Raw(`<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="copy-svg h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>`)
}
type CopyButton struct {
app.Compo
from *CodeBlock
text string
}
func (cb *CopyButton) Render() app.UI {
return app.Button().Class("copy-button").Text(cb.text).OnClick(cb.onClick)
}
func (cb *CopyButton) onClick(ctx app.Context, e app.Event) {
// using go
log.Println("copy via go\n", cb.from.code)
// using element id
val := app.Window().GetElementByID(cb.from.id).Get("innerHTML")
log.Println("copy via dom\n", val.String())
app.Window().Get("navigator").Get("clipboard").Call("writeText", val)
cb.text = "Copied"
ctx.After(2*time.Second, cb.revertText)
}
func (cb *CopyButton) revertText(ctx app.Context) {
cb.text = "Copy code"
}
Demo code..
Wow, thanks a million.
I've incoporated everything into
https://github.com/suntong/go-app-demos/blob/master/0B2A-codecopy/main.go
(I'm keeping m.code[i]
as that would where my data come from in my realworld app)
The // using go
and // using element id
are both working fine, however, it is the next line that causes my browser panic, the line of app.Window().Get("navigator").Get("clipboard").Call("writeText", val)
, and the panic errors are:
2023/08/14 14:16:58 copy via dom
// Code block 1
function helloWorld() {
console.log("Hello, world!");
}
wasm_exec.js:22 panic: syscall/js: call of Value.Call on undefined [recovered]
wasm_exec.js:22 panic: syscall/js: call of Value.Call on undefined
wasm_exec.js:22
wasm_exec.js:22 goroutine 1 [running]:
wasm_exec.js:22 github.com/maxence-charriere/go-app/v9/pkg/app.RunWhenOnBrowser.func1()
wasm_exec.js:22 /.../Go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.7.3/pkg/app/app.go:109 +0x4
wasm_exec.js:22 panic({0x65540, 0x80a3f0})
wasm_exec.js:22 /usr/lib/go-1.19/src/runtime/panic.go:890 +0x33
wasm_exec.js:22 syscall/js.Value.Call({{}, 0x0, 0x0}, {0xcf08b, 0x9}, {0x81df60, 0x1, 0x1})
wasm_exec.js:22 /usr/lib/go-1.19/src/syscall/js/js.go:384 +0x35
wasm_exec.js:22 github.com/maxence-charriere/go-app/v9/pkg/app.value.Call({{{}, 0x0, 0x0}}, {0xcf08b, 0x9}, {0x81df60, 0x1, 0x1}) // Code block 1
function helloWorld() {
console.log("Hello, world!");
}
wasm_exec.js:22 panic: syscall/js: call of Value.Call on undefined [recovered]
wasm_exec.js:22 panic: syscall/js: call of Value.Call on undefined
wasm_exec.js:22
wasm_exec.js:22 goroutine 1 [running]:
wasm_exec.js:22 github.com/maxence-charriere/go-app/v9/pkg/app.RunWhenOnBrowser.func1()
wasm_exec.js:22 /.../Go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.7.3/pkg/app/app.go:109 +0x4
wasm_exec.js:22 panic({0x65540, 0x80a3f0})
wasm_exec.js:22 /usr/lib/go-1.19/src/runtime/panic.go:890 +0x33
wasm_exec.js:22 syscall/js.Value.Call({{}, 0x0, 0x0}, {0xcf08b, 0x9}, {0x81df60, 0x1, 0x1})
wasm_exec.js:22 /usr/lib/go-1.19/src/syscall/js/js.go:384 +0x35
wasm_exec.js:22 github.com/maxence-charriere/go-app/v9/pkg/app.value.Call({{{}, 0x0, 0x0}}, {0xcf08b, 0x9}, {0x81df60, 0x1, 0x1})
wasm_exec.js:22 panic: syscall/js: call of Value.Call on undefined [recovered]
wasm_exec.js:22 panic: syscall/js: call of Value.Call on undefined
wasm_exec.js:22
wasm_exec.js:22 goroutine 1 [running]:
wasm_exec.js:22 github.com/maxence-charriere/go-app/v9/pkg/app.RunWhenOnBrowser.func1()
wasm_exec.js:22 ...