根据 Gadget 的设计,我们可能会需要在用户不用手动改变设置的情况下,主动地改变某些用户的设置(比如在 "推箱子" 这个 Gadget 中,每过一关就自动更新 "从指定关卡开始" 这个属性)。
要使用 setprefs 功能,我们需要在 Gadget 中包含以下内容:...
根据 Gadget 的设计,我们可能会需要在用户不用手动改变设置的情况下,主动地改变某些用户的设置(比如在 "推箱子" 这个 Gadget 中,每过一关就自动更新 "从指定关卡开始" 这个属性)。
要使用 setprefs
功能,我们需要在 Gadget 中包含以下内容:
- 在 <ModulePrefs> 标签中添加一个 <Require feature="setprefs"/> 标签,这使得 Gadget 读取 setprefs 库;
- 一个需要被用来改变的用户设置(废话),如果不想让用户随意改动,那么可以使用
hidden 类型(这和 HTML 中是一样的);
- 一个 JavaScript 函数,比如 set() ,用来改变这个用户设置。
需要注意的是,每个用户设置的长度会受到 URL 长度的限制,根据 Google 的说法,每个用户设置不能超过 2KB。
我们来看下面的例子:这个 Gadget 包含了一个计数器和两个按钮,其中一个按钮将计数器的值增加1,另一个按钮将计数器的值恢复到0。计数器的值被存储在 "counter" 这个用户设置中。为了防止 Gadget 的用户更改这个值,"counter" 的属性被设为 "hidden" 。
1
<?xml version="1.0" encoding="UTF-8" ?>
2
<Module>
3
<ModulePrefs title="Set Userprefs Demo">
4
<Require feature="setprefs" />
5
</ModulePrefs>
6
<UserPref name="counter"
7
default_value="0"
8
datatype="hidden"/>
9
<Content type="html">
10
<
29
<input type="button" value="加1" name="count" onClick="incrementCounter();">
30
<input type="button" value="恢复" name="reset" onClick="resetCounter();">
31
32
]]>
33
</Content>
34
</Module>
PS: 如果有多于一个设置需要改变,那么建议使用 JSON 字符串来把这些属性合成一个。下面 (源文件在 这里 ) 是一个实例:

