[GopherJS] Setting Implementation via JSON and Web Storage (localStorage)


Implement setting feature to save user preferences in web application via JSON, Web Storage, and GopherJS.

index.html | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>GopherJS implement setting via JSON and Web Storage (localStorage)</title>
</head>
<body>

<input type="checkbox" checked="checked" id="en"/><span>English</span><br>
<input type="checkbox" checked="checked" id="ja"/><span>Japanese</span><br>
<br>
<span>Order:</span>
<select id="order">
  <option value="eng" selected="selected">English First</option>
  <option value="jpa">Japanese First</option>
</select>

<script src="app.js"></script>
</body>
</html>

FIXME: There is bug in the code below. The json.Marshal cannot convert Setting type correctly. Still try to figure out what's going wrong.

app.go | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main

import (
	"encoding/json"
	"github.com/gopherjs/gopherjs/js"
)

var localStorage = js.Global.Get("localStorage")
var mySettingName = "mySetting"

type Setting struct {
	en    bool   `json:"en"`
	ja    bool   `json:"ja"`
	order string `json:"order"`
}

func Setting2JSON(s Setting) string {
	b, err := json.Marshal(s)
	if err != nil {
		panic(err)
	}
	return string(b)
}

func JSON2Setting(j string) Setting {
	setting := Setting{}
	err := json.Unmarshal([]byte(j), &setting)
	if err != nil {
		panic(err)
	}
	return setting
}

func SaveSetting(s Setting) {
	localStorage.Set(mySettingName, Setting2JSON(s))
}

func LoadSetting() Setting {
	return JSON2Setting(localStorage.Get(mySettingName).String())
}

func SetupSetting() {
	d := js.Global.Get("document")
	enElm := d.Call("getElementById", "en")
	jaElm := d.Call("getElementById", "ja")
	orderElm := d.Call("getElementById", "order")

	s := Setting{}

	// check if there is saved setting in user browser
	if localStorage.Get(mySettingName) == js.Undefined {
		// no setting saved, use default setting
		s.en = enElm.Get("checked").Bool()
		s.ja = jaElm.Get("checked").Bool()
		s.order = orderElm.Get("options").Call("item", orderElm.Get("selectedIndex").Int()).Get("value").String()
		SaveSetting(s)
	} else {
		// use saved setting in user browser
		s = LoadSetting()
		enElm.Set("checked", s.en)
		jaElm.Set("checked", s.ja)
		orderElm.Set("value", s.order)
	}

	enElm.Call("addEventListener", "click", func(event *js.Object) {
		s.en = enElm.Get("checked").Bool()
		SaveSetting(s)
	})

	jaElm.Call("addEventListener", "click", func(event *js.Object) {
		s.ja = jaElm.Get("checked").Bool()
		SaveSetting(s)
	})

	orderElm.Call("addEventListener", "change", func(event *js.Object) {
		s.order = orderElm.Get("options").Call("item", orderElm.Get("selectedIndex").Int()).Get("value").String()
		SaveSetting(s)
	})
}

func main() {
	SetupSetting()
}

To see demo: use GopherJS to compile app.go to app.js. Put index.html and app.js in the same directory. Open index.html with your browser.

To implement setting feature via JavaScript, see [3].


Tested on:

  • Ubuntu Linux 16.10
  • Go 1.7.4
  • Chromium Version 55.0.2883.87 Built on Ubuntu , running on Ubuntu 16.10 (64-bit)

References:

[1]GopherJS - A compiler from Go to JavaScript (GitHub, GopherJS Playground, godoc)
[2]

pali/setting.go at master · siongui/pali · GitHub

pali/json.go at master · siongui/pali · GitHub

pali/dictionary.go at master · siongui/pali · GitHub

pali/setting.html at master · siongui/pali · GitHub

[3][JavaScript] Setting Implementation via JSON and Web Storage (localStorage)