//go:build js package main import ( "bytes" "encoding/json" "syscall/js" "text/template" ) func main() { regenChan := make(chan struct{}) go executeTemplate(regenChan) eventListener := func(this js.Value, args []js.Value) interface{} { ev := args[0] ev.Call("preventDefault") regenChan <- struct{}{} return nil } querySelector("#template").Call("addEventListener", "keyup", js.FuncOf(eventListener)) querySelector("#data").Call("addEventListener", "keyup", js.FuncOf(eventListener)) regenChan <- struct{}{} <-make(chan struct{}) } func executeTemplate(regenChan chan struct{}) { templateEl := querySelector("#template") dataEl := querySelector("#data") outputEl := querySelector("#output") tmplMessageEl := querySelector("#template-message") dataMessageEl := querySelector("#data-message") displayErrors := func(dataErr error, tmplErr error) { if dataErr != nil { dataMessageEl.Set("innerText", dataErr.Error()) } else { dataMessageEl.Set("innerText", "") } if tmplErr != nil { tmplMessageEl.Set("innerText", tmplErr.Error()) } else { tmplMessageEl.Set("innerText", "") } } var templateSource string var tmpl *template.Template setTemplateSource := func(newTemplateSource string) (*template.Template, error) { if tmpl == nil || templateSource != newTemplateSource { newTmpl := template.New("") if _, err := newTmpl.Parse(newTemplateSource); err != nil { return nil, err } tmpl = newTmpl } return tmpl, nil } var outBuf bytes.Buffer for range regenChan { templateValue := templateEl.Get("value").String() dataValue := dataEl.Get("value").String() var dataJson interface{} dataErr := json.Unmarshal([]byte(dataValue), &dataJson) tmplInst, tmplErr := setTemplateSource(templateValue) if dataErr != nil || tmplErr != nil { displayErrors(dataErr, tmplErr) continue } outBuf.Reset() if err := tmplInst.Execute(&outBuf, dataJson); err != nil { displayErrors(nil, err) continue } outputEl.Set("innerText", outBuf.String()) displayErrors(nil, nil) } } func querySelector(query string) js.Value { return js.Global().Get("document").Call("querySelector", query) }