使用JSON的实例
1
<?xml version="1.0" encoding="UTF-8" ?>
2
<Module>
3
<ModulePrefs title="__UP_title__"
4
category="tools"
5
render_inline="required"
6
scrolling="false"
7
author="Sophia B."
8
directory_title="__MSG_todo__"
9
author_email="sophia.feedback+todo@gmail.com"
10
author_affiliation="Google Inc."
11
author_location="Mountain View, CA"
12
screenshot="/ig/modules/todo.png"
13
singleton="false"
14
thumbnail="/ig/modules/todo-thm.png"
15
description="__MSG_description__">
16
<Locale messages="todo_content/todo_en.xml" />
17
<Locale lang="zh-CN" messages="todo_content/todo_zh-cn.xml" />
18
</ModulePrefs>
19
<UserPref name="title" display_name="__MSG_title__" required="false" default_value="__MSG_todo__" />
20
<UserPref name="bgcolor" display_name="__MSG_background_color__" default_value="#e5ecf9" datatype="enum">
21
<EnumValue display_value="__MSG_yellow__" value="#ffffcc" />
22
<EnumValue display_value="__MSG_blue__" value="#e5ecf9" />
23
<EnumValue display_value="__MSG_gray__" value="#efefef" />
24
<EnumValue display_value="__MSG_green__" value="#e0eee0" />
25
<EnumValue display_value="__MSG_pink__" value="#fff0f5" />
26
<EnumValue display_value="__MSG_orange__" value="#fff5ee" />
27
</UserPref>
28
<UserPref name="todos" default_value="" datatype="hidden" />
29
<Content type="html">
30
<
32
<script language="JavaScript"
33
src="/ig/modules/todo_content/json.js"></script>
34
<script language="JavaScript">
35
var todos__MODULE_ID__; // This is a json object of todo items
36
var edited__MODULE_ID__;
37
var prefs__MODULE_ID__;
38
39
_IG_RegisterOnloadHandler(
40
function loadTodos__MODULE_ID__() {
41
prefs__MODULE_ID__ = new _IG_Prefs(__MODULE_ID__);
42
var todosstring = prefs__MODULE_ID__.getString("todos");
43
if (todosstring == "")
44
todos__MODULE_ID__ = {"array":[]};
45
else
46
todos__MODULE_ID__ = JSON.parse(todosstring);
47
edited__MODULE_ID__ = false;
48
createTable__MODULE_ID__();
49
}
50
)
51
52
function saveTodos__MODULE_ID__(){
53
prefs__MODULE_ID__.set("todos", JSON.stringify(todos__MODULE_ID__));
54
_gel("newTodoInput__MODULE_ID__").focus();
55
}
56
57
function addTodo__MODULE_ID__(name, priority) {
58
var name = _trim(name);
59
_gel("newTodoInput__MODULE_ID__").value = "";
60
if (name == "")
61
return;
62
todos__MODULE_ID__.array[numTodos__MODULE_ID__()] =
63
{"name": name, "priority": priority};
64
createTable__MODULE_ID__();
65
saveTodos__MODULE_ID__();
66
return false;
67
}
68
69
function deleteTodo__MODULE_ID__(number) {
70
if (edited__MODULE_ID__)
71
return;
72
var beginning = todos__MODULE_ID__.array.slice(0, number);
73
var end = todos__MODULE_ID__.array.slice(number + 1,
74
numTodos__MODULE_ID__());
75
todos__MODULE_ID__.array = beginning.concat(end);
76
createTable__MODULE_ID__();
77
saveTodos__MODULE_ID__();
78
}
79
80
function swapTodos__MODULE_ID__(to, from) {
81
var temp = todos__MODULE_ID__.array[to];
82
todos__MODULE_ID__.array[to] = todos__MODULE_ID__.array[from];
83
todos__MODULE_ID__.array[from] = temp;
84
}
85
86
function sortByPriority__MODULE_ID__(number) {
87
var todo = todos__MODULE_ID__.array[number];;
88
var lastPriority = todo.priority;
89
for (i = number + 1; i < numTodos__MODULE_ID__(); i++) {
90
var currentTodo = todos__MODULE_ID__.array[i];
91
if (currentTodo == null)
92
break;
93
var currentPriority = currentTodo.priority;
94
if (currentPriority >= lastPriority)
95
break;
96
swapTodos__MODULE_ID__(i, i - 1);
97
}
98
for (i = number - 1; i >= 0; i--) {
99
var currentTodo = todos__MODULE_ID__.array[i];
100
if (currentTodo == null)
101
break;
102
var currentPriority = currentTodo.priority;
103
if (currentPriority <= lastPriority)
104
break;
105
swapTodos__MODULE_ID__(i + 1, i);
106
}
107
}
108
109
function setPriority__MODULE_ID__(number, priority) {
110
var row = getRow__MODULE_ID__(number);
111
var col = getCol__MODULE_ID__(row, 0);
112
col.innerHTML = createPriorityLink__MODULE_ID__(priority, number);
113
todos__MODULE_ID__.array[number].priority = priority;
114
sortByPriority__MODULE_ID__(number);
115
createTable__MODULE_ID__();
116
saveTodos__MODULE_ID__();
117
}
118
119
function editPriority__MODULE_ID__(number, priority) {
120
var row = getRow__MODULE_ID__(number);
121
if (edited__MODULE_ID__)
122
return;
123
edited__MODULE_ID__ = true;
124
var col = getCol__MODULE_ID__(row, 0);
125
col.innerHTML = createPrioritySelect__MODULE_ID__(number, priority);
126
}
127
128
function selected__MODULE_ID__(priority, num) {
129
if (priority == num)
130
return "selected=true";
131
else
132
return "";
133
}
134
135
function rowClass__MODULE_ID__(number) {
136
if (number % 2 != 0)
137
return " class=odd__MODULE_ID__ ";
138
else
139
return " class=even__MODULE_ID__ ";
140
}
141
142
function createTable__MODULE_ID__() {
143
var html = "<table cellspacing=0 id=todosTable__MODULE_ID__>";
144
for (i = 0; i < numTodos__MODULE_ID__(); i++) {
145
if (todos__MODULE_ID__.array[i] == null)
146
break;
147
var priority = todos__MODULE_ID__.array[i].priority;
148
var name = todos__MODULE_ID__.array[i].name;
149
html = html + createRow__MODULE_ID__(i, priority, name);
150
}
151
html = html + "</table>";
152
_gel("todosDiv__MODULE_ID__").innerHTML = html;
153
}
154
155
function createRow__MODULE_ID__(number, priority, name) {
156
var html =
157
"<tr id=\"row" + number + "__MODULE_ID__\"" +
158
rowClass__MODULE_ID__(number) + ">" +
159
"<td class=priority_td__MODULE_ID__>" +
160
createPriorityLink__MODULE_ID__(priority, number) +
161
"</td>" +
162
"<td class=name_td__MODULE_ID__>" +
163
createName__MODULE_ID__(number, name) +
164
"</td>" +
165
"<td>" +
166
createDelete__MODULE_ID__(number) +
167
"</td>" +
168
"</tr>";
169
return html;
170
}
171
172
function escapeName__MODULE_ID__(name) {
173
name = name.replace(/&/g,"&")
174
name = name.replace(/</g,"<")
175
name = name.replace(/>/g,">")
176
name = name.replace(/"/g,""")
177
name = name.replace(/'/g,"'")
178
return name;
179
}
180
181
function createName__MODULE_ID__(number, name) {
182
var html =
183
"<a class=name_a__MODULE_ID__" +
184
" href=\"javascript:editName__MODULE_ID__(" + number + ")\">" +
185
escapeName__MODULE_ID__(name) +
186
"</a>";
187
return html;
188
}
189
190
function createDelete__MODULE_ID__(number) {
191
var html =
192
"<a href=\"javascript:deleteTodo__MODULE_ID__(" + number + ")\">" +
193
"<img class=delete__MODULE_ID__" +
194
" src=\"http://www.google.com/ig/modules/todo_content/x.gif\">" +
195
"</a>";
196
return html;
197
}
198
199
200
function createPrioritySelect__MODULE_ID__(number, priority) {
201
var html =
202
"<select id=select__MODULE_ID__ " +
203
"onchange=\"submitPriority__MODULE_ID__(" + number + ")\">" +
204
"<option class=option__MODULE_ID__ value=1 " +
205
"onclick=\"submitPriority__MODULE_ID__(" + number + ")\" " +
206
selected__MODULE_ID__(priority, 1) + ">" +
207
"__MSG_high__" +
208
"</option>" +
209
"<option class=option__MODULE_ID__ value=2 " +
210
"onclick=\"submitPriority__MODULE_ID__(" + number + ")\" " +
211
selected__MODULE_ID__(priority, 2) + ">" +
212
"__MSG_medium__" +
213
"</option>" +
214
"<option class=option__MODULE_ID__ value=3 " +
215
"onclick=\"submitPriority__MODULE_ID__(" + number + ")\" " +
216
selected__MODULE_ID__(priority, 3) + ">" +
217
"__MSG_low__" +
218
"</option>" +
219
"</select>";
220
return html;
221
}
222
223
function createPriorityLink__MODULE_ID__(priority, number) {
224
var html =
225
"<a class=p" + priority + "___MODULE_ID__ " +
226
"href=\"javascript:editPriority__MODULE_ID__(" +
227
number + "," + priority + ")\">" +
228
getPriorityText__MODULE_ID__(priority) +
229
"</a>";
230
return html;
231
}
232
233
function createEditNameForm__MODULE_ID__(number, name) {
234
var html =
235
"<input onkeypress=\"if (isEnter__MODULE_ID__(event))" +
236
"{setName__MODULE_ID__(" + number+ ", event); return false;}\" " +
237
"type=text id=name_input__MODULE_ID__ value=\"" +
238
escapeName__MODULE_ID__(name) + "\">";
239
return html;
240
}
241
242
243
function getPriorityText__MODULE_ID__(priority) {
244
if (priority == 1)
245
return "__MSG_high__";
246
else if (priority == 2)
247
return "__MSG_medium__";
248
return "__MSG_low__";
249
}
250
251
function submitPriority__MODULE_ID__(number) {
252
var row = getRow__MODULE_ID__(number);
253
var col = getCol__MODULE_ID__(row, 0);
254
var select = _gel("select__MODULE_ID__");
255
var newPriority = select.options[select.selectedIndex].value;
256
setPriority__MODULE_ID__(number, newPriority);
257
edited__MODULE_ID__ = false;
258
}
259
260
function editName__MODULE_ID__(number) {
261
if (edited__MODULE_ID__)
262
return;
263
edited__MODULE_ID__ = true;
264
var row = getRow__MODULE_ID__(number);
265
var col = getCol__MODULE_ID__(row, 1);
266
var name = todos__MODULE_ID__.array[number].name;
267
col.innerHTML = createEditNameForm__MODULE_ID__(number, name);
268
_gel("name_input__MODULE_ID__").focus();
269
_gel("name_input__MODULE_ID__").select();
270
}
271
272
function setName__MODULE_ID__(number) {
273
var name = _trim(_gel("name_input__MODULE_ID__").value);
274
if (name == "")
275
name = todos__MODULE_ID__.array[number].name;
276
todos__MODULE_ID__.array[number].name = name;
277
var row = getRow__MODULE_ID__(number);
278
var col = getCol__MODULE_ID__(row, 1);
279
col.innerHTML = createName__MODULE_ID__(number,name);
280
saveTodos__MODULE_ID__();
281
edited__MODULE_ID__ = false;
282
return false;
283
}
284
285
function edit__MODULE_ID__() {
286
return edited__MODULE_ID__;
287
}
288
289
function isEnter__MODULE_ID__(e) {
290
var characterCode;
291
if(e && e.which){
292
e = e
293
characterCode = e.which
294
} else {
295
e = event
296
characterCode = e.keyCode
297
}
298
if (characterCode == 13)
299
return true;
300
return false
301
}
302
303
function getTable__MODULE_ID__() {
304
return _gel('todosTable__MODULE_ID__');
305
}
306
307
function getRow__MODULE_ID__(number) {
308
return _gel("row" + number + "__MODULE_ID__");
309
}
310
311
function getCol__MODULE_ID__(row, index) {
312
return row.childNodes.item(index);
313
}
314
315
function numTodos__MODULE_ID__() {
316
return todos__MODULE_ID__.array.length;
317
}
318
</script>
319
320
<style type="text/css">
321
.delete__MODULE_ID__ {
322
border-style: none;
323
}
324
.priority_td__MODULE_ID__ {
325
font-family: arial;
326
padding-__BIDI_END_EDGE__: 20px;
327
font-size: 12px;
328
}
329
.p1___MODULE_ID__:link, .p1___MODULE_ID__:visited {
330
color: red;
331
text-decoration: none;
332
font-size: 12px;
333
}
334
.p2___MODULE_ID__:link, .p2___MODULE_ID__:visited {
335
color: blue;
336
text-decoration: none;
337
font-size: 12px;
338
}
339
.p3___MODULE_ID__:link, .p3___MODULE_ID__:visited {
340
color: #ff00ff;
341
text-decoration: none;
342
font-size: 12px;
343
}
344
.name_a__MODULE_ID__:link, .name_a__MODULE_ID__:visited {
345
text-decoration:none;
346
font-size: 12px;
347
color: black;
348
}
349
#name_input__MODULE_ID__, #newTodoInput__MODULE_ID__ {
350
width: 100%;
351
font-family: arial;
352
padding: 0px;
353
}
354
#new_todo_td__MODULE_ID__ {
355
font-size: 12px
356
}
357
#input__MODULE_ID__ {
358
font-family: arial;
359
padding: 0px;
360
}
361
#todosTable__MODULE_ID__ {
362
margin:0;
363
padding:0;
364
width:100%;
365
font-size: 12px;
366
}
367
.name_td__MODULE_ID__ {
368
width:100%;
369
}
370
.option__MODULE_ID__ {
371
font-size: 12px;
372
padding: 0px;
373
margin: 0px;
374
font-family: arial;
375
}
376
#select__MODULE_ID__ {
377
font-family: arial;
378
width: 52px;
379
margin: 0px;
380
padding: 0px;
381
}
382
.even__MODULE_ID__ {
383
background: __UP_bgcolor__;
384
}
385
.odd__MODULE_ID__ {
386
background: white;
387
}
388
</style>
389
390
<form name = "newTodoForm__MODULE_ID__"
391
onsubmit="return addTodo__MODULE_ID__(
392
document.newTodoForm__MODULE_ID__.
393
newTodoInput__MODULE_ID__.value, 3, false)">
394
<table cellspacing=0>
395
<tr>
396
<td id="new_todo_td__MODULE_ID__">
397
<nobr>__MSG_new_item__</nobr>
398
</td>
399
<td style='width:100%' >
400
<input id="newTodoInput__MODULE_ID__" type="text"
401
style='width:100%'>
402
</td>
403
<td>
404
<input type = "button" value="__MSG_add__"
405
onclick = "javascript:addTodo__MODULE_ID__(
406
document.newTodoForm__MODULE_ID__.
407
newTodoInput__MODULE_ID__.value, 3, false)">
408
</td>
409
</tr>
410
</table>
411
<div id="todosDiv__MODULE_ID__"></div>
412
</form>
413
414
415
]]>
416
</Content>
417
</Module>
另外,在 http://www.json.org/json.js 这个JavaScript 文件中,提供了一些封装好的 JSON 方法供我们使用。