docs: update js api docs
[project/luci.git] / docs / jsapi / form.js.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>Source: form.js</title>
6
7
8 <script src="scripts/prettify/prettify.js"></script>
9 <script src="scripts/prettify/lang-css.js"></script>
10 <script src="scripts/jquery.min.js"></script>
11 <!--[if lt IE 9]>
12 <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13 <![endif]-->
14 <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
15 <link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
16 <link type="text/css" rel="stylesheet" href="styles/jaguar.css">
17
18
19 <script>
20 var config = {"monospaceLinks":true,"cleverLinks":true,"default":{"outputSourceFiles":true}};
21 </script>
22
23
24
25 </head>
26 <body>
27 <div id="wrap" class="clearfix">
28
29 <div class="navigation">
30 <h3 class="applicationName"><a href="index.html"></a></h3>
31
32 <div class="search">
33 <input id="search" type="text" class="form-control input-sm" placeholder="Search Documentations">
34 </div>
35 <ul class="list">
36
37 <li class="item" data-name="LuCI">
38 <span class="title">
39 <a href="LuCI.html">LuCI</a>
40
41 </span>
42 <ul class="members itemMembers">
43
44 <span class="subtitle">Members</span>
45
46 <li data-name="LuCI#Class"><a href="LuCI.html#Class">Class</a></li>
47
48 <li data-name="LuCI#dom"><a href="LuCI.html#dom">dom</a></li>
49
50 <li data-name="LuCI#env"><a href="LuCI.html#env">env</a></li>
51
52 <li data-name="LuCI#Poll"><a href="LuCI.html#Poll">Poll</a></li>
53
54 <li data-name="LuCI#Request"><a href="LuCI.html#Request">Request</a></li>
55
56 <li data-name="LuCI#view"><a href="LuCI.html#view">view</a></li>
57
58 </ul>
59 <ul class="typedefs itemMembers">
60
61 <span class="subtitle">Typedefs</span>
62
63 <li data-name="LuCI.requestCallbackFn"><a href="LuCI.html#.requestCallbackFn">requestCallbackFn</a></li>
64
65 </ul>
66 <ul class="typedefs itemMembers">
67
68 </ul>
69 <ul class="methods itemMembers">
70
71 <span class="subtitle">Methods</span>
72
73 <li data-name="LuCI#bind"><a href="LuCI.html#bind">bind</a></li>
74
75 <li data-name="LuCI#error"><a href="LuCI.html#error">error</a></li>
76
77 <li data-name="LuCI#fspath"><a href="LuCI.html#fspath">fspath</a></li>
78
79 <li data-name="LuCI#get"><a href="LuCI.html#get">get</a></li>
80
81 <li data-name="LuCI#halt"><a href="LuCI.html#halt">halt</a></li>
82
83 <li data-name="LuCI#hasSystemFeature"><a href="LuCI.html#hasSystemFeature">hasSystemFeature</a></li>
84
85 <li data-name="LuCI#hasViewPermission"><a href="LuCI.html#hasViewPermission">hasViewPermission</a></li>
86
87 <li data-name="LuCI#isObject"><a href="LuCI.html#isObject">isObject</a></li>
88
89 <li data-name="LuCI#location"><a href="LuCI.html#location">location</a></li>
90
91 <li data-name="LuCI#media"><a href="LuCI.html#media">media</a></li>
92
93 <li data-name="LuCI#path"><a href="LuCI.html#path">path</a></li>
94
95 <li data-name="LuCI#poll"><a href="LuCI.html#poll">poll</a></li>
96
97 <li data-name="LuCI#post"><a href="LuCI.html#post">post</a></li>
98
99 <li data-name="LuCI#raise"><a href="LuCI.html#raise">raise</a></li>
100
101 <li data-name="LuCI#require"><a href="LuCI.html#require">require</a></li>
102
103 <li data-name="LuCI#resolveDefault"><a href="LuCI.html#resolveDefault">resolveDefault</a></li>
104
105 <li data-name="LuCI#resource"><a href="LuCI.html#resource">resource</a></li>
106
107 <li data-name="LuCI#run"><a href="LuCI.html#run">run</a></li>
108
109 <li data-name="LuCI#sortedKeys"><a href="LuCI.html#sortedKeys">sortedKeys</a></li>
110
111 <li data-name="LuCI#stop"><a href="LuCI.html#stop">stop</a></li>
112
113 <li data-name="LuCI#toArray"><a href="LuCI.html#toArray">toArray</a></li>
114
115 <li data-name="LuCI#url"><a href="LuCI.html#url">url</a></li>
116
117 </ul>
118 <ul class="events itemMembers">
119
120 </ul>
121 </li>
122
123 <li class="item" data-name="LuCI.baseclass">
124 <span class="title">
125 <a href="LuCI.baseclass.html">LuCI.baseclass</a>
126
127 </span>
128 <ul class="members itemMembers">
129
130 </ul>
131 <ul class="typedefs itemMembers">
132
133 </ul>
134 <ul class="typedefs itemMembers">
135
136 </ul>
137 <ul class="methods itemMembers">
138
139 <span class="subtitle">Methods</span>
140
141 <li data-name="LuCI.baseclass.extend"><a href="LuCI.baseclass.html#.extend">extend</a></li>
142
143 <li data-name="LuCI.baseclass.instantiate"><a href="LuCI.baseclass.html#.instantiate">instantiate</a></li>
144
145 <li data-name="LuCI.baseclass.isSubclass"><a href="LuCI.baseclass.html#.isSubclass">isSubclass</a></li>
146
147 <li data-name="LuCI.baseclass.singleton"><a href="LuCI.baseclass.html#.singleton">singleton</a></li>
148
149 <li data-name="LuCI.baseclass#super"><a href="LuCI.baseclass.html#super">super</a></li>
150
151 <li data-name="LuCI.baseclass#varargs"><a href="LuCI.baseclass.html#varargs">varargs</a></li>
152
153 </ul>
154 <ul class="events itemMembers">
155
156 </ul>
157 </li>
158
159 <li class="item" data-name="LuCI.dom">
160 <span class="title">
161 <a href="LuCI.dom.html">LuCI.dom</a>
162
163 </span>
164 <ul class="members itemMembers">
165
166 </ul>
167 <ul class="typedefs itemMembers">
168
169 <span class="subtitle">Typedefs</span>
170
171 <li data-name="LuCI.dom~ignoreCallbackFn"><a href="LuCI.dom.html#~ignoreCallbackFn">ignoreCallbackFn</a></li>
172
173 </ul>
174 <ul class="typedefs itemMembers">
175
176 </ul>
177 <ul class="methods itemMembers">
178
179 <span class="subtitle">Methods</span>
180
181 <li data-name="LuCI.dom#append"><a href="LuCI.dom.html#append">append</a></li>
182
183 <li data-name="LuCI.dom#attr"><a href="LuCI.dom.html#attr">attr</a></li>
184
185 <li data-name="LuCI.dom#bindClassInstance"><a href="LuCI.dom.html#bindClassInstance">bindClassInstance</a></li>
186
187 <li data-name="LuCI.dom#callClassMethod"><a href="LuCI.dom.html#callClassMethod">callClassMethod</a></li>
188
189 <li data-name="LuCI.dom#content"><a href="LuCI.dom.html#content">content</a></li>
190
191 <li data-name="LuCI.dom#create"><a href="LuCI.dom.html#create">create</a></li>
192
193 <li data-name="LuCI.dom#data"><a href="LuCI.dom.html#data">data</a></li>
194
195 <li data-name="LuCI.dom#elem"><a href="LuCI.dom.html#elem">elem</a></li>
196
197 <li data-name="LuCI.dom#findClassInstance"><a href="LuCI.dom.html#findClassInstance">findClassInstance</a></li>
198
199 <li data-name="LuCI.dom#isEmpty"><a href="LuCI.dom.html#isEmpty">isEmpty</a></li>
200
201 <li data-name="LuCI.dom#matches"><a href="LuCI.dom.html#matches">matches</a></li>
202
203 <li data-name="LuCI.dom#parent"><a href="LuCI.dom.html#parent">parent</a></li>
204
205 <li data-name="LuCI.dom#parse"><a href="LuCI.dom.html#parse">parse</a></li>
206
207 </ul>
208 <ul class="events itemMembers">
209
210 </ul>
211 </li>
212
213 <li class="item" data-name="LuCI.form">
214 <span class="title">
215 <a href="LuCI.form.html">LuCI.form</a>
216
217 </span>
218 <ul class="members itemMembers">
219
220 </ul>
221 <ul class="typedefs itemMembers">
222
223 </ul>
224 <ul class="typedefs itemMembers">
225
226 </ul>
227 <ul class="methods itemMembers">
228
229 </ul>
230 <ul class="events itemMembers">
231
232 </ul>
233 </li>
234
235 <li class="item" data-name="LuCI.form.AbstractElement">
236 <span class="title">
237 <a href="LuCI.form.AbstractElement.html">LuCI.form.AbstractElement</a>
238
239 </span>
240 <ul class="members itemMembers">
241
242 </ul>
243 <ul class="typedefs itemMembers">
244
245 </ul>
246 <ul class="typedefs itemMembers">
247
248 </ul>
249 <ul class="methods itemMembers">
250
251 <span class="subtitle">Methods</span>
252
253 <li data-name="LuCI.form.AbstractElement#append"><a href="LuCI.form.AbstractElement.html#append">append</a></li>
254
255 <li data-name="LuCI.form.AbstractElement#parse"><a href="LuCI.form.AbstractElement.html#parse">parse</a></li>
256
257 <li data-name="LuCI.form.AbstractElement#render"><a href="LuCI.form.AbstractElement.html#render">render</a></li>
258
259 <li data-name="LuCI.form.AbstractElement#stripTags"><a href="LuCI.form.AbstractElement.html#stripTags">stripTags</a></li>
260
261 <li data-name="LuCI.form.AbstractElement#titleFn"><a href="LuCI.form.AbstractElement.html#titleFn">titleFn</a></li>
262
263 </ul>
264 <ul class="events itemMembers">
265
266 </ul>
267 </li>
268
269 <li class="item" data-name="LuCI.form.AbstractSection">
270 <span class="title">
271 <a href="LuCI.form.AbstractSection.html">LuCI.form.AbstractSection</a>
272
273 </span>
274 <ul class="members itemMembers">
275
276 <span class="subtitle">Members</span>
277
278 <li data-name="LuCI.form.AbstractSection##parentoption"><a href="LuCI.form.AbstractSection.html#parentoption">parentoption</a></li>
279
280 </ul>
281 <ul class="typedefs itemMembers">
282
283 </ul>
284 <ul class="typedefs itemMembers">
285
286 </ul>
287 <ul class="methods itemMembers">
288
289 <span class="subtitle">Methods</span>
290
291 <li data-name="LuCI.form.AbstractSection#append"><a href="LuCI.form.AbstractSection.html#append">append</a></li>
292
293 <li data-name="LuCI.form.AbstractSection#cfgsections"><a href="LuCI.form.AbstractSection.html#cfgsections">cfgsections</a></li>
294
295 <li data-name="LuCI.form.AbstractSection#cfgvalue"><a href="LuCI.form.AbstractSection.html#cfgvalue">cfgvalue</a></li>
296
297 <li data-name="LuCI.form.AbstractSection#filter"><a href="LuCI.form.AbstractSection.html#filter">filter</a></li>
298
299 <li data-name="LuCI.form.AbstractSection#formvalue"><a href="LuCI.form.AbstractSection.html#formvalue">formvalue</a></li>
300
301 <li data-name="LuCI.form.AbstractSection#getOption"><a href="LuCI.form.AbstractSection.html#getOption">getOption</a></li>
302
303 <li data-name="LuCI.form.AbstractSection#getUIElement"><a href="LuCI.form.AbstractSection.html#getUIElement">getUIElement</a></li>
304
305 <li data-name="LuCI.form.AbstractSection#load"><a href="LuCI.form.AbstractSection.html#load">load</a></li>
306
307 <li data-name="LuCI.form.AbstractSection#option"><a href="LuCI.form.AbstractSection.html#option">option</a></li>
308
309 <li data-name="LuCI.form.AbstractSection#parse"><a href="LuCI.form.AbstractSection.html#parse">parse</a></li>
310
311 <li data-name="LuCI.form.AbstractSection#render"><a href="LuCI.form.AbstractSection.html#render">render</a></li>
312
313 <li data-name="LuCI.form.AbstractSection#stripTags"><a href="LuCI.form.AbstractSection.html#stripTags">stripTags</a></li>
314
315 <li data-name="LuCI.form.AbstractSection#tab"><a href="LuCI.form.AbstractSection.html#tab">tab</a></li>
316
317 <li data-name="LuCI.form.AbstractSection#taboption"><a href="LuCI.form.AbstractSection.html#taboption">taboption</a></li>
318
319 <li data-name="LuCI.form.AbstractSection#titleFn"><a href="LuCI.form.AbstractSection.html#titleFn">titleFn</a></li>
320
321 </ul>
322 <ul class="events itemMembers">
323
324 </ul>
325 </li>
326
327 <li class="item" data-name="LuCI.form.AbstractValue">
328 <span class="title">
329 <a href="LuCI.form.AbstractValue.html">LuCI.form.AbstractValue</a>
330
331 </span>
332 <ul class="members itemMembers">
333
334 <span class="subtitle">Members</span>
335
336 <li data-name="LuCI.form.AbstractValue##datatype"><a href="LuCI.form.AbstractValue.html#datatype">datatype</a></li>
337
338 <li data-name="LuCI.form.AbstractValue##default"><a href="LuCI.form.AbstractValue.html#default">default</a></li>
339
340 <li data-name="LuCI.form.AbstractValue##editable"><a href="LuCI.form.AbstractValue.html#editable">editable</a></li>
341
342 <li data-name="LuCI.form.AbstractValue##modalonly"><a href="LuCI.form.AbstractValue.html#modalonly">modalonly</a></li>
343
344 <li data-name="LuCI.form.AbstractValue##onchange"><a href="LuCI.form.AbstractValue.html#onchange">onchange</a></li>
345
346 <li data-name="LuCI.form.AbstractValue##optional"><a href="LuCI.form.AbstractValue.html#optional">optional</a></li>
347
348 <li data-name="LuCI.form.AbstractValue##readonly"><a href="LuCI.form.AbstractValue.html#readonly">readonly</a></li>
349
350 <li data-name="LuCI.form.AbstractValue##rmempty"><a href="LuCI.form.AbstractValue.html#rmempty">rmempty</a></li>
351
352 <li data-name="LuCI.form.AbstractValue##uciconfig"><a href="LuCI.form.AbstractValue.html#uciconfig">uciconfig</a></li>
353
354 <li data-name="LuCI.form.AbstractValue##ucioption"><a href="LuCI.form.AbstractValue.html#ucioption">ucioption</a></li>
355
356 <li data-name="LuCI.form.AbstractValue##ucisection"><a href="LuCI.form.AbstractValue.html#ucisection">ucisection</a></li>
357
358 <li data-name="LuCI.form.AbstractValue##validate"><a href="LuCI.form.AbstractValue.html#validate">validate</a></li>
359
360 <li data-name="LuCI.form.AbstractValue##width"><a href="LuCI.form.AbstractValue.html#width">width</a></li>
361
362 </ul>
363 <ul class="typedefs itemMembers">
364
365 </ul>
366 <ul class="typedefs itemMembers">
367
368 </ul>
369 <ul class="methods itemMembers">
370
371 <span class="subtitle">Methods</span>
372
373 <li data-name="LuCI.form.AbstractValue#append"><a href="LuCI.form.AbstractValue.html#append">append</a></li>
374
375 <li data-name="LuCI.form.AbstractValue#cbid"><a href="LuCI.form.AbstractValue.html#cbid">cbid</a></li>
376
377 <li data-name="LuCI.form.AbstractValue#cfgvalue"><a href="LuCI.form.AbstractValue.html#cfgvalue">cfgvalue</a></li>
378
379 <li data-name="LuCI.form.AbstractValue#depends"><a href="LuCI.form.AbstractValue.html#depends">depends</a></li>
380
381 <li data-name="LuCI.form.AbstractValue#formvalue"><a href="LuCI.form.AbstractValue.html#formvalue">formvalue</a></li>
382
383 <li data-name="LuCI.form.AbstractValue#getUIElement"><a href="LuCI.form.AbstractValue.html#getUIElement">getUIElement</a></li>
384
385 <li data-name="LuCI.form.AbstractValue#isActive"><a href="LuCI.form.AbstractValue.html#isActive">isActive</a></li>
386
387 <li data-name="LuCI.form.AbstractValue#isValid"><a href="LuCI.form.AbstractValue.html#isValid">isValid</a></li>
388
389 <li data-name="LuCI.form.AbstractValue#load"><a href="LuCI.form.AbstractValue.html#load">load</a></li>
390
391 <li data-name="LuCI.form.AbstractValue#parse"><a href="LuCI.form.AbstractValue.html#parse">parse</a></li>
392
393 <li data-name="LuCI.form.AbstractValue#remove"><a href="LuCI.form.AbstractValue.html#remove">remove</a></li>
394
395 <li data-name="LuCI.form.AbstractValue#render"><a href="LuCI.form.AbstractValue.html#render">render</a></li>
396
397 <li data-name="LuCI.form.AbstractValue#stripTags"><a href="LuCI.form.AbstractValue.html#stripTags">stripTags</a></li>
398
399 <li data-name="LuCI.form.AbstractValue#textvalue"><a href="LuCI.form.AbstractValue.html#textvalue">textvalue</a></li>
400
401 <li data-name="LuCI.form.AbstractValue#titleFn"><a href="LuCI.form.AbstractValue.html#titleFn">titleFn</a></li>
402
403 <li data-name="LuCI.form.AbstractValue#validate"><a href="LuCI.form.AbstractValue.html#validate">validate</a></li>
404
405 <li data-name="LuCI.form.AbstractValue#write"><a href="LuCI.form.AbstractValue.html#write">write</a></li>
406
407 </ul>
408 <ul class="events itemMembers">
409
410 </ul>
411 </li>
412
413 <li class="item" data-name="LuCI.form.ButtonValue">
414 <span class="title">
415 <a href="LuCI.form.ButtonValue.html">LuCI.form.ButtonValue</a>
416
417 </span>
418 <ul class="members itemMembers">
419
420 <span class="subtitle">Members</span>
421
422 <li data-name="LuCI.form.ButtonValue##inputstyle"><a href="LuCI.form.ButtonValue.html#inputstyle">inputstyle</a></li>
423
424 <li data-name="LuCI.form.ButtonValue##inputtitle"><a href="LuCI.form.ButtonValue.html#inputtitle">inputtitle</a></li>
425
426 <li data-name="LuCI.form.ButtonValue##onclick"><a href="LuCI.form.ButtonValue.html#onclick">onclick</a></li>
427
428 <li data-name="LuCI.form.ButtonValue#datatype"><a href="LuCI.form.ButtonValue.html#datatype">datatype</a></li>
429
430 <li data-name="LuCI.form.ButtonValue#default"><a href="LuCI.form.ButtonValue.html#default">default</a></li>
431
432 <li data-name="LuCI.form.ButtonValue#editable"><a href="LuCI.form.ButtonValue.html#editable">editable</a></li>
433
434 <li data-name="LuCI.form.ButtonValue#modalonly"><a href="LuCI.form.ButtonValue.html#modalonly">modalonly</a></li>
435
436 <li data-name="LuCI.form.ButtonValue#onchange"><a href="LuCI.form.ButtonValue.html#onchange">onchange</a></li>
437
438 <li data-name="LuCI.form.ButtonValue#optional"><a href="LuCI.form.ButtonValue.html#optional">optional</a></li>
439
440 <li data-name="LuCI.form.ButtonValue#password"><a href="LuCI.form.ButtonValue.html#password">password</a></li>
441
442 <li data-name="LuCI.form.ButtonValue#placeholder"><a href="LuCI.form.ButtonValue.html#placeholder">placeholder</a></li>
443
444 <li data-name="LuCI.form.ButtonValue#readonly"><a href="LuCI.form.ButtonValue.html#readonly">readonly</a></li>
445
446 <li data-name="LuCI.form.ButtonValue#rmempty"><a href="LuCI.form.ButtonValue.html#rmempty">rmempty</a></li>
447
448 <li data-name="LuCI.form.ButtonValue#uciconfig"><a href="LuCI.form.ButtonValue.html#uciconfig">uciconfig</a></li>
449
450 <li data-name="LuCI.form.ButtonValue#ucioption"><a href="LuCI.form.ButtonValue.html#ucioption">ucioption</a></li>
451
452 <li data-name="LuCI.form.ButtonValue#ucisection"><a href="LuCI.form.ButtonValue.html#ucisection">ucisection</a></li>
453
454 <li data-name="LuCI.form.ButtonValue#validate"><a href="LuCI.form.ButtonValue.html#validate">validate</a></li>
455
456 <li data-name="LuCI.form.ButtonValue#width"><a href="LuCI.form.ButtonValue.html#width">width</a></li>
457
458 </ul>
459 <ul class="typedefs itemMembers">
460
461 </ul>
462 <ul class="typedefs itemMembers">
463
464 </ul>
465 <ul class="methods itemMembers">
466
467 <span class="subtitle">Methods</span>
468
469 <li data-name="LuCI.form.ButtonValue#append"><a href="LuCI.form.ButtonValue.html#append">append</a></li>
470
471 <li data-name="LuCI.form.ButtonValue#cbid"><a href="LuCI.form.ButtonValue.html#cbid">cbid</a></li>
472
473 <li data-name="LuCI.form.ButtonValue#cfgvalue"><a href="LuCI.form.ButtonValue.html#cfgvalue">cfgvalue</a></li>
474
475 <li data-name="LuCI.form.ButtonValue#depends"><a href="LuCI.form.ButtonValue.html#depends">depends</a></li>
476
477 <li data-name="LuCI.form.ButtonValue#formvalue"><a href="LuCI.form.ButtonValue.html#formvalue">formvalue</a></li>
478
479 <li data-name="LuCI.form.ButtonValue#getUIElement"><a href="LuCI.form.ButtonValue.html#getUIElement">getUIElement</a></li>
480
481 <li data-name="LuCI.form.ButtonValue#isActive"><a href="LuCI.form.ButtonValue.html#isActive">isActive</a></li>
482
483 <li data-name="LuCI.form.ButtonValue#isValid"><a href="LuCI.form.ButtonValue.html#isValid">isValid</a></li>
484
485 <li data-name="LuCI.form.ButtonValue#load"><a href="LuCI.form.ButtonValue.html#load">load</a></li>
486
487 <li data-name="LuCI.form.ButtonValue#parse"><a href="LuCI.form.ButtonValue.html#parse">parse</a></li>
488
489 <li data-name="LuCI.form.ButtonValue#remove"><a href="LuCI.form.ButtonValue.html#remove">remove</a></li>
490
491 <li data-name="LuCI.form.ButtonValue#stripTags"><a href="LuCI.form.ButtonValue.html#stripTags">stripTags</a></li>
492
493 <li data-name="LuCI.form.ButtonValue#textvalue"><a href="LuCI.form.ButtonValue.html#textvalue">textvalue</a></li>
494
495 <li data-name="LuCI.form.ButtonValue#titleFn"><a href="LuCI.form.ButtonValue.html#titleFn">titleFn</a></li>
496
497 <li data-name="LuCI.form.ButtonValue#value"><a href="LuCI.form.ButtonValue.html#value">value</a></li>
498
499 <li data-name="LuCI.form.ButtonValue#write"><a href="LuCI.form.ButtonValue.html#write">write</a></li>
500
501 </ul>
502 <ul class="events itemMembers">
503
504 </ul>
505 </li>
506
507 <li class="item" data-name="LuCI.form.DummyValue">
508 <span class="title">
509 <a href="LuCI.form.DummyValue.html">LuCI.form.DummyValue</a>
510
511 </span>
512 <ul class="members itemMembers">
513
514 <span class="subtitle">Members</span>
515
516 <li data-name="LuCI.form.DummyValue##href"><a href="LuCI.form.DummyValue.html#href">href</a></li>
517
518 <li data-name="LuCI.form.DummyValue##rawhtml"><a href="LuCI.form.DummyValue.html#rawhtml">rawhtml</a></li>
519
520 <li data-name="LuCI.form.DummyValue#datatype"><a href="LuCI.form.DummyValue.html#datatype">datatype</a></li>
521
522 <li data-name="LuCI.form.DummyValue#default"><a href="LuCI.form.DummyValue.html#default">default</a></li>
523
524 <li data-name="LuCI.form.DummyValue#editable"><a href="LuCI.form.DummyValue.html#editable">editable</a></li>
525
526 <li data-name="LuCI.form.DummyValue#modalonly"><a href="LuCI.form.DummyValue.html#modalonly">modalonly</a></li>
527
528 <li data-name="LuCI.form.DummyValue#onchange"><a href="LuCI.form.DummyValue.html#onchange">onchange</a></li>
529
530 <li data-name="LuCI.form.DummyValue#optional"><a href="LuCI.form.DummyValue.html#optional">optional</a></li>
531
532 <li data-name="LuCI.form.DummyValue#password"><a href="LuCI.form.DummyValue.html#password">password</a></li>
533
534 <li data-name="LuCI.form.DummyValue#placeholder"><a href="LuCI.form.DummyValue.html#placeholder">placeholder</a></li>
535
536 <li data-name="LuCI.form.DummyValue#readonly"><a href="LuCI.form.DummyValue.html#readonly">readonly</a></li>
537
538 <li data-name="LuCI.form.DummyValue#rmempty"><a href="LuCI.form.DummyValue.html#rmempty">rmempty</a></li>
539
540 <li data-name="LuCI.form.DummyValue#uciconfig"><a href="LuCI.form.DummyValue.html#uciconfig">uciconfig</a></li>
541
542 <li data-name="LuCI.form.DummyValue#ucioption"><a href="LuCI.form.DummyValue.html#ucioption">ucioption</a></li>
543
544 <li data-name="LuCI.form.DummyValue#ucisection"><a href="LuCI.form.DummyValue.html#ucisection">ucisection</a></li>
545
546 <li data-name="LuCI.form.DummyValue#validate"><a href="LuCI.form.DummyValue.html#validate">validate</a></li>
547
548 <li data-name="LuCI.form.DummyValue#width"><a href="LuCI.form.DummyValue.html#width">width</a></li>
549
550 </ul>
551 <ul class="typedefs itemMembers">
552
553 </ul>
554 <ul class="typedefs itemMembers">
555
556 </ul>
557 <ul class="methods itemMembers">
558
559 <span class="subtitle">Methods</span>
560
561 <li data-name="LuCI.form.DummyValue#append"><a href="LuCI.form.DummyValue.html#append">append</a></li>
562
563 <li data-name="LuCI.form.DummyValue#cbid"><a href="LuCI.form.DummyValue.html#cbid">cbid</a></li>
564
565 <li data-name="LuCI.form.DummyValue#cfgvalue"><a href="LuCI.form.DummyValue.html#cfgvalue">cfgvalue</a></li>
566
567 <li data-name="LuCI.form.DummyValue#depends"><a href="LuCI.form.DummyValue.html#depends">depends</a></li>
568
569 <li data-name="LuCI.form.DummyValue#formvalue"><a href="LuCI.form.DummyValue.html#formvalue">formvalue</a></li>
570
571 <li data-name="LuCI.form.DummyValue#getUIElement"><a href="LuCI.form.DummyValue.html#getUIElement">getUIElement</a></li>
572
573 <li data-name="LuCI.form.DummyValue#isActive"><a href="LuCI.form.DummyValue.html#isActive">isActive</a></li>
574
575 <li data-name="LuCI.form.DummyValue#isValid"><a href="LuCI.form.DummyValue.html#isValid">isValid</a></li>
576
577 <li data-name="LuCI.form.DummyValue#load"><a href="LuCI.form.DummyValue.html#load">load</a></li>
578
579 <li data-name="LuCI.form.DummyValue#parse"><a href="LuCI.form.DummyValue.html#parse">parse</a></li>
580
581 <li data-name="LuCI.form.DummyValue#remove"><a href="LuCI.form.DummyValue.html#remove">remove</a></li>
582
583 <li data-name="LuCI.form.DummyValue#stripTags"><a href="LuCI.form.DummyValue.html#stripTags">stripTags</a></li>
584
585 <li data-name="LuCI.form.DummyValue#textvalue"><a href="LuCI.form.DummyValue.html#textvalue">textvalue</a></li>
586
587 <li data-name="LuCI.form.DummyValue#titleFn"><a href="LuCI.form.DummyValue.html#titleFn">titleFn</a></li>
588
589 <li data-name="LuCI.form.DummyValue#value"><a href="LuCI.form.DummyValue.html#value">value</a></li>
590
591 <li data-name="LuCI.form.DummyValue#write"><a href="LuCI.form.DummyValue.html#write">write</a></li>
592
593 </ul>
594 <ul class="events itemMembers">
595
596 </ul>
597 </li>
598
599 <li class="item" data-name="LuCI.form.DynamicList">
600 <span class="title">
601 <a href="LuCI.form.DynamicList.html">LuCI.form.DynamicList</a>
602
603 </span>
604 <ul class="members itemMembers">
605
606 <span class="subtitle">Members</span>
607
608 <li data-name="LuCI.form.DynamicList#datatype"><a href="LuCI.form.DynamicList.html#datatype">datatype</a></li>
609
610 <li data-name="LuCI.form.DynamicList#default"><a href="LuCI.form.DynamicList.html#default">default</a></li>
611
612 <li data-name="LuCI.form.DynamicList#editable"><a href="LuCI.form.DynamicList.html#editable">editable</a></li>
613
614 <li data-name="LuCI.form.DynamicList#modalonly"><a href="LuCI.form.DynamicList.html#modalonly">modalonly</a></li>
615
616 <li data-name="LuCI.form.DynamicList#onchange"><a href="LuCI.form.DynamicList.html#onchange">onchange</a></li>
617
618 <li data-name="LuCI.form.DynamicList#optional"><a href="LuCI.form.DynamicList.html#optional">optional</a></li>
619
620 <li data-name="LuCI.form.DynamicList#password"><a href="LuCI.form.DynamicList.html#password">password</a></li>
621
622 <li data-name="LuCI.form.DynamicList#placeholder"><a href="LuCI.form.DynamicList.html#placeholder">placeholder</a></li>
623
624 <li data-name="LuCI.form.DynamicList#readonly"><a href="LuCI.form.DynamicList.html#readonly">readonly</a></li>
625
626 <li data-name="LuCI.form.DynamicList#rmempty"><a href="LuCI.form.DynamicList.html#rmempty">rmempty</a></li>
627
628 <li data-name="LuCI.form.DynamicList#uciconfig"><a href="LuCI.form.DynamicList.html#uciconfig">uciconfig</a></li>
629
630 <li data-name="LuCI.form.DynamicList#ucioption"><a href="LuCI.form.DynamicList.html#ucioption">ucioption</a></li>
631
632 <li data-name="LuCI.form.DynamicList#ucisection"><a href="LuCI.form.DynamicList.html#ucisection">ucisection</a></li>
633
634 <li data-name="LuCI.form.DynamicList#validate"><a href="LuCI.form.DynamicList.html#validate">validate</a></li>
635
636 <li data-name="LuCI.form.DynamicList#width"><a href="LuCI.form.DynamicList.html#width">width</a></li>
637
638 </ul>
639 <ul class="typedefs itemMembers">
640
641 </ul>
642 <ul class="typedefs itemMembers">
643
644 </ul>
645 <ul class="methods itemMembers">
646
647 <span class="subtitle">Methods</span>
648
649 <li data-name="LuCI.form.DynamicList#append"><a href="LuCI.form.DynamicList.html#append">append</a></li>
650
651 <li data-name="LuCI.form.DynamicList#cbid"><a href="LuCI.form.DynamicList.html#cbid">cbid</a></li>
652
653 <li data-name="LuCI.form.DynamicList#cfgvalue"><a href="LuCI.form.DynamicList.html#cfgvalue">cfgvalue</a></li>
654
655 <li data-name="LuCI.form.DynamicList#depends"><a href="LuCI.form.DynamicList.html#depends">depends</a></li>
656
657 <li data-name="LuCI.form.DynamicList#formvalue"><a href="LuCI.form.DynamicList.html#formvalue">formvalue</a></li>
658
659 <li data-name="LuCI.form.DynamicList#getUIElement"><a href="LuCI.form.DynamicList.html#getUIElement">getUIElement</a></li>
660
661 <li data-name="LuCI.form.DynamicList#isActive"><a href="LuCI.form.DynamicList.html#isActive">isActive</a></li>
662
663 <li data-name="LuCI.form.DynamicList#isValid"><a href="LuCI.form.DynamicList.html#isValid">isValid</a></li>
664
665 <li data-name="LuCI.form.DynamicList#load"><a href="LuCI.form.DynamicList.html#load">load</a></li>
666
667 <li data-name="LuCI.form.DynamicList#parse"><a href="LuCI.form.DynamicList.html#parse">parse</a></li>
668
669 <li data-name="LuCI.form.DynamicList#remove"><a href="LuCI.form.DynamicList.html#remove">remove</a></li>
670
671 <li data-name="LuCI.form.DynamicList#stripTags"><a href="LuCI.form.DynamicList.html#stripTags">stripTags</a></li>
672
673 <li data-name="LuCI.form.DynamicList#textvalue"><a href="LuCI.form.DynamicList.html#textvalue">textvalue</a></li>
674
675 <li data-name="LuCI.form.DynamicList#titleFn"><a href="LuCI.form.DynamicList.html#titleFn">titleFn</a></li>
676
677 <li data-name="LuCI.form.DynamicList#value"><a href="LuCI.form.DynamicList.html#value">value</a></li>
678
679 <li data-name="LuCI.form.DynamicList#write"><a href="LuCI.form.DynamicList.html#write">write</a></li>
680
681 </ul>
682 <ul class="events itemMembers">
683
684 </ul>
685 </li>
686
687 <li class="item" data-name="LuCI.form.FileUpload">
688 <span class="title">
689 <a href="LuCI.form.FileUpload.html">LuCI.form.FileUpload</a>
690
691 </span>
692 <ul class="members itemMembers">
693
694 <span class="subtitle">Members</span>
695
696 <li data-name="LuCI.form.FileUpload##enable_remove"><a href="LuCI.form.FileUpload.html#enable_remove">enable_remove</a></li>
697
698 <li data-name="LuCI.form.FileUpload##enable_upload"><a href="LuCI.form.FileUpload.html#enable_upload">enable_upload</a></li>
699
700 <li data-name="LuCI.form.FileUpload##root_directory"><a href="LuCI.form.FileUpload.html#root_directory">root_directory</a></li>
701
702 <li data-name="LuCI.form.FileUpload##show_hidden"><a href="LuCI.form.FileUpload.html#show_hidden">show_hidden</a></li>
703
704 <li data-name="LuCI.form.FileUpload#datatype"><a href="LuCI.form.FileUpload.html#datatype">datatype</a></li>
705
706 <li data-name="LuCI.form.FileUpload#default"><a href="LuCI.form.FileUpload.html#default">default</a></li>
707
708 <li data-name="LuCI.form.FileUpload#editable"><a href="LuCI.form.FileUpload.html#editable">editable</a></li>
709
710 <li data-name="LuCI.form.FileUpload#modalonly"><a href="LuCI.form.FileUpload.html#modalonly">modalonly</a></li>
711
712 <li data-name="LuCI.form.FileUpload#onchange"><a href="LuCI.form.FileUpload.html#onchange">onchange</a></li>
713
714 <li data-name="LuCI.form.FileUpload#optional"><a href="LuCI.form.FileUpload.html#optional">optional</a></li>
715
716 <li data-name="LuCI.form.FileUpload#password"><a href="LuCI.form.FileUpload.html#password">password</a></li>
717
718 <li data-name="LuCI.form.FileUpload#placeholder"><a href="LuCI.form.FileUpload.html#placeholder">placeholder</a></li>
719
720 <li data-name="LuCI.form.FileUpload#readonly"><a href="LuCI.form.FileUpload.html#readonly">readonly</a></li>
721
722 <li data-name="LuCI.form.FileUpload#rmempty"><a href="LuCI.form.FileUpload.html#rmempty">rmempty</a></li>
723
724 <li data-name="LuCI.form.FileUpload#uciconfig"><a href="LuCI.form.FileUpload.html#uciconfig">uciconfig</a></li>
725
726 <li data-name="LuCI.form.FileUpload#ucioption"><a href="LuCI.form.FileUpload.html#ucioption">ucioption</a></li>
727
728 <li data-name="LuCI.form.FileUpload#ucisection"><a href="LuCI.form.FileUpload.html#ucisection">ucisection</a></li>
729
730 <li data-name="LuCI.form.FileUpload#validate"><a href="LuCI.form.FileUpload.html#validate">validate</a></li>
731
732 <li data-name="LuCI.form.FileUpload#width"><a href="LuCI.form.FileUpload.html#width">width</a></li>
733
734 </ul>
735 <ul class="typedefs itemMembers">
736
737 </ul>
738 <ul class="typedefs itemMembers">
739
740 </ul>
741 <ul class="methods itemMembers">
742
743 <span class="subtitle">Methods</span>
744
745 <li data-name="LuCI.form.FileUpload#append"><a href="LuCI.form.FileUpload.html#append">append</a></li>
746
747 <li data-name="LuCI.form.FileUpload#cbid"><a href="LuCI.form.FileUpload.html#cbid">cbid</a></li>
748
749 <li data-name="LuCI.form.FileUpload#cfgvalue"><a href="LuCI.form.FileUpload.html#cfgvalue">cfgvalue</a></li>
750
751 <li data-name="LuCI.form.FileUpload#depends"><a href="LuCI.form.FileUpload.html#depends">depends</a></li>
752
753 <li data-name="LuCI.form.FileUpload#formvalue"><a href="LuCI.form.FileUpload.html#formvalue">formvalue</a></li>
754
755 <li data-name="LuCI.form.FileUpload#getUIElement"><a href="LuCI.form.FileUpload.html#getUIElement">getUIElement</a></li>
756
757 <li data-name="LuCI.form.FileUpload#isActive"><a href="LuCI.form.FileUpload.html#isActive">isActive</a></li>
758
759 <li data-name="LuCI.form.FileUpload#isValid"><a href="LuCI.form.FileUpload.html#isValid">isValid</a></li>
760
761 <li data-name="LuCI.form.FileUpload#load"><a href="LuCI.form.FileUpload.html#load">load</a></li>
762
763 <li data-name="LuCI.form.FileUpload#parse"><a href="LuCI.form.FileUpload.html#parse">parse</a></li>
764
765 <li data-name="LuCI.form.FileUpload#remove"><a href="LuCI.form.FileUpload.html#remove">remove</a></li>
766
767 <li data-name="LuCI.form.FileUpload#stripTags"><a href="LuCI.form.FileUpload.html#stripTags">stripTags</a></li>
768
769 <li data-name="LuCI.form.FileUpload#textvalue"><a href="LuCI.form.FileUpload.html#textvalue">textvalue</a></li>
770
771 <li data-name="LuCI.form.FileUpload#titleFn"><a href="LuCI.form.FileUpload.html#titleFn">titleFn</a></li>
772
773 <li data-name="LuCI.form.FileUpload#value"><a href="LuCI.form.FileUpload.html#value">value</a></li>
774
775 <li data-name="LuCI.form.FileUpload#write"><a href="LuCI.form.FileUpload.html#write">write</a></li>
776
777 </ul>
778 <ul class="events itemMembers">
779
780 </ul>
781 </li>
782
783 <li class="item" data-name="LuCI.form.FlagValue">
784 <span class="title">
785 <a href="LuCI.form.FlagValue.html">LuCI.form.FlagValue</a>
786
787 </span>
788 <ul class="members itemMembers">
789
790 <span class="subtitle">Members</span>
791
792 <li data-name="LuCI.form.FlagValue##disabled"><a href="LuCI.form.FlagValue.html#disabled">disabled</a></li>
793
794 <li data-name="LuCI.form.FlagValue##enabled"><a href="LuCI.form.FlagValue.html#enabled">enabled</a></li>
795
796 <li data-name="LuCI.form.FlagValue#datatype"><a href="LuCI.form.FlagValue.html#datatype">datatype</a></li>
797
798 <li data-name="LuCI.form.FlagValue#default"><a href="LuCI.form.FlagValue.html#default">default</a></li>
799
800 <li data-name="LuCI.form.FlagValue#editable"><a href="LuCI.form.FlagValue.html#editable">editable</a></li>
801
802 <li data-name="LuCI.form.FlagValue#modalonly"><a href="LuCI.form.FlagValue.html#modalonly">modalonly</a></li>
803
804 <li data-name="LuCI.form.FlagValue#onchange"><a href="LuCI.form.FlagValue.html#onchange">onchange</a></li>
805
806 <li data-name="LuCI.form.FlagValue#optional"><a href="LuCI.form.FlagValue.html#optional">optional</a></li>
807
808 <li data-name="LuCI.form.FlagValue#password"><a href="LuCI.form.FlagValue.html#password">password</a></li>
809
810 <li data-name="LuCI.form.FlagValue#placeholder"><a href="LuCI.form.FlagValue.html#placeholder">placeholder</a></li>
811
812 <li data-name="LuCI.form.FlagValue#readonly"><a href="LuCI.form.FlagValue.html#readonly">readonly</a></li>
813
814 <li data-name="LuCI.form.FlagValue#rmempty"><a href="LuCI.form.FlagValue.html#rmempty">rmempty</a></li>
815
816 <li data-name="LuCI.form.FlagValue#uciconfig"><a href="LuCI.form.FlagValue.html#uciconfig">uciconfig</a></li>
817
818 <li data-name="LuCI.form.FlagValue#ucioption"><a href="LuCI.form.FlagValue.html#ucioption">ucioption</a></li>
819
820 <li data-name="LuCI.form.FlagValue#ucisection"><a href="LuCI.form.FlagValue.html#ucisection">ucisection</a></li>
821
822 <li data-name="LuCI.form.FlagValue#validate"><a href="LuCI.form.FlagValue.html#validate">validate</a></li>
823
824 <li data-name="LuCI.form.FlagValue#width"><a href="LuCI.form.FlagValue.html#width">width</a></li>
825
826 </ul>
827 <ul class="typedefs itemMembers">
828
829 </ul>
830 <ul class="typedefs itemMembers">
831
832 </ul>
833 <ul class="methods itemMembers">
834
835 <span class="subtitle">Methods</span>
836
837 <li data-name="LuCI.form.FlagValue#append"><a href="LuCI.form.FlagValue.html#append">append</a></li>
838
839 <li data-name="LuCI.form.FlagValue#cbid"><a href="LuCI.form.FlagValue.html#cbid">cbid</a></li>
840
841 <li data-name="LuCI.form.FlagValue#cfgvalue"><a href="LuCI.form.FlagValue.html#cfgvalue">cfgvalue</a></li>
842
843 <li data-name="LuCI.form.FlagValue#depends"><a href="LuCI.form.FlagValue.html#depends">depends</a></li>
844
845 <li data-name="LuCI.form.FlagValue#formvalue"><a href="LuCI.form.FlagValue.html#formvalue">formvalue</a></li>
846
847 <li data-name="LuCI.form.FlagValue#getUIElement"><a href="LuCI.form.FlagValue.html#getUIElement">getUIElement</a></li>
848
849 <li data-name="LuCI.form.FlagValue#isActive"><a href="LuCI.form.FlagValue.html#isActive">isActive</a></li>
850
851 <li data-name="LuCI.form.FlagValue#isValid"><a href="LuCI.form.FlagValue.html#isValid">isValid</a></li>
852
853 <li data-name="LuCI.form.FlagValue#load"><a href="LuCI.form.FlagValue.html#load">load</a></li>
854
855 <li data-name="LuCI.form.FlagValue#parse"><a href="LuCI.form.FlagValue.html#parse">parse</a></li>
856
857 <li data-name="LuCI.form.FlagValue#remove"><a href="LuCI.form.FlagValue.html#remove">remove</a></li>
858
859 <li data-name="LuCI.form.FlagValue#stripTags"><a href="LuCI.form.FlagValue.html#stripTags">stripTags</a></li>
860
861 <li data-name="LuCI.form.FlagValue#textvalue"><a href="LuCI.form.FlagValue.html#textvalue">textvalue</a></li>
862
863 <li data-name="LuCI.form.FlagValue#titleFn"><a href="LuCI.form.FlagValue.html#titleFn">titleFn</a></li>
864
865 <li data-name="LuCI.form.FlagValue#value"><a href="LuCI.form.FlagValue.html#value">value</a></li>
866
867 <li data-name="LuCI.form.FlagValue#write"><a href="LuCI.form.FlagValue.html#write">write</a></li>
868
869 </ul>
870 <ul class="events itemMembers">
871
872 </ul>
873 </li>
874
875 <li class="item" data-name="LuCI.form.GridSection">
876 <span class="title">
877 <a href="LuCI.form.GridSection.html">LuCI.form.GridSection</a>
878
879 </span>
880 <ul class="members itemMembers">
881
882 <span class="subtitle">Members</span>
883
884 <li data-name="LuCI.form.GridSection#addbtntitle"><a href="LuCI.form.GridSection.html#addbtntitle">addbtntitle</a></li>
885
886 <li data-name="LuCI.form.GridSection#addremove"><a href="LuCI.form.GridSection.html#addremove">addremove</a></li>
887
888 <li data-name="LuCI.form.GridSection#anonymous"><a href="LuCI.form.GridSection.html#anonymous">anonymous</a></li>
889
890 <li data-name="LuCI.form.GridSection#extedit"><a href="LuCI.form.GridSection.html#extedit">extedit</a></li>
891
892 <li data-name="LuCI.form.GridSection#max_cols"><a href="LuCI.form.GridSection.html#max_cols">max_cols</a></li>
893
894 <li data-name="LuCI.form.GridSection#modaltitle"><a href="LuCI.form.GridSection.html#modaltitle">modaltitle</a></li>
895
896 <li data-name="LuCI.form.GridSection#nodescriptions"><a href="LuCI.form.GridSection.html#nodescriptions">nodescriptions</a></li>
897
898 <li data-name="LuCI.form.GridSection#parentoption"><a href="LuCI.form.GridSection.html#parentoption">parentoption</a></li>
899
900 <li data-name="LuCI.form.GridSection#rowcolors"><a href="LuCI.form.GridSection.html#rowcolors">rowcolors</a></li>
901
902 <li data-name="LuCI.form.GridSection#sectiontitle"><a href="LuCI.form.GridSection.html#sectiontitle">sectiontitle</a></li>
903
904 <li data-name="LuCI.form.GridSection#sortable"><a href="LuCI.form.GridSection.html#sortable">sortable</a></li>
905
906 <li data-name="LuCI.form.GridSection#tabbed"><a href="LuCI.form.GridSection.html#tabbed">tabbed</a></li>
907
908 <li data-name="LuCI.form.GridSection#uciconfig"><a href="LuCI.form.GridSection.html#uciconfig">uciconfig</a></li>
909
910 </ul>
911 <ul class="typedefs itemMembers">
912
913 </ul>
914 <ul class="typedefs itemMembers">
915
916 </ul>
917 <ul class="methods itemMembers">
918
919 <span class="subtitle">Methods</span>
920
921 <li data-name="LuCI.form.GridSection#addModalOptions"><a href="LuCI.form.GridSection.html#addModalOptions">addModalOptions</a></li>
922
923 <li data-name="LuCI.form.GridSection#append"><a href="LuCI.form.GridSection.html#append">append</a></li>
924
925 <li data-name="LuCI.form.GridSection#cfgvalue"><a href="LuCI.form.GridSection.html#cfgvalue">cfgvalue</a></li>
926
927 <li data-name="LuCI.form.GridSection#filter"><a href="LuCI.form.GridSection.html#filter">filter</a></li>
928
929 <li data-name="LuCI.form.GridSection#formvalue"><a href="LuCI.form.GridSection.html#formvalue">formvalue</a></li>
930
931 <li data-name="LuCI.form.GridSection#getOption"><a href="LuCI.form.GridSection.html#getOption">getOption</a></li>
932
933 <li data-name="LuCI.form.GridSection#getUIElement"><a href="LuCI.form.GridSection.html#getUIElement">getUIElement</a></li>
934
935 <li data-name="LuCI.form.GridSection#load"><a href="LuCI.form.GridSection.html#load">load</a></li>
936
937 <li data-name="LuCI.form.GridSection#option"><a href="LuCI.form.GridSection.html#option">option</a></li>
938
939 <li data-name="LuCI.form.GridSection#parse"><a href="LuCI.form.GridSection.html#parse">parse</a></li>
940
941 <li data-name="LuCI.form.GridSection#stripTags"><a href="LuCI.form.GridSection.html#stripTags">stripTags</a></li>
942
943 <li data-name="LuCI.form.GridSection#tab"><a href="LuCI.form.GridSection.html#tab">tab</a></li>
944
945 <li data-name="LuCI.form.GridSection#taboption"><a href="LuCI.form.GridSection.html#taboption">taboption</a></li>
946
947 <li data-name="LuCI.form.GridSection#titleFn"><a href="LuCI.form.GridSection.html#titleFn">titleFn</a></li>
948
949 </ul>
950 <ul class="events itemMembers">
951
952 </ul>
953 </li>
954
955 <li class="item" data-name="LuCI.form.HiddenValue">
956 <span class="title">
957 <a href="LuCI.form.HiddenValue.html">LuCI.form.HiddenValue</a>
958
959 </span>
960 <ul class="members itemMembers">
961
962 <span class="subtitle">Members</span>
963
964 <li data-name="LuCI.form.HiddenValue#datatype"><a href="LuCI.form.HiddenValue.html#datatype">datatype</a></li>
965
966 <li data-name="LuCI.form.HiddenValue#default"><a href="LuCI.form.HiddenValue.html#default">default</a></li>
967
968 <li data-name="LuCI.form.HiddenValue#editable"><a href="LuCI.form.HiddenValue.html#editable">editable</a></li>
969
970 <li data-name="LuCI.form.HiddenValue#modalonly"><a href="LuCI.form.HiddenValue.html#modalonly">modalonly</a></li>
971
972 <li data-name="LuCI.form.HiddenValue#onchange"><a href="LuCI.form.HiddenValue.html#onchange">onchange</a></li>
973
974 <li data-name="LuCI.form.HiddenValue#optional"><a href="LuCI.form.HiddenValue.html#optional">optional</a></li>
975
976 <li data-name="LuCI.form.HiddenValue#password"><a href="LuCI.form.HiddenValue.html#password">password</a></li>
977
978 <li data-name="LuCI.form.HiddenValue#placeholder"><a href="LuCI.form.HiddenValue.html#placeholder">placeholder</a></li>
979
980 <li data-name="LuCI.form.HiddenValue#readonly"><a href="LuCI.form.HiddenValue.html#readonly">readonly</a></li>
981
982 <li data-name="LuCI.form.HiddenValue#rmempty"><a href="LuCI.form.HiddenValue.html#rmempty">rmempty</a></li>
983
984 <li data-name="LuCI.form.HiddenValue#uciconfig"><a href="LuCI.form.HiddenValue.html#uciconfig">uciconfig</a></li>
985
986 <li data-name="LuCI.form.HiddenValue#ucioption"><a href="LuCI.form.HiddenValue.html#ucioption">ucioption</a></li>
987
988 <li data-name="LuCI.form.HiddenValue#ucisection"><a href="LuCI.form.HiddenValue.html#ucisection">ucisection</a></li>
989
990 <li data-name="LuCI.form.HiddenValue#validate"><a href="LuCI.form.HiddenValue.html#validate">validate</a></li>
991
992 <li data-name="LuCI.form.HiddenValue#width"><a href="LuCI.form.HiddenValue.html#width">width</a></li>
993
994 </ul>
995 <ul class="typedefs itemMembers">
996
997 </ul>
998 <ul class="typedefs itemMembers">
999
1000 </ul>
1001 <ul class="methods itemMembers">
1002
1003 <span class="subtitle">Methods</span>
1004
1005 <li data-name="LuCI.form.HiddenValue#append"><a href="LuCI.form.HiddenValue.html#append">append</a></li>
1006
1007 <li data-name="LuCI.form.HiddenValue#cbid"><a href="LuCI.form.HiddenValue.html#cbid">cbid</a></li>
1008
1009 <li data-name="LuCI.form.HiddenValue#cfgvalue"><a href="LuCI.form.HiddenValue.html#cfgvalue">cfgvalue</a></li>
1010
1011 <li data-name="LuCI.form.HiddenValue#depends"><a href="LuCI.form.HiddenValue.html#depends">depends</a></li>
1012
1013 <li data-name="LuCI.form.HiddenValue#formvalue"><a href="LuCI.form.HiddenValue.html#formvalue">formvalue</a></li>
1014
1015 <li data-name="LuCI.form.HiddenValue#getUIElement"><a href="LuCI.form.HiddenValue.html#getUIElement">getUIElement</a></li>
1016
1017 <li data-name="LuCI.form.HiddenValue#isActive"><a href="LuCI.form.HiddenValue.html#isActive">isActive</a></li>
1018
1019 <li data-name="LuCI.form.HiddenValue#isValid"><a href="LuCI.form.HiddenValue.html#isValid">isValid</a></li>
1020
1021 <li data-name="LuCI.form.HiddenValue#load"><a href="LuCI.form.HiddenValue.html#load">load</a></li>
1022
1023 <li data-name="LuCI.form.HiddenValue#parse"><a href="LuCI.form.HiddenValue.html#parse">parse</a></li>
1024
1025 <li data-name="LuCI.form.HiddenValue#remove"><a href="LuCI.form.HiddenValue.html#remove">remove</a></li>
1026
1027 <li data-name="LuCI.form.HiddenValue#stripTags"><a href="LuCI.form.HiddenValue.html#stripTags">stripTags</a></li>
1028
1029 <li data-name="LuCI.form.HiddenValue#textvalue"><a href="LuCI.form.HiddenValue.html#textvalue">textvalue</a></li>
1030
1031 <li data-name="LuCI.form.HiddenValue#titleFn"><a href="LuCI.form.HiddenValue.html#titleFn">titleFn</a></li>
1032
1033 <li data-name="LuCI.form.HiddenValue#value"><a href="LuCI.form.HiddenValue.html#value">value</a></li>
1034
1035 <li data-name="LuCI.form.HiddenValue#write"><a href="LuCI.form.HiddenValue.html#write">write</a></li>
1036
1037 </ul>
1038 <ul class="events itemMembers">
1039
1040 </ul>
1041 </li>
1042
1043 <li class="item" data-name="LuCI.form.JSONMap">
1044 <span class="title">
1045 <a href="LuCI.form.JSONMap.html">LuCI.form.JSONMap</a>
1046
1047 </span>
1048 <ul class="members itemMembers">
1049
1050 <span class="subtitle">Members</span>
1051
1052 <li data-name="LuCI.form.JSONMap#readonly"><a href="LuCI.form.JSONMap.html#readonly">readonly</a></li>
1053
1054 </ul>
1055 <ul class="typedefs itemMembers">
1056
1057 </ul>
1058 <ul class="typedefs itemMembers">
1059
1060 </ul>
1061 <ul class="methods itemMembers">
1062
1063 <span class="subtitle">Methods</span>
1064
1065 <li data-name="LuCI.form.JSONMap#append"><a href="LuCI.form.JSONMap.html#append">append</a></li>
1066
1067 <li data-name="LuCI.form.JSONMap#chain"><a href="LuCI.form.JSONMap.html#chain">chain</a></li>
1068
1069 <li data-name="LuCI.form.JSONMap#findElement"><a href="LuCI.form.JSONMap.html#findElement">findElement</a></li>
1070
1071 <li data-name="LuCI.form.JSONMap#findElements"><a href="LuCI.form.JSONMap.html#findElements">findElements</a></li>
1072
1073 <li data-name="LuCI.form.JSONMap#load"><a href="LuCI.form.JSONMap.html#load">load</a></li>
1074
1075 <li data-name="LuCI.form.JSONMap#lookupOption"><a href="LuCI.form.JSONMap.html#lookupOption">lookupOption</a></li>
1076
1077 <li data-name="LuCI.form.JSONMap#parse"><a href="LuCI.form.JSONMap.html#parse">parse</a></li>
1078
1079 <li data-name="LuCI.form.JSONMap#render"><a href="LuCI.form.JSONMap.html#render">render</a></li>
1080
1081 <li data-name="LuCI.form.JSONMap#reset"><a href="LuCI.form.JSONMap.html#reset">reset</a></li>
1082
1083 <li data-name="LuCI.form.JSONMap#save"><a href="LuCI.form.JSONMap.html#save">save</a></li>
1084
1085 <li data-name="LuCI.form.JSONMap#section"><a href="LuCI.form.JSONMap.html#section">section</a></li>
1086
1087 <li data-name="LuCI.form.JSONMap#stripTags"><a href="LuCI.form.JSONMap.html#stripTags">stripTags</a></li>
1088
1089 <li data-name="LuCI.form.JSONMap#titleFn"><a href="LuCI.form.JSONMap.html#titleFn">titleFn</a></li>
1090
1091 </ul>
1092 <ul class="events itemMembers">
1093
1094 </ul>
1095 </li>
1096
1097 <li class="item" data-name="LuCI.form.ListValue">
1098 <span class="title">
1099 <a href="LuCI.form.ListValue.html">LuCI.form.ListValue</a>
1100
1101 </span>
1102 <ul class="members itemMembers">
1103
1104 <span class="subtitle">Members</span>
1105
1106 <li data-name="LuCI.form.ListValue##orientation"><a href="LuCI.form.ListValue.html#orientation">orientation</a></li>
1107
1108 <li data-name="LuCI.form.ListValue##size"><a href="LuCI.form.ListValue.html#size">size</a></li>
1109
1110 <li data-name="LuCI.form.ListValue##widget"><a href="LuCI.form.ListValue.html#widget">widget</a></li>
1111
1112 <li data-name="LuCI.form.ListValue#datatype"><a href="LuCI.form.ListValue.html#datatype">datatype</a></li>
1113
1114 <li data-name="LuCI.form.ListValue#default"><a href="LuCI.form.ListValue.html#default">default</a></li>
1115
1116 <li data-name="LuCI.form.ListValue#editable"><a href="LuCI.form.ListValue.html#editable">editable</a></li>
1117
1118 <li data-name="LuCI.form.ListValue#modalonly"><a href="LuCI.form.ListValue.html#modalonly">modalonly</a></li>
1119
1120 <li data-name="LuCI.form.ListValue#onchange"><a href="LuCI.form.ListValue.html#onchange">onchange</a></li>
1121
1122 <li data-name="LuCI.form.ListValue#optional"><a href="LuCI.form.ListValue.html#optional">optional</a></li>
1123
1124 <li data-name="LuCI.form.ListValue#password"><a href="LuCI.form.ListValue.html#password">password</a></li>
1125
1126 <li data-name="LuCI.form.ListValue#placeholder"><a href="LuCI.form.ListValue.html#placeholder">placeholder</a></li>
1127
1128 <li data-name="LuCI.form.ListValue#readonly"><a href="LuCI.form.ListValue.html#readonly">readonly</a></li>
1129
1130 <li data-name="LuCI.form.ListValue#rmempty"><a href="LuCI.form.ListValue.html#rmempty">rmempty</a></li>
1131
1132 <li data-name="LuCI.form.ListValue#uciconfig"><a href="LuCI.form.ListValue.html#uciconfig">uciconfig</a></li>
1133
1134 <li data-name="LuCI.form.ListValue#ucioption"><a href="LuCI.form.ListValue.html#ucioption">ucioption</a></li>
1135
1136 <li data-name="LuCI.form.ListValue#ucisection"><a href="LuCI.form.ListValue.html#ucisection">ucisection</a></li>
1137
1138 <li data-name="LuCI.form.ListValue#validate"><a href="LuCI.form.ListValue.html#validate">validate</a></li>
1139
1140 <li data-name="LuCI.form.ListValue#width"><a href="LuCI.form.ListValue.html#width">width</a></li>
1141
1142 </ul>
1143 <ul class="typedefs itemMembers">
1144
1145 </ul>
1146 <ul class="typedefs itemMembers">
1147
1148 </ul>
1149 <ul class="methods itemMembers">
1150
1151 <span class="subtitle">Methods</span>
1152
1153 <li data-name="LuCI.form.ListValue#append"><a href="LuCI.form.ListValue.html#append">append</a></li>
1154
1155 <li data-name="LuCI.form.ListValue#cbid"><a href="LuCI.form.ListValue.html#cbid">cbid</a></li>
1156
1157 <li data-name="LuCI.form.ListValue#cfgvalue"><a href="LuCI.form.ListValue.html#cfgvalue">cfgvalue</a></li>
1158
1159 <li data-name="LuCI.form.ListValue#depends"><a href="LuCI.form.ListValue.html#depends">depends</a></li>
1160
1161 <li data-name="LuCI.form.ListValue#formvalue"><a href="LuCI.form.ListValue.html#formvalue">formvalue</a></li>
1162
1163 <li data-name="LuCI.form.ListValue#getUIElement"><a href="LuCI.form.ListValue.html#getUIElement">getUIElement</a></li>
1164
1165 <li data-name="LuCI.form.ListValue#isActive"><a href="LuCI.form.ListValue.html#isActive">isActive</a></li>
1166
1167 <li data-name="LuCI.form.ListValue#isValid"><a href="LuCI.form.ListValue.html#isValid">isValid</a></li>
1168
1169 <li data-name="LuCI.form.ListValue#load"><a href="LuCI.form.ListValue.html#load">load</a></li>
1170
1171 <li data-name="LuCI.form.ListValue#parse"><a href="LuCI.form.ListValue.html#parse">parse</a></li>
1172
1173 <li data-name="LuCI.form.ListValue#remove"><a href="LuCI.form.ListValue.html#remove">remove</a></li>
1174
1175 <li data-name="LuCI.form.ListValue#stripTags"><a href="LuCI.form.ListValue.html#stripTags">stripTags</a></li>
1176
1177 <li data-name="LuCI.form.ListValue#textvalue"><a href="LuCI.form.ListValue.html#textvalue">textvalue</a></li>
1178
1179 <li data-name="LuCI.form.ListValue#titleFn"><a href="LuCI.form.ListValue.html#titleFn">titleFn</a></li>
1180
1181 <li data-name="LuCI.form.ListValue#value"><a href="LuCI.form.ListValue.html#value">value</a></li>
1182
1183 <li data-name="LuCI.form.ListValue#write"><a href="LuCI.form.ListValue.html#write">write</a></li>
1184
1185 </ul>
1186 <ul class="events itemMembers">
1187
1188 </ul>
1189 </li>
1190
1191 <li class="item" data-name="LuCI.form.Map">
1192 <span class="title">
1193 <a href="LuCI.form.Map.html">LuCI.form.Map</a>
1194
1195 </span>
1196 <ul class="members itemMembers">
1197
1198 <span class="subtitle">Members</span>
1199
1200 <li data-name="LuCI.form.Map##readonly"><a href="LuCI.form.Map.html#readonly">readonly</a></li>
1201
1202 </ul>
1203 <ul class="typedefs itemMembers">
1204
1205 </ul>
1206 <ul class="typedefs itemMembers">
1207
1208 </ul>
1209 <ul class="methods itemMembers">
1210
1211 <span class="subtitle">Methods</span>
1212
1213 <li data-name="LuCI.form.Map#append"><a href="LuCI.form.Map.html#append">append</a></li>
1214
1215 <li data-name="LuCI.form.Map#chain"><a href="LuCI.form.Map.html#chain">chain</a></li>
1216
1217 <li data-name="LuCI.form.Map#findElement"><a href="LuCI.form.Map.html#findElement">findElement</a></li>
1218
1219 <li data-name="LuCI.form.Map#findElements"><a href="LuCI.form.Map.html#findElements">findElements</a></li>
1220
1221 <li data-name="LuCI.form.Map#load"><a href="LuCI.form.Map.html#load">load</a></li>
1222
1223 <li data-name="LuCI.form.Map#lookupOption"><a href="LuCI.form.Map.html#lookupOption">lookupOption</a></li>
1224
1225 <li data-name="LuCI.form.Map#parse"><a href="LuCI.form.Map.html#parse">parse</a></li>
1226
1227 <li data-name="LuCI.form.Map#render"><a href="LuCI.form.Map.html#render">render</a></li>
1228
1229 <li data-name="LuCI.form.Map#reset"><a href="LuCI.form.Map.html#reset">reset</a></li>
1230
1231 <li data-name="LuCI.form.Map#save"><a href="LuCI.form.Map.html#save">save</a></li>
1232
1233 <li data-name="LuCI.form.Map#section"><a href="LuCI.form.Map.html#section">section</a></li>
1234
1235 <li data-name="LuCI.form.Map#stripTags"><a href="LuCI.form.Map.html#stripTags">stripTags</a></li>
1236
1237 <li data-name="LuCI.form.Map#titleFn"><a href="LuCI.form.Map.html#titleFn">titleFn</a></li>
1238
1239 </ul>
1240 <ul class="events itemMembers">
1241
1242 </ul>
1243 </li>
1244
1245 <li class="item" data-name="LuCI.form.MultiValue">
1246 <span class="title">
1247 <a href="LuCI.form.MultiValue.html">LuCI.form.MultiValue</a>
1248
1249 </span>
1250 <ul class="members itemMembers">
1251
1252 <span class="subtitle">Members</span>
1253
1254 <li data-name="LuCI.form.MultiValue##display_size"><a href="LuCI.form.MultiValue.html#display_size">display_size</a></li>
1255
1256 <li data-name="LuCI.form.MultiValue##dropdown_size"><a href="LuCI.form.MultiValue.html#dropdown_size">dropdown_size</a></li>
1257
1258 <li data-name="LuCI.form.MultiValue#datatype"><a href="LuCI.form.MultiValue.html#datatype">datatype</a></li>
1259
1260 <li data-name="LuCI.form.MultiValue#default"><a href="LuCI.form.MultiValue.html#default">default</a></li>
1261
1262 <li data-name="LuCI.form.MultiValue#editable"><a href="LuCI.form.MultiValue.html#editable">editable</a></li>
1263
1264 <li data-name="LuCI.form.MultiValue#modalonly"><a href="LuCI.form.MultiValue.html#modalonly">modalonly</a></li>
1265
1266 <li data-name="LuCI.form.MultiValue#onchange"><a href="LuCI.form.MultiValue.html#onchange">onchange</a></li>
1267
1268 <li data-name="LuCI.form.MultiValue#optional"><a href="LuCI.form.MultiValue.html#optional">optional</a></li>
1269
1270 <li data-name="LuCI.form.MultiValue#password"><a href="LuCI.form.MultiValue.html#password">password</a></li>
1271
1272 <li data-name="LuCI.form.MultiValue#placeholder"><a href="LuCI.form.MultiValue.html#placeholder">placeholder</a></li>
1273
1274 <li data-name="LuCI.form.MultiValue#readonly"><a href="LuCI.form.MultiValue.html#readonly">readonly</a></li>
1275
1276 <li data-name="LuCI.form.MultiValue#rmempty"><a href="LuCI.form.MultiValue.html#rmempty">rmempty</a></li>
1277
1278 <li data-name="LuCI.form.MultiValue#uciconfig"><a href="LuCI.form.MultiValue.html#uciconfig">uciconfig</a></li>
1279
1280 <li data-name="LuCI.form.MultiValue#ucioption"><a href="LuCI.form.MultiValue.html#ucioption">ucioption</a></li>
1281
1282 <li data-name="LuCI.form.MultiValue#ucisection"><a href="LuCI.form.MultiValue.html#ucisection">ucisection</a></li>
1283
1284 <li data-name="LuCI.form.MultiValue#validate"><a href="LuCI.form.MultiValue.html#validate">validate</a></li>
1285
1286 <li data-name="LuCI.form.MultiValue#width"><a href="LuCI.form.MultiValue.html#width">width</a></li>
1287
1288 </ul>
1289 <ul class="typedefs itemMembers">
1290
1291 </ul>
1292 <ul class="typedefs itemMembers">
1293
1294 </ul>
1295 <ul class="methods itemMembers">
1296
1297 <span class="subtitle">Methods</span>
1298
1299 <li data-name="LuCI.form.MultiValue#append"><a href="LuCI.form.MultiValue.html#append">append</a></li>
1300
1301 <li data-name="LuCI.form.MultiValue#cbid"><a href="LuCI.form.MultiValue.html#cbid">cbid</a></li>
1302
1303 <li data-name="LuCI.form.MultiValue#cfgvalue"><a href="LuCI.form.MultiValue.html#cfgvalue">cfgvalue</a></li>
1304
1305 <li data-name="LuCI.form.MultiValue#depends"><a href="LuCI.form.MultiValue.html#depends">depends</a></li>
1306
1307 <li data-name="LuCI.form.MultiValue#formvalue"><a href="LuCI.form.MultiValue.html#formvalue">formvalue</a></li>
1308
1309 <li data-name="LuCI.form.MultiValue#getUIElement"><a href="LuCI.form.MultiValue.html#getUIElement">getUIElement</a></li>
1310
1311 <li data-name="LuCI.form.MultiValue#isActive"><a href="LuCI.form.MultiValue.html#isActive">isActive</a></li>
1312
1313 <li data-name="LuCI.form.MultiValue#isValid"><a href="LuCI.form.MultiValue.html#isValid">isValid</a></li>
1314
1315 <li data-name="LuCI.form.MultiValue#load"><a href="LuCI.form.MultiValue.html#load">load</a></li>
1316
1317 <li data-name="LuCI.form.MultiValue#parse"><a href="LuCI.form.MultiValue.html#parse">parse</a></li>
1318
1319 <li data-name="LuCI.form.MultiValue#remove"><a href="LuCI.form.MultiValue.html#remove">remove</a></li>
1320
1321 <li data-name="LuCI.form.MultiValue#stripTags"><a href="LuCI.form.MultiValue.html#stripTags">stripTags</a></li>
1322
1323 <li data-name="LuCI.form.MultiValue#textvalue"><a href="LuCI.form.MultiValue.html#textvalue">textvalue</a></li>
1324
1325 <li data-name="LuCI.form.MultiValue#titleFn"><a href="LuCI.form.MultiValue.html#titleFn">titleFn</a></li>
1326
1327 <li data-name="LuCI.form.MultiValue#value"><a href="LuCI.form.MultiValue.html#value">value</a></li>
1328
1329 <li data-name="LuCI.form.MultiValue#write"><a href="LuCI.form.MultiValue.html#write">write</a></li>
1330
1331 </ul>
1332 <ul class="events itemMembers">
1333
1334 </ul>
1335 </li>
1336
1337 <li class="item" data-name="LuCI.form.NamedSection">
1338 <span class="title">
1339 <a href="LuCI.form.NamedSection.html">LuCI.form.NamedSection</a>
1340
1341 </span>
1342 <ul class="members itemMembers">
1343
1344 <span class="subtitle">Members</span>
1345
1346 <li data-name="LuCI.form.NamedSection##addremove"><a href="LuCI.form.NamedSection.html#addremove">addremove</a></li>
1347
1348 <li data-name="LuCI.form.NamedSection##uciconfig"><a href="LuCI.form.NamedSection.html#uciconfig">uciconfig</a></li>
1349
1350 <li data-name="LuCI.form.NamedSection#parentoption"><a href="LuCI.form.NamedSection.html#parentoption">parentoption</a></li>
1351
1352 </ul>
1353 <ul class="typedefs itemMembers">
1354
1355 </ul>
1356 <ul class="typedefs itemMembers">
1357
1358 </ul>
1359 <ul class="methods itemMembers">
1360
1361 <span class="subtitle">Methods</span>
1362
1363 <li data-name="LuCI.form.NamedSection#append"><a href="LuCI.form.NamedSection.html#append">append</a></li>
1364
1365 <li data-name="LuCI.form.NamedSection#cfgsections"><a href="LuCI.form.NamedSection.html#cfgsections">cfgsections</a></li>
1366
1367 <li data-name="LuCI.form.NamedSection#cfgvalue"><a href="LuCI.form.NamedSection.html#cfgvalue">cfgvalue</a></li>
1368
1369 <li data-name="LuCI.form.NamedSection#filter"><a href="LuCI.form.NamedSection.html#filter">filter</a></li>
1370
1371 <li data-name="LuCI.form.NamedSection#formvalue"><a href="LuCI.form.NamedSection.html#formvalue">formvalue</a></li>
1372
1373 <li data-name="LuCI.form.NamedSection#getOption"><a href="LuCI.form.NamedSection.html#getOption">getOption</a></li>
1374
1375 <li data-name="LuCI.form.NamedSection#getUIElement"><a href="LuCI.form.NamedSection.html#getUIElement">getUIElement</a></li>
1376
1377 <li data-name="LuCI.form.NamedSection#load"><a href="LuCI.form.NamedSection.html#load">load</a></li>
1378
1379 <li data-name="LuCI.form.NamedSection#option"><a href="LuCI.form.NamedSection.html#option">option</a></li>
1380
1381 <li data-name="LuCI.form.NamedSection#parse"><a href="LuCI.form.NamedSection.html#parse">parse</a></li>
1382
1383 <li data-name="LuCI.form.NamedSection#render"><a href="LuCI.form.NamedSection.html#render">render</a></li>
1384
1385 <li data-name="LuCI.form.NamedSection#stripTags"><a href="LuCI.form.NamedSection.html#stripTags">stripTags</a></li>
1386
1387 <li data-name="LuCI.form.NamedSection#tab"><a href="LuCI.form.NamedSection.html#tab">tab</a></li>
1388
1389 <li data-name="LuCI.form.NamedSection#taboption"><a href="LuCI.form.NamedSection.html#taboption">taboption</a></li>
1390
1391 <li data-name="LuCI.form.NamedSection#titleFn"><a href="LuCI.form.NamedSection.html#titleFn">titleFn</a></li>
1392
1393 </ul>
1394 <ul class="events itemMembers">
1395
1396 </ul>
1397 </li>
1398
1399 <li class="item" data-name="LuCI.form.SectionValue">
1400 <span class="title">
1401 <a href="LuCI.form.SectionValue.html">LuCI.form.SectionValue</a>
1402
1403 </span>
1404 <ul class="members itemMembers">
1405
1406 <span class="subtitle">Members</span>
1407
1408 <li data-name="LuCI.form.SectionValue##subsection"><a href="LuCI.form.SectionValue.html#subsection">subsection</a></li>
1409
1410 <li data-name="LuCI.form.SectionValue#datatype"><a href="LuCI.form.SectionValue.html#datatype">datatype</a></li>
1411
1412 <li data-name="LuCI.form.SectionValue#default"><a href="LuCI.form.SectionValue.html#default">default</a></li>
1413
1414 <li data-name="LuCI.form.SectionValue#editable"><a href="LuCI.form.SectionValue.html#editable">editable</a></li>
1415
1416 <li data-name="LuCI.form.SectionValue#modalonly"><a href="LuCI.form.SectionValue.html#modalonly">modalonly</a></li>
1417
1418 <li data-name="LuCI.form.SectionValue#onchange"><a href="LuCI.form.SectionValue.html#onchange">onchange</a></li>
1419
1420 <li data-name="LuCI.form.SectionValue#optional"><a href="LuCI.form.SectionValue.html#optional">optional</a></li>
1421
1422 <li data-name="LuCI.form.SectionValue#password"><a href="LuCI.form.SectionValue.html#password">password</a></li>
1423
1424 <li data-name="LuCI.form.SectionValue#placeholder"><a href="LuCI.form.SectionValue.html#placeholder">placeholder</a></li>
1425
1426 <li data-name="LuCI.form.SectionValue#readonly"><a href="LuCI.form.SectionValue.html#readonly">readonly</a></li>
1427
1428 <li data-name="LuCI.form.SectionValue#rmempty"><a href="LuCI.form.SectionValue.html#rmempty">rmempty</a></li>
1429
1430 <li data-name="LuCI.form.SectionValue#uciconfig"><a href="LuCI.form.SectionValue.html#uciconfig">uciconfig</a></li>
1431
1432 <li data-name="LuCI.form.SectionValue#ucioption"><a href="LuCI.form.SectionValue.html#ucioption">ucioption</a></li>
1433
1434 <li data-name="LuCI.form.SectionValue#ucisection"><a href="LuCI.form.SectionValue.html#ucisection">ucisection</a></li>
1435
1436 <li data-name="LuCI.form.SectionValue#validate"><a href="LuCI.form.SectionValue.html#validate">validate</a></li>
1437
1438 <li data-name="LuCI.form.SectionValue#width"><a href="LuCI.form.SectionValue.html#width">width</a></li>
1439
1440 </ul>
1441 <ul class="typedefs itemMembers">
1442
1443 </ul>
1444 <ul class="typedefs itemMembers">
1445
1446 </ul>
1447 <ul class="methods itemMembers">
1448
1449 <span class="subtitle">Methods</span>
1450
1451 <li data-name="LuCI.form.SectionValue#append"><a href="LuCI.form.SectionValue.html#append">append</a></li>
1452
1453 <li data-name="LuCI.form.SectionValue#cbid"><a href="LuCI.form.SectionValue.html#cbid">cbid</a></li>
1454
1455 <li data-name="LuCI.form.SectionValue#cfgvalue"><a href="LuCI.form.SectionValue.html#cfgvalue">cfgvalue</a></li>
1456
1457 <li data-name="LuCI.form.SectionValue#depends"><a href="LuCI.form.SectionValue.html#depends">depends</a></li>
1458
1459 <li data-name="LuCI.form.SectionValue#formvalue"><a href="LuCI.form.SectionValue.html#formvalue">formvalue</a></li>
1460
1461 <li data-name="LuCI.form.SectionValue#getUIElement"><a href="LuCI.form.SectionValue.html#getUIElement">getUIElement</a></li>
1462
1463 <li data-name="LuCI.form.SectionValue#isActive"><a href="LuCI.form.SectionValue.html#isActive">isActive</a></li>
1464
1465 <li data-name="LuCI.form.SectionValue#isValid"><a href="LuCI.form.SectionValue.html#isValid">isValid</a></li>
1466
1467 <li data-name="LuCI.form.SectionValue#load"><a href="LuCI.form.SectionValue.html#load">load</a></li>
1468
1469 <li data-name="LuCI.form.SectionValue#parse"><a href="LuCI.form.SectionValue.html#parse">parse</a></li>
1470
1471 <li data-name="LuCI.form.SectionValue#remove"><a href="LuCI.form.SectionValue.html#remove">remove</a></li>
1472
1473 <li data-name="LuCI.form.SectionValue#stripTags"><a href="LuCI.form.SectionValue.html#stripTags">stripTags</a></li>
1474
1475 <li data-name="LuCI.form.SectionValue#textvalue"><a href="LuCI.form.SectionValue.html#textvalue">textvalue</a></li>
1476
1477 <li data-name="LuCI.form.SectionValue#titleFn"><a href="LuCI.form.SectionValue.html#titleFn">titleFn</a></li>
1478
1479 <li data-name="LuCI.form.SectionValue#value"><a href="LuCI.form.SectionValue.html#value">value</a></li>
1480
1481 <li data-name="LuCI.form.SectionValue#write"><a href="LuCI.form.SectionValue.html#write">write</a></li>
1482
1483 </ul>
1484 <ul class="events itemMembers">
1485
1486 </ul>
1487 </li>
1488
1489 <li class="item" data-name="LuCI.form.TableSection">
1490 <span class="title">
1491 <a href="LuCI.form.TableSection.html">LuCI.form.TableSection</a>
1492
1493 </span>
1494 <ul class="members itemMembers">
1495
1496 <span class="subtitle">Members</span>
1497
1498 <li data-name="LuCI.form.TableSection##addbtntitle"><a href="LuCI.form.TableSection.html#addbtntitle">addbtntitle</a></li>
1499
1500 <li data-name="LuCI.form.TableSection##addremove"><a href="LuCI.form.TableSection.html#addremove">addremove</a></li>
1501
1502 <li data-name="LuCI.form.TableSection##anonymous"><a href="LuCI.form.TableSection.html#anonymous">anonymous</a></li>
1503
1504 <li data-name="LuCI.form.TableSection##extedit"><a href="LuCI.form.TableSection.html#extedit">extedit</a></li>
1505
1506 <li data-name="LuCI.form.TableSection##max_cols"><a href="LuCI.form.TableSection.html#max_cols">max_cols</a></li>
1507
1508 <li data-name="LuCI.form.TableSection##modaltitle"><a href="LuCI.form.TableSection.html#modaltitle">modaltitle</a></li>
1509
1510 <li data-name="LuCI.form.TableSection##nodescriptions"><a href="LuCI.form.TableSection.html#nodescriptions">nodescriptions</a></li>
1511
1512 <li data-name="LuCI.form.TableSection##rowcolors"><a href="LuCI.form.TableSection.html#rowcolors">rowcolors</a></li>
1513
1514 <li data-name="LuCI.form.TableSection##sectiontitle"><a href="LuCI.form.TableSection.html#sectiontitle">sectiontitle</a></li>
1515
1516 <li data-name="LuCI.form.TableSection##sortable"><a href="LuCI.form.TableSection.html#sortable">sortable</a></li>
1517
1518 <li data-name="LuCI.form.TableSection##uciconfig"><a href="LuCI.form.TableSection.html#uciconfig">uciconfig</a></li>
1519
1520 <li data-name="LuCI.form.TableSection#addbtntitle"><a href="LuCI.form.TableSection.html#addbtntitle">addbtntitle</a></li>
1521
1522 <li data-name="LuCI.form.TableSection#addremove"><a href="LuCI.form.TableSection.html#addremove">addremove</a></li>
1523
1524 <li data-name="LuCI.form.TableSection#anonymous"><a href="LuCI.form.TableSection.html#anonymous">anonymous</a></li>
1525
1526 <li data-name="LuCI.form.TableSection#parentoption"><a href="LuCI.form.TableSection.html#parentoption">parentoption</a></li>
1527
1528 <li data-name="LuCI.form.TableSection#tabbed"><a href="LuCI.form.TableSection.html#tabbed">tabbed</a></li>
1529
1530 <li data-name="LuCI.form.TableSection#uciconfig"><a href="LuCI.form.TableSection.html#uciconfig">uciconfig</a></li>
1531
1532 </ul>
1533 <ul class="typedefs itemMembers">
1534
1535 </ul>
1536 <ul class="typedefs itemMembers">
1537
1538 </ul>
1539 <ul class="methods itemMembers">
1540
1541 <span class="subtitle">Methods</span>
1542
1543 <li data-name="LuCI.form.TableSection#addModalOptions"><a href="LuCI.form.TableSection.html#addModalOptions">addModalOptions</a></li>
1544
1545 <li data-name="LuCI.form.TableSection#append"><a href="LuCI.form.TableSection.html#append">append</a></li>
1546
1547 <li data-name="LuCI.form.TableSection#cfgvalue"><a href="LuCI.form.TableSection.html#cfgvalue">cfgvalue</a></li>
1548
1549 <li data-name="LuCI.form.TableSection#filter"><a href="LuCI.form.TableSection.html#filter">filter</a></li>
1550
1551 <li data-name="LuCI.form.TableSection#formvalue"><a href="LuCI.form.TableSection.html#formvalue">formvalue</a></li>
1552
1553 <li data-name="LuCI.form.TableSection#getOption"><a href="LuCI.form.TableSection.html#getOption">getOption</a></li>
1554
1555 <li data-name="LuCI.form.TableSection#getUIElement"><a href="LuCI.form.TableSection.html#getUIElement">getUIElement</a></li>
1556
1557 <li data-name="LuCI.form.TableSection#load"><a href="LuCI.form.TableSection.html#load">load</a></li>
1558
1559 <li data-name="LuCI.form.TableSection#option"><a href="LuCI.form.TableSection.html#option">option</a></li>
1560
1561 <li data-name="LuCI.form.TableSection#parse"><a href="LuCI.form.TableSection.html#parse">parse</a></li>
1562
1563 <li data-name="LuCI.form.TableSection#stripTags"><a href="LuCI.form.TableSection.html#stripTags">stripTags</a></li>
1564
1565 <li data-name="LuCI.form.TableSection#tab"><a href="LuCI.form.TableSection.html#tab">tab</a></li>
1566
1567 <li data-name="LuCI.form.TableSection#taboption"><a href="LuCI.form.TableSection.html#taboption">taboption</a></li>
1568
1569 <li data-name="LuCI.form.TableSection#titleFn"><a href="LuCI.form.TableSection.html#titleFn">titleFn</a></li>
1570
1571 </ul>
1572 <ul class="events itemMembers">
1573
1574 </ul>
1575 </li>
1576
1577 <li class="item" data-name="LuCI.form.TextValue">
1578 <span class="title">
1579 <a href="LuCI.form.TextValue.html">LuCI.form.TextValue</a>
1580
1581 </span>
1582 <ul class="members itemMembers">
1583
1584 <span class="subtitle">Members</span>
1585
1586 <li data-name="LuCI.form.TextValue##cols"><a href="LuCI.form.TextValue.html#cols">cols</a></li>
1587
1588 <li data-name="LuCI.form.TextValue##monospace"><a href="LuCI.form.TextValue.html#monospace">monospace</a></li>
1589
1590 <li data-name="LuCI.form.TextValue##rows"><a href="LuCI.form.TextValue.html#rows">rows</a></li>
1591
1592 <li data-name="LuCI.form.TextValue##wrap"><a href="LuCI.form.TextValue.html#wrap">wrap</a></li>
1593
1594 <li data-name="LuCI.form.TextValue#datatype"><a href="LuCI.form.TextValue.html#datatype">datatype</a></li>
1595
1596 <li data-name="LuCI.form.TextValue#default"><a href="LuCI.form.TextValue.html#default">default</a></li>
1597
1598 <li data-name="LuCI.form.TextValue#editable"><a href="LuCI.form.TextValue.html#editable">editable</a></li>
1599
1600 <li data-name="LuCI.form.TextValue#modalonly"><a href="LuCI.form.TextValue.html#modalonly">modalonly</a></li>
1601
1602 <li data-name="LuCI.form.TextValue#onchange"><a href="LuCI.form.TextValue.html#onchange">onchange</a></li>
1603
1604 <li data-name="LuCI.form.TextValue#optional"><a href="LuCI.form.TextValue.html#optional">optional</a></li>
1605
1606 <li data-name="LuCI.form.TextValue#password"><a href="LuCI.form.TextValue.html#password">password</a></li>
1607
1608 <li data-name="LuCI.form.TextValue#placeholder"><a href="LuCI.form.TextValue.html#placeholder">placeholder</a></li>
1609
1610 <li data-name="LuCI.form.TextValue#readonly"><a href="LuCI.form.TextValue.html#readonly">readonly</a></li>
1611
1612 <li data-name="LuCI.form.TextValue#rmempty"><a href="LuCI.form.TextValue.html#rmempty">rmempty</a></li>
1613
1614 <li data-name="LuCI.form.TextValue#uciconfig"><a href="LuCI.form.TextValue.html#uciconfig">uciconfig</a></li>
1615
1616 <li data-name="LuCI.form.TextValue#ucioption"><a href="LuCI.form.TextValue.html#ucioption">ucioption</a></li>
1617
1618 <li data-name="LuCI.form.TextValue#ucisection"><a href="LuCI.form.TextValue.html#ucisection">ucisection</a></li>
1619
1620 <li data-name="LuCI.form.TextValue#validate"><a href="LuCI.form.TextValue.html#validate">validate</a></li>
1621
1622 <li data-name="LuCI.form.TextValue#width"><a href="LuCI.form.TextValue.html#width">width</a></li>
1623
1624 </ul>
1625 <ul class="typedefs itemMembers">
1626
1627 </ul>
1628 <ul class="typedefs itemMembers">
1629
1630 </ul>
1631 <ul class="methods itemMembers">
1632
1633 <span class="subtitle">Methods</span>
1634
1635 <li data-name="LuCI.form.TextValue#append"><a href="LuCI.form.TextValue.html#append">append</a></li>
1636
1637 <li data-name="LuCI.form.TextValue#cbid"><a href="LuCI.form.TextValue.html#cbid">cbid</a></li>
1638
1639 <li data-name="LuCI.form.TextValue#cfgvalue"><a href="LuCI.form.TextValue.html#cfgvalue">cfgvalue</a></li>
1640
1641 <li data-name="LuCI.form.TextValue#depends"><a href="LuCI.form.TextValue.html#depends">depends</a></li>
1642
1643 <li data-name="LuCI.form.TextValue#formvalue"><a href="LuCI.form.TextValue.html#formvalue">formvalue</a></li>
1644
1645 <li data-name="LuCI.form.TextValue#getUIElement"><a href="LuCI.form.TextValue.html#getUIElement">getUIElement</a></li>
1646
1647 <li data-name="LuCI.form.TextValue#isActive"><a href="LuCI.form.TextValue.html#isActive">isActive</a></li>
1648
1649 <li data-name="LuCI.form.TextValue#isValid"><a href="LuCI.form.TextValue.html#isValid">isValid</a></li>
1650
1651 <li data-name="LuCI.form.TextValue#load"><a href="LuCI.form.TextValue.html#load">load</a></li>
1652
1653 <li data-name="LuCI.form.TextValue#parse"><a href="LuCI.form.TextValue.html#parse">parse</a></li>
1654
1655 <li data-name="LuCI.form.TextValue#remove"><a href="LuCI.form.TextValue.html#remove">remove</a></li>
1656
1657 <li data-name="LuCI.form.TextValue#stripTags"><a href="LuCI.form.TextValue.html#stripTags">stripTags</a></li>
1658
1659 <li data-name="LuCI.form.TextValue#textvalue"><a href="LuCI.form.TextValue.html#textvalue">textvalue</a></li>
1660
1661 <li data-name="LuCI.form.TextValue#titleFn"><a href="LuCI.form.TextValue.html#titleFn">titleFn</a></li>
1662
1663 <li data-name="LuCI.form.TextValue#write"><a href="LuCI.form.TextValue.html#write">write</a></li>
1664
1665 </ul>
1666 <ul class="events itemMembers">
1667
1668 </ul>
1669 </li>
1670
1671 <li class="item" data-name="LuCI.form.TypedSection">
1672 <span class="title">
1673 <a href="LuCI.form.TypedSection.html">LuCI.form.TypedSection</a>
1674
1675 </span>
1676 <ul class="members itemMembers">
1677
1678 <span class="subtitle">Members</span>
1679
1680 <li data-name="LuCI.form.TypedSection##addbtntitle"><a href="LuCI.form.TypedSection.html#addbtntitle">addbtntitle</a></li>
1681
1682 <li data-name="LuCI.form.TypedSection##addremove"><a href="LuCI.form.TypedSection.html#addremove">addremove</a></li>
1683
1684 <li data-name="LuCI.form.TypedSection##anonymous"><a href="LuCI.form.TypedSection.html#anonymous">anonymous</a></li>
1685
1686 <li data-name="LuCI.form.TypedSection##tabbed"><a href="LuCI.form.TypedSection.html#tabbed">tabbed</a></li>
1687
1688 <li data-name="LuCI.form.TypedSection##uciconfig"><a href="LuCI.form.TypedSection.html#uciconfig">uciconfig</a></li>
1689
1690 <li data-name="LuCI.form.TypedSection#parentoption"><a href="LuCI.form.TypedSection.html#parentoption">parentoption</a></li>
1691
1692 </ul>
1693 <ul class="typedefs itemMembers">
1694
1695 </ul>
1696 <ul class="typedefs itemMembers">
1697
1698 </ul>
1699 <ul class="methods itemMembers">
1700
1701 <span class="subtitle">Methods</span>
1702
1703 <li data-name="LuCI.form.TypedSection#append"><a href="LuCI.form.TypedSection.html#append">append</a></li>
1704
1705 <li data-name="LuCI.form.TypedSection#cfgsections"><a href="LuCI.form.TypedSection.html#cfgsections">cfgsections</a></li>
1706
1707 <li data-name="LuCI.form.TypedSection#cfgvalue"><a href="LuCI.form.TypedSection.html#cfgvalue">cfgvalue</a></li>
1708
1709 <li data-name="LuCI.form.TypedSection#filter"><a href="LuCI.form.TypedSection.html#filter">filter</a></li>
1710
1711 <li data-name="LuCI.form.TypedSection#formvalue"><a href="LuCI.form.TypedSection.html#formvalue">formvalue</a></li>
1712
1713 <li data-name="LuCI.form.TypedSection#getOption"><a href="LuCI.form.TypedSection.html#getOption">getOption</a></li>
1714
1715 <li data-name="LuCI.form.TypedSection#getUIElement"><a href="LuCI.form.TypedSection.html#getUIElement">getUIElement</a></li>
1716
1717 <li data-name="LuCI.form.TypedSection#load"><a href="LuCI.form.TypedSection.html#load">load</a></li>
1718
1719 <li data-name="LuCI.form.TypedSection#option"><a href="LuCI.form.TypedSection.html#option">option</a></li>
1720
1721 <li data-name="LuCI.form.TypedSection#parse"><a href="LuCI.form.TypedSection.html#parse">parse</a></li>
1722
1723 <li data-name="LuCI.form.TypedSection#render"><a href="LuCI.form.TypedSection.html#render">render</a></li>
1724
1725 <li data-name="LuCI.form.TypedSection#stripTags"><a href="LuCI.form.TypedSection.html#stripTags">stripTags</a></li>
1726
1727 <li data-name="LuCI.form.TypedSection#tab"><a href="LuCI.form.TypedSection.html#tab">tab</a></li>
1728
1729 <li data-name="LuCI.form.TypedSection#taboption"><a href="LuCI.form.TypedSection.html#taboption">taboption</a></li>
1730
1731 <li data-name="LuCI.form.TypedSection#titleFn"><a href="LuCI.form.TypedSection.html#titleFn">titleFn</a></li>
1732
1733 </ul>
1734 <ul class="events itemMembers">
1735
1736 </ul>
1737 </li>
1738
1739 <li class="item" data-name="LuCI.form.Value">
1740 <span class="title">
1741 <a href="LuCI.form.Value.html">LuCI.form.Value</a>
1742
1743 </span>
1744 <ul class="members itemMembers">
1745
1746 <span class="subtitle">Members</span>
1747
1748 <li data-name="LuCI.form.Value##password"><a href="LuCI.form.Value.html#password">password</a></li>
1749
1750 <li data-name="LuCI.form.Value##placeholder"><a href="LuCI.form.Value.html#placeholder">placeholder</a></li>
1751
1752 <li data-name="LuCI.form.Value#datatype"><a href="LuCI.form.Value.html#datatype">datatype</a></li>
1753
1754 <li data-name="LuCI.form.Value#default"><a href="LuCI.form.Value.html#default">default</a></li>
1755
1756 <li data-name="LuCI.form.Value#editable"><a href="LuCI.form.Value.html#editable">editable</a></li>
1757
1758 <li data-name="LuCI.form.Value#modalonly"><a href="LuCI.form.Value.html#modalonly">modalonly</a></li>
1759
1760 <li data-name="LuCI.form.Value#onchange"><a href="LuCI.form.Value.html#onchange">onchange</a></li>
1761
1762 <li data-name="LuCI.form.Value#optional"><a href="LuCI.form.Value.html#optional">optional</a></li>
1763
1764 <li data-name="LuCI.form.Value#readonly"><a href="LuCI.form.Value.html#readonly">readonly</a></li>
1765
1766 <li data-name="LuCI.form.Value#rmempty"><a href="LuCI.form.Value.html#rmempty">rmempty</a></li>
1767
1768 <li data-name="LuCI.form.Value#uciconfig"><a href="LuCI.form.Value.html#uciconfig">uciconfig</a></li>
1769
1770 <li data-name="LuCI.form.Value#ucioption"><a href="LuCI.form.Value.html#ucioption">ucioption</a></li>
1771
1772 <li data-name="LuCI.form.Value#ucisection"><a href="LuCI.form.Value.html#ucisection">ucisection</a></li>
1773
1774 <li data-name="LuCI.form.Value#validate"><a href="LuCI.form.Value.html#validate">validate</a></li>
1775
1776 <li data-name="LuCI.form.Value#width"><a href="LuCI.form.Value.html#width">width</a></li>
1777
1778 </ul>
1779 <ul class="typedefs itemMembers">
1780
1781 </ul>
1782 <ul class="typedefs itemMembers">
1783
1784 </ul>
1785 <ul class="methods itemMembers">
1786
1787 <span class="subtitle">Methods</span>
1788
1789 <li data-name="LuCI.form.Value#append"><a href="LuCI.form.Value.html#append">append</a></li>
1790
1791 <li data-name="LuCI.form.Value#cbid"><a href="LuCI.form.Value.html#cbid">cbid</a></li>
1792
1793 <li data-name="LuCI.form.Value#cfgvalue"><a href="LuCI.form.Value.html#cfgvalue">cfgvalue</a></li>
1794
1795 <li data-name="LuCI.form.Value#depends"><a href="LuCI.form.Value.html#depends">depends</a></li>
1796
1797 <li data-name="LuCI.form.Value#formvalue"><a href="LuCI.form.Value.html#formvalue">formvalue</a></li>
1798
1799 <li data-name="LuCI.form.Value#getUIElement"><a href="LuCI.form.Value.html#getUIElement">getUIElement</a></li>
1800
1801 <li data-name="LuCI.form.Value#isActive"><a href="LuCI.form.Value.html#isActive">isActive</a></li>
1802
1803 <li data-name="LuCI.form.Value#isValid"><a href="LuCI.form.Value.html#isValid">isValid</a></li>
1804
1805 <li data-name="LuCI.form.Value#load"><a href="LuCI.form.Value.html#load">load</a></li>
1806
1807 <li data-name="LuCI.form.Value#parse"><a href="LuCI.form.Value.html#parse">parse</a></li>
1808
1809 <li data-name="LuCI.form.Value#remove"><a href="LuCI.form.Value.html#remove">remove</a></li>
1810
1811 <li data-name="LuCI.form.Value#render"><a href="LuCI.form.Value.html#render">render</a></li>
1812
1813 <li data-name="LuCI.form.Value#stripTags"><a href="LuCI.form.Value.html#stripTags">stripTags</a></li>
1814
1815 <li data-name="LuCI.form.Value#textvalue"><a href="LuCI.form.Value.html#textvalue">textvalue</a></li>
1816
1817 <li data-name="LuCI.form.Value#titleFn"><a href="LuCI.form.Value.html#titleFn">titleFn</a></li>
1818
1819 <li data-name="LuCI.form.Value#value"><a href="LuCI.form.Value.html#value">value</a></li>
1820
1821 <li data-name="LuCI.form.Value#write"><a href="LuCI.form.Value.html#write">write</a></li>
1822
1823 </ul>
1824 <ul class="events itemMembers">
1825
1826 </ul>
1827 </li>
1828
1829 <li class="item" data-name="LuCI.fs">
1830 <span class="title">
1831 <a href="LuCI.fs.html">LuCI.fs</a>
1832
1833 </span>
1834 <ul class="members itemMembers">
1835
1836 </ul>
1837 <ul class="typedefs itemMembers">
1838
1839 <span class="subtitle">Typedefs</span>
1840
1841 <li data-name="LuCI.fs.FileExecResult"><a href="LuCI.fs.html#.FileExecResult">FileExecResult</a></li>
1842
1843 <li data-name="LuCI.fs.FileStatEntry"><a href="LuCI.fs.html#.FileStatEntry">FileStatEntry</a></li>
1844
1845 </ul>
1846 <ul class="typedefs itemMembers">
1847
1848 </ul>
1849 <ul class="methods itemMembers">
1850
1851 <span class="subtitle">Methods</span>
1852
1853 <li data-name="LuCI.fs#exec"><a href="LuCI.fs.html#exec">exec</a></li>
1854
1855 <li data-name="LuCI.fs#exec_direct"><a href="LuCI.fs.html#exec_direct">exec_direct</a></li>
1856
1857 <li data-name="LuCI.fs#lines"><a href="LuCI.fs.html#lines">lines</a></li>
1858
1859 <li data-name="LuCI.fs#list"><a href="LuCI.fs.html#list">list</a></li>
1860
1861 <li data-name="LuCI.fs#read"><a href="LuCI.fs.html#read">read</a></li>
1862
1863 <li data-name="LuCI.fs#read_direct"><a href="LuCI.fs.html#read_direct">read_direct</a></li>
1864
1865 <li data-name="LuCI.fs#remove"><a href="LuCI.fs.html#remove">remove</a></li>
1866
1867 <li data-name="LuCI.fs#stat"><a href="LuCI.fs.html#stat">stat</a></li>
1868
1869 <li data-name="LuCI.fs#trimmed"><a href="LuCI.fs.html#trimmed">trimmed</a></li>
1870
1871 <li data-name="LuCI.fs#write"><a href="LuCI.fs.html#write">write</a></li>
1872
1873 </ul>
1874 <ul class="events itemMembers">
1875
1876 </ul>
1877 </li>
1878
1879 <li class="item" data-name="LuCI.headers">
1880 <span class="title">
1881 <a href="LuCI.headers.html">LuCI.headers</a>
1882
1883 </span>
1884 <ul class="members itemMembers">
1885
1886 </ul>
1887 <ul class="typedefs itemMembers">
1888
1889 </ul>
1890 <ul class="typedefs itemMembers">
1891
1892 </ul>
1893 <ul class="methods itemMembers">
1894
1895 <span class="subtitle">Methods</span>
1896
1897 <li data-name="LuCI.headers#get"><a href="LuCI.headers.html#get">get</a></li>
1898
1899 <li data-name="LuCI.headers#has"><a href="LuCI.headers.html#has">has</a></li>
1900
1901 </ul>
1902 <ul class="events itemMembers">
1903
1904 </ul>
1905 </li>
1906
1907 <li class="item" data-name="LuCI.network">
1908 <span class="title">
1909 <a href="LuCI.network.html">LuCI.network</a>
1910
1911 </span>
1912 <ul class="members itemMembers">
1913
1914 </ul>
1915 <ul class="typedefs itemMembers">
1916
1917 <span class="subtitle">Typedefs</span>
1918
1919 <li data-name="LuCI.network.SwitchTopology"><a href="LuCI.network.html#.SwitchTopology">SwitchTopology</a></li>
1920
1921 <li data-name="LuCI.network.WifiEncryption"><a href="LuCI.network.html#.WifiEncryption">WifiEncryption</a></li>
1922
1923 <li data-name="LuCI.network.WifiPeerEntry"><a href="LuCI.network.html#.WifiPeerEntry">WifiPeerEntry</a></li>
1924
1925 <li data-name="LuCI.network.WifiRateEntry"><a href="LuCI.network.html#.WifiRateEntry">WifiRateEntry</a></li>
1926
1927 <li data-name="LuCI.network.WifiScanResult"><a href="LuCI.network.html#.WifiScanResult">WifiScanResult</a></li>
1928
1929 </ul>
1930 <ul class="typedefs itemMembers">
1931
1932 </ul>
1933 <ul class="methods itemMembers">
1934
1935 <span class="subtitle">Methods</span>
1936
1937 <li data-name="LuCI.network#addNetwork"><a href="LuCI.network.html#addNetwork">addNetwork</a></li>
1938
1939 <li data-name="LuCI.network#addWifiNetwork"><a href="LuCI.network.html#addWifiNetwork">addWifiNetwork</a></li>
1940
1941 <li data-name="LuCI.network#deleteNetwork"><a href="LuCI.network.html#deleteNetwork">deleteNetwork</a></li>
1942
1943 <li data-name="LuCI.network#deleteWifiNetwork"><a href="LuCI.network.html#deleteWifiNetwork">deleteWifiNetwork</a></li>
1944
1945 <li data-name="LuCI.network#flushCache"><a href="LuCI.network.html#flushCache">flushCache</a></li>
1946
1947 <li data-name="LuCI.network#formatWifiEncryption"><a href="LuCI.network.html#formatWifiEncryption">formatWifiEncryption</a></li>
1948
1949 <li data-name="LuCI.network#getDevice"><a href="LuCI.network.html#getDevice">getDevice</a></li>
1950
1951 <li data-name="LuCI.network#getDevices"><a href="LuCI.network.html#getDevices">getDevices</a></li>
1952
1953 <li data-name="LuCI.network#getDSLModemType"><a href="LuCI.network.html#getDSLModemType">getDSLModemType</a></li>
1954
1955 <li data-name="LuCI.network#getHostHints"><a href="LuCI.network.html#getHostHints">getHostHints</a></li>
1956
1957 <li data-name="LuCI.network#getIfnameOf"><a href="LuCI.network.html#getIfnameOf">getIfnameOf</a></li>
1958
1959 <li data-name="LuCI.network#getNetwork"><a href="LuCI.network.html#getNetwork">getNetwork</a></li>
1960
1961 <li data-name="LuCI.network#getNetworks"><a href="LuCI.network.html#getNetworks">getNetworks</a></li>
1962
1963 <li data-name="LuCI.network#getProtocol"><a href="LuCI.network.html#getProtocol">getProtocol</a></li>
1964
1965 <li data-name="LuCI.network#getProtocols"><a href="LuCI.network.html#getProtocols">getProtocols</a></li>
1966
1967 <li data-name="LuCI.network#getSwitchTopologies"><a href="LuCI.network.html#getSwitchTopologies">getSwitchTopologies</a></li>
1968
1969 <li data-name="LuCI.network#getWAN6Networks"><a href="LuCI.network.html#getWAN6Networks">getWAN6Networks</a></li>
1970
1971 <li data-name="LuCI.network#getWANNetworks"><a href="LuCI.network.html#getWANNetworks">getWANNetworks</a></li>
1972
1973 <li data-name="LuCI.network#getWifiDevice"><a href="LuCI.network.html#getWifiDevice">getWifiDevice</a></li>
1974
1975 <li data-name="LuCI.network#getWifiDevices"><a href="LuCI.network.html#getWifiDevices">getWifiDevices</a></li>
1976
1977 <li data-name="LuCI.network#getWifiNetwork"><a href="LuCI.network.html#getWifiNetwork">getWifiNetwork</a></li>
1978
1979 <li data-name="LuCI.network#getWifiNetworks"><a href="LuCI.network.html#getWifiNetworks">getWifiNetworks</a></li>
1980
1981 <li data-name="LuCI.network#isIgnoredDevice"><a href="LuCI.network.html#isIgnoredDevice">isIgnoredDevice</a></li>
1982
1983 <li data-name="LuCI.network#maskToPrefix"><a href="LuCI.network.html#maskToPrefix">maskToPrefix</a></li>
1984
1985 <li data-name="LuCI.network#prefixToMask"><a href="LuCI.network.html#prefixToMask">prefixToMask</a></li>
1986
1987 <li data-name="LuCI.network#registerErrorCode"><a href="LuCI.network.html#registerErrorCode">registerErrorCode</a></li>
1988
1989 <li data-name="LuCI.network#registerPatternVirtual"><a href="LuCI.network.html#registerPatternVirtual">registerPatternVirtual</a></li>
1990
1991 <li data-name="LuCI.network#registerProtocol"><a href="LuCI.network.html#registerProtocol">registerProtocol</a></li>
1992
1993 <li data-name="LuCI.network#renameNetwork"><a href="LuCI.network.html#renameNetwork">renameNetwork</a></li>
1994
1995 </ul>
1996 <ul class="events itemMembers">
1997
1998 </ul>
1999 </li>
2000
2001 <li class="item" data-name="LuCI.network.Device">
2002 <span class="title">
2003 <a href="LuCI.network.Device.html">LuCI.network.Device</a>
2004
2005 </span>
2006 <ul class="members itemMembers">
2007
2008 </ul>
2009 <ul class="typedefs itemMembers">
2010
2011 </ul>
2012 <ul class="typedefs itemMembers">
2013
2014 </ul>
2015 <ul class="methods itemMembers">
2016
2017 <span class="subtitle">Methods</span>
2018
2019 <li data-name="LuCI.network.Device#getBridgeID"><a href="LuCI.network.Device.html#getBridgeID">getBridgeID</a></li>
2020
2021 <li data-name="LuCI.network.Device#getBridgeSTP"><a href="LuCI.network.Device.html#getBridgeSTP">getBridgeSTP</a></li>
2022
2023 <li data-name="LuCI.network.Device#getI18n"><a href="LuCI.network.Device.html#getI18n">getI18n</a></li>
2024
2025 <li data-name="LuCI.network.Device#getIP6Addrs"><a href="LuCI.network.Device.html#getIP6Addrs">getIP6Addrs</a></li>
2026
2027 <li data-name="LuCI.network.Device#getIPAddrs"><a href="LuCI.network.Device.html#getIPAddrs">getIPAddrs</a></li>
2028
2029 <li data-name="LuCI.network.Device#getMAC"><a href="LuCI.network.Device.html#getMAC">getMAC</a></li>
2030
2031 <li data-name="LuCI.network.Device#getMTU"><a href="LuCI.network.Device.html#getMTU">getMTU</a></li>
2032
2033 <li data-name="LuCI.network.Device#getName"><a href="LuCI.network.Device.html#getName">getName</a></li>
2034
2035 <li data-name="LuCI.network.Device#getNetwork"><a href="LuCI.network.Device.html#getNetwork">getNetwork</a></li>
2036
2037 <li data-name="LuCI.network.Device#getNetworks"><a href="LuCI.network.Device.html#getNetworks">getNetworks</a></li>
2038
2039 <li data-name="LuCI.network.Device#getPorts"><a href="LuCI.network.Device.html#getPorts">getPorts</a></li>
2040
2041 <li data-name="LuCI.network.Device#getRXBytes"><a href="LuCI.network.Device.html#getRXBytes">getRXBytes</a></li>
2042
2043 <li data-name="LuCI.network.Device#getRXPackets"><a href="LuCI.network.Device.html#getRXPackets">getRXPackets</a></li>
2044
2045 <li data-name="LuCI.network.Device#getShortName"><a href="LuCI.network.Device.html#getShortName">getShortName</a></li>
2046
2047 <li data-name="LuCI.network.Device#getTXBytes"><a href="LuCI.network.Device.html#getTXBytes">getTXBytes</a></li>
2048
2049 <li data-name="LuCI.network.Device#getTXPackets"><a href="LuCI.network.Device.html#getTXPackets">getTXPackets</a></li>
2050
2051 <li data-name="LuCI.network.Device#getType"><a href="LuCI.network.Device.html#getType">getType</a></li>
2052
2053 <li data-name="LuCI.network.Device#getTypeI18n"><a href="LuCI.network.Device.html#getTypeI18n">getTypeI18n</a></li>
2054
2055 <li data-name="LuCI.network.Device#getWifiNetwork"><a href="LuCI.network.Device.html#getWifiNetwork">getWifiNetwork</a></li>
2056
2057 <li data-name="LuCI.network.Device#isBridge"><a href="LuCI.network.Device.html#isBridge">isBridge</a></li>
2058
2059 <li data-name="LuCI.network.Device#isBridgePort"><a href="LuCI.network.Device.html#isBridgePort">isBridgePort</a></li>
2060
2061 <li data-name="LuCI.network.Device#isUp"><a href="LuCI.network.Device.html#isUp">isUp</a></li>
2062
2063 </ul>
2064 <ul class="events itemMembers">
2065
2066 </ul>
2067 </li>
2068
2069 <li class="item" data-name="LuCI.network.Hosts">
2070 <span class="title">
2071 <a href="LuCI.network.Hosts.html">LuCI.network.Hosts</a>
2072
2073 </span>
2074 <ul class="members itemMembers">
2075
2076 </ul>
2077 <ul class="typedefs itemMembers">
2078
2079 </ul>
2080 <ul class="typedefs itemMembers">
2081
2082 </ul>
2083 <ul class="methods itemMembers">
2084
2085 <span class="subtitle">Methods</span>
2086
2087 <li data-name="LuCI.network.Hosts#getHostnameByIP6Addr"><a href="LuCI.network.Hosts.html#getHostnameByIP6Addr">getHostnameByIP6Addr</a></li>
2088
2089 <li data-name="LuCI.network.Hosts#getHostnameByIPAddr"><a href="LuCI.network.Hosts.html#getHostnameByIPAddr">getHostnameByIPAddr</a></li>
2090
2091 <li data-name="LuCI.network.Hosts#getHostnameByMACAddr"><a href="LuCI.network.Hosts.html#getHostnameByMACAddr">getHostnameByMACAddr</a></li>
2092
2093 <li data-name="LuCI.network.Hosts#getIP6AddrByMACAddr"><a href="LuCI.network.Hosts.html#getIP6AddrByMACAddr">getIP6AddrByMACAddr</a></li>
2094
2095 <li data-name="LuCI.network.Hosts#getIPAddrByMACAddr"><a href="LuCI.network.Hosts.html#getIPAddrByMACAddr">getIPAddrByMACAddr</a></li>
2096
2097 <li data-name="LuCI.network.Hosts#getMACAddrByIP6Addr"><a href="LuCI.network.Hosts.html#getMACAddrByIP6Addr">getMACAddrByIP6Addr</a></li>
2098
2099 <li data-name="LuCI.network.Hosts#getMACAddrByIPAddr"><a href="LuCI.network.Hosts.html#getMACAddrByIPAddr">getMACAddrByIPAddr</a></li>
2100
2101 <li data-name="LuCI.network.Hosts#getMACHints"><a href="LuCI.network.Hosts.html#getMACHints">getMACHints</a></li>
2102
2103 </ul>
2104 <ul class="events itemMembers">
2105
2106 </ul>
2107 </li>
2108
2109 <li class="item" data-name="LuCI.network.Protocol">
2110 <span class="title">
2111 <a href="LuCI.network.Protocol.html">LuCI.network.Protocol</a>
2112
2113 </span>
2114 <ul class="members itemMembers">
2115
2116 </ul>
2117 <ul class="typedefs itemMembers">
2118
2119 </ul>
2120 <ul class="typedefs itemMembers">
2121
2122 </ul>
2123 <ul class="methods itemMembers">
2124
2125 <span class="subtitle">Methods</span>
2126
2127 <li data-name="LuCI.network.Protocol#addDevice"><a href="LuCI.network.Protocol.html#addDevice">addDevice</a></li>
2128
2129 <li data-name="LuCI.network.Protocol#containsDevice"><a href="LuCI.network.Protocol.html#containsDevice">containsDevice</a></li>
2130
2131 <li data-name="LuCI.network.Protocol#deleteConfiguration"><a href="LuCI.network.Protocol.html#deleteConfiguration">deleteConfiguration</a></li>
2132
2133 <li data-name="LuCI.network.Protocol#deleteDevice"><a href="LuCI.network.Protocol.html#deleteDevice">deleteDevice</a></li>
2134
2135 <li data-name="LuCI.network.Protocol#get"><a href="LuCI.network.Protocol.html#get">get</a></li>
2136
2137 <li data-name="LuCI.network.Protocol#getDevice"><a href="LuCI.network.Protocol.html#getDevice">getDevice</a></li>
2138
2139 <li data-name="LuCI.network.Protocol#getDevices"><a href="LuCI.network.Protocol.html#getDevices">getDevices</a></li>
2140
2141 <li data-name="LuCI.network.Protocol#getDNS6Addrs"><a href="LuCI.network.Protocol.html#getDNS6Addrs">getDNS6Addrs</a></li>
2142
2143 <li data-name="LuCI.network.Protocol#getDNSAddrs"><a href="LuCI.network.Protocol.html#getDNSAddrs">getDNSAddrs</a></li>
2144
2145 <li data-name="LuCI.network.Protocol#getErrors"><a href="LuCI.network.Protocol.html#getErrors">getErrors</a></li>
2146
2147 <li data-name="LuCI.network.Protocol#getExpiry"><a href="LuCI.network.Protocol.html#getExpiry">getExpiry</a></li>
2148
2149 <li data-name="LuCI.network.Protocol#getGateway6Addr"><a href="LuCI.network.Protocol.html#getGateway6Addr">getGateway6Addr</a></li>
2150
2151 <li data-name="LuCI.network.Protocol#getGatewayAddr"><a href="LuCI.network.Protocol.html#getGatewayAddr">getGatewayAddr</a></li>
2152
2153 <li data-name="LuCI.network.Protocol#getI18n"><a href="LuCI.network.Protocol.html#getI18n">getI18n</a></li>
2154
2155 <li data-name="LuCI.network.Protocol#getIfname"><a href="LuCI.network.Protocol.html#getIfname">getIfname</a></li>
2156
2157 <li data-name="LuCI.network.Protocol#getIP6Addr"><a href="LuCI.network.Protocol.html#getIP6Addr">getIP6Addr</a></li>
2158
2159 <li data-name="LuCI.network.Protocol#getIP6Addrs"><a href="LuCI.network.Protocol.html#getIP6Addrs">getIP6Addrs</a></li>
2160
2161 <li data-name="LuCI.network.Protocol#getIP6Prefix"><a href="LuCI.network.Protocol.html#getIP6Prefix">getIP6Prefix</a></li>
2162
2163 <li data-name="LuCI.network.Protocol#getIPAddr"><a href="LuCI.network.Protocol.html#getIPAddr">getIPAddr</a></li>
2164
2165 <li data-name="LuCI.network.Protocol#getIPAddrs"><a href="LuCI.network.Protocol.html#getIPAddrs">getIPAddrs</a></li>
2166
2167 <li data-name="LuCI.network.Protocol#getL2Device"><a href="LuCI.network.Protocol.html#getL2Device">getL2Device</a></li>
2168
2169 <li data-name="LuCI.network.Protocol#getL3Device"><a href="LuCI.network.Protocol.html#getL3Device">getL3Device</a></li>
2170
2171 <li data-name="LuCI.network.Protocol#getMetric"><a href="LuCI.network.Protocol.html#getMetric">getMetric</a></li>
2172
2173 <li data-name="LuCI.network.Protocol#getName"><a href="LuCI.network.Protocol.html#getName">getName</a></li>
2174
2175 <li data-name="LuCI.network.Protocol#getNetmask"><a href="LuCI.network.Protocol.html#getNetmask">getNetmask</a></li>
2176
2177 <li data-name="LuCI.network.Protocol#getOpkgPackage"><a href="LuCI.network.Protocol.html#getOpkgPackage">getOpkgPackage</a></li>
2178
2179 <li data-name="LuCI.network.Protocol#getProtocol"><a href="LuCI.network.Protocol.html#getProtocol">getProtocol</a></li>
2180
2181 <li data-name="LuCI.network.Protocol#getType"><a href="LuCI.network.Protocol.html#getType">getType</a></li>
2182
2183 <li data-name="LuCI.network.Protocol#getUptime"><a href="LuCI.network.Protocol.html#getUptime">getUptime</a></li>
2184
2185 <li data-name="LuCI.network.Protocol#getZoneName"><a href="LuCI.network.Protocol.html#getZoneName">getZoneName</a></li>
2186
2187 <li data-name="LuCI.network.Protocol#isAlias"><a href="LuCI.network.Protocol.html#isAlias">isAlias</a></li>
2188
2189 <li data-name="LuCI.network.Protocol#isBridge"><a href="LuCI.network.Protocol.html#isBridge">isBridge</a></li>
2190
2191 <li data-name="LuCI.network.Protocol#isCreateable"><a href="LuCI.network.Protocol.html#isCreateable">isCreateable</a></li>
2192
2193 <li data-name="LuCI.network.Protocol#isDynamic"><a href="LuCI.network.Protocol.html#isDynamic">isDynamic</a></li>
2194
2195 <li data-name="LuCI.network.Protocol#isEmpty"><a href="LuCI.network.Protocol.html#isEmpty">isEmpty</a></li>
2196
2197 <li data-name="LuCI.network.Protocol#isFloating"><a href="LuCI.network.Protocol.html#isFloating">isFloating</a></li>
2198
2199 <li data-name="LuCI.network.Protocol#isInstalled"><a href="LuCI.network.Protocol.html#isInstalled">isInstalled</a></li>
2200
2201 <li data-name="LuCI.network.Protocol#isUp"><a href="LuCI.network.Protocol.html#isUp">isUp</a></li>
2202
2203 <li data-name="LuCI.network.Protocol#isVirtual"><a href="LuCI.network.Protocol.html#isVirtual">isVirtual</a></li>
2204
2205 <li data-name="LuCI.network.Protocol#set"><a href="LuCI.network.Protocol.html#set">set</a></li>
2206
2207 </ul>
2208 <ul class="events itemMembers">
2209
2210 </ul>
2211 </li>
2212
2213 <li class="item" data-name="LuCI.network.WifiDevice">
2214 <span class="title">
2215 <a href="LuCI.network.WifiDevice.html">LuCI.network.WifiDevice</a>
2216
2217 </span>
2218 <ul class="members itemMembers">
2219
2220 </ul>
2221 <ul class="typedefs itemMembers">
2222
2223 </ul>
2224 <ul class="typedefs itemMembers">
2225
2226 </ul>
2227 <ul class="methods itemMembers">
2228
2229 <span class="subtitle">Methods</span>
2230
2231 <li data-name="LuCI.network.WifiDevice#addWifiNetwork"><a href="LuCI.network.WifiDevice.html#addWifiNetwork">addWifiNetwork</a></li>
2232
2233 <li data-name="LuCI.network.WifiDevice#deleteWifiNetwork"><a href="LuCI.network.WifiDevice.html#deleteWifiNetwork">deleteWifiNetwork</a></li>
2234
2235 <li data-name="LuCI.network.WifiDevice#get"><a href="LuCI.network.WifiDevice.html#get">get</a></li>
2236
2237 <li data-name="LuCI.network.WifiDevice#getHTModes"><a href="LuCI.network.WifiDevice.html#getHTModes">getHTModes</a></li>
2238
2239 <li data-name="LuCI.network.WifiDevice#getHWModes"><a href="LuCI.network.WifiDevice.html#getHWModes">getHWModes</a></li>
2240
2241 <li data-name="LuCI.network.WifiDevice#getI18n"><a href="LuCI.network.WifiDevice.html#getI18n">getI18n</a></li>
2242
2243 <li data-name="LuCI.network.WifiDevice#getName"><a href="LuCI.network.WifiDevice.html#getName">getName</a></li>
2244
2245 <li data-name="LuCI.network.WifiDevice#getScanList"><a href="LuCI.network.WifiDevice.html#getScanList">getScanList</a></li>
2246
2247 <li data-name="LuCI.network.WifiDevice#getWifiNetwork"><a href="LuCI.network.WifiDevice.html#getWifiNetwork">getWifiNetwork</a></li>
2248
2249 <li data-name="LuCI.network.WifiDevice#getWifiNetworks"><a href="LuCI.network.WifiDevice.html#getWifiNetworks">getWifiNetworks</a></li>
2250
2251 <li data-name="LuCI.network.WifiDevice#isDisabled"><a href="LuCI.network.WifiDevice.html#isDisabled">isDisabled</a></li>
2252
2253 <li data-name="LuCI.network.WifiDevice#isUp"><a href="LuCI.network.WifiDevice.html#isUp">isUp</a></li>
2254
2255 <li data-name="LuCI.network.WifiDevice#set"><a href="LuCI.network.WifiDevice.html#set">set</a></li>
2256
2257 </ul>
2258 <ul class="events itemMembers">
2259
2260 </ul>
2261 </li>
2262
2263 <li class="item" data-name="LuCI.network.WifiNetwork">
2264 <span class="title">
2265 <a href="LuCI.network.WifiNetwork.html">LuCI.network.WifiNetwork</a>
2266
2267 </span>
2268 <ul class="members itemMembers">
2269
2270 </ul>
2271 <ul class="typedefs itemMembers">
2272
2273 </ul>
2274 <ul class="typedefs itemMembers">
2275
2276 </ul>
2277 <ul class="methods itemMembers">
2278
2279 <span class="subtitle">Methods</span>
2280
2281 <li data-name="LuCI.network.WifiNetwork#disconnectClient"><a href="LuCI.network.WifiNetwork.html#disconnectClient">disconnectClient</a></li>
2282
2283 <li data-name="LuCI.network.WifiNetwork#get"><a href="LuCI.network.WifiNetwork.html#get">get</a></li>
2284
2285 <li data-name="LuCI.network.WifiNetwork#getActiveBSSID"><a href="LuCI.network.WifiNetwork.html#getActiveBSSID">getActiveBSSID</a></li>
2286
2287 <li data-name="LuCI.network.WifiNetwork#getActiveEncryption"><a href="LuCI.network.WifiNetwork.html#getActiveEncryption">getActiveEncryption</a></li>
2288
2289 <li data-name="LuCI.network.WifiNetwork#getActiveMode"><a href="LuCI.network.WifiNetwork.html#getActiveMode">getActiveMode</a></li>
2290
2291 <li data-name="LuCI.network.WifiNetwork#getActiveModeI18n"><a href="LuCI.network.WifiNetwork.html#getActiveModeI18n">getActiveModeI18n</a></li>
2292
2293 <li data-name="LuCI.network.WifiNetwork#getActiveSSID"><a href="LuCI.network.WifiNetwork.html#getActiveSSID">getActiveSSID</a></li>
2294
2295 <li data-name="LuCI.network.WifiNetwork#getAssocList"><a href="LuCI.network.WifiNetwork.html#getAssocList">getAssocList</a></li>
2296
2297 <li data-name="LuCI.network.WifiNetwork#getBitRate"><a href="LuCI.network.WifiNetwork.html#getBitRate">getBitRate</a></li>
2298
2299 <li data-name="LuCI.network.WifiNetwork#getBSSID"><a href="LuCI.network.WifiNetwork.html#getBSSID">getBSSID</a></li>
2300
2301 <li data-name="LuCI.network.WifiNetwork#getChannel"><a href="LuCI.network.WifiNetwork.html#getChannel">getChannel</a></li>
2302
2303 <li data-name="LuCI.network.WifiNetwork#getCountryCode"><a href="LuCI.network.WifiNetwork.html#getCountryCode">getCountryCode</a></li>
2304
2305 <li data-name="LuCI.network.WifiNetwork#getDevice"><a href="LuCI.network.WifiNetwork.html#getDevice">getDevice</a></li>
2306
2307 <li data-name="LuCI.network.WifiNetwork#getFrequency"><a href="LuCI.network.WifiNetwork.html#getFrequency">getFrequency</a></li>
2308
2309 <li data-name="LuCI.network.WifiNetwork#getI18n"><a href="LuCI.network.WifiNetwork.html#getI18n">getI18n</a></li>
2310
2311 <li data-name="LuCI.network.WifiNetwork#getID"><a href="LuCI.network.WifiNetwork.html#getID">getID</a></li>
2312
2313 <li data-name="LuCI.network.WifiNetwork#getIfname"><a href="LuCI.network.WifiNetwork.html#getIfname">getIfname</a></li>
2314
2315 <li data-name="LuCI.network.WifiNetwork#getMeshID"><a href="LuCI.network.WifiNetwork.html#getMeshID">getMeshID</a></li>
2316
2317 <li data-name="LuCI.network.WifiNetwork#getMode"><a href="LuCI.network.WifiNetwork.html#getMode">getMode</a></li>
2318
2319 <li data-name="LuCI.network.WifiNetwork#getName"><a href="LuCI.network.WifiNetwork.html#getName">getName</a></li>
2320
2321 <li data-name="LuCI.network.WifiNetwork#getNetwork"><a href="LuCI.network.WifiNetwork.html#getNetwork">getNetwork</a></li>
2322
2323 <li data-name="LuCI.network.WifiNetwork#getNetworkNames"><a href="LuCI.network.WifiNetwork.html#getNetworkNames">getNetworkNames</a></li>
2324
2325 <li data-name="LuCI.network.WifiNetwork#getNetworks"><a href="LuCI.network.WifiNetwork.html#getNetworks">getNetworks</a></li>
2326
2327 <li data-name="LuCI.network.WifiNetwork#getNoise"><a href="LuCI.network.WifiNetwork.html#getNoise">getNoise</a></li>
2328
2329 <li data-name="LuCI.network.WifiNetwork#getShortName"><a href="LuCI.network.WifiNetwork.html#getShortName">getShortName</a></li>
2330
2331 <li data-name="LuCI.network.WifiNetwork#getSignal"><a href="LuCI.network.WifiNetwork.html#getSignal">getSignal</a></li>
2332
2333 <li data-name="LuCI.network.WifiNetwork#getSignalLevel"><a href="LuCI.network.WifiNetwork.html#getSignalLevel">getSignalLevel</a></li>
2334
2335 <li data-name="LuCI.network.WifiNetwork#getSignalPercent"><a href="LuCI.network.WifiNetwork.html#getSignalPercent">getSignalPercent</a></li>
2336
2337 <li data-name="LuCI.network.WifiNetwork#getSSID"><a href="LuCI.network.WifiNetwork.html#getSSID">getSSID</a></li>
2338
2339 <li data-name="LuCI.network.WifiNetwork#getTXPower"><a href="LuCI.network.WifiNetwork.html#getTXPower">getTXPower</a></li>
2340
2341 <li data-name="LuCI.network.WifiNetwork#getTXPowerOffset"><a href="LuCI.network.WifiNetwork.html#getTXPowerOffset">getTXPowerOffset</a></li>
2342
2343 <li data-name="LuCI.network.WifiNetwork#getWifiDevice"><a href="LuCI.network.WifiNetwork.html#getWifiDevice">getWifiDevice</a></li>
2344
2345 <li data-name="LuCI.network.WifiNetwork#getWifiDeviceName"><a href="LuCI.network.WifiNetwork.html#getWifiDeviceName">getWifiDeviceName</a></li>
2346
2347 <li data-name="LuCI.network.WifiNetwork#isClientDisconnectSupported"><a href="LuCI.network.WifiNetwork.html#isClientDisconnectSupported">isClientDisconnectSupported</a></li>
2348
2349 <li data-name="LuCI.network.WifiNetwork#isDisabled"><a href="LuCI.network.WifiNetwork.html#isDisabled">isDisabled</a></li>
2350
2351 <li data-name="LuCI.network.WifiNetwork#isUp"><a href="LuCI.network.WifiNetwork.html#isUp">isUp</a></li>
2352
2353 <li data-name="LuCI.network.WifiNetwork#set"><a href="LuCI.network.WifiNetwork.html#set">set</a></li>
2354
2355 </ul>
2356 <ul class="events itemMembers">
2357
2358 </ul>
2359 </li>
2360
2361 <li class="item" data-name="LuCI.poll">
2362 <span class="title">
2363 <a href="LuCI.poll.html">LuCI.poll</a>
2364
2365 </span>
2366 <ul class="members itemMembers">
2367
2368 </ul>
2369 <ul class="typedefs itemMembers">
2370
2371 </ul>
2372 <ul class="typedefs itemMembers">
2373
2374 </ul>
2375 <ul class="methods itemMembers">
2376
2377 <span class="subtitle">Methods</span>
2378
2379 <li data-name="LuCI.poll#active"><a href="LuCI.poll.html#active">active</a></li>
2380
2381 <li data-name="LuCI.poll#add"><a href="LuCI.poll.html#add">add</a></li>
2382
2383 <li data-name="LuCI.poll#remove"><a href="LuCI.poll.html#remove">remove</a></li>
2384
2385 <li data-name="LuCI.poll#start"><a href="LuCI.poll.html#start">start</a></li>
2386
2387 <li data-name="LuCI.poll#stop"><a href="LuCI.poll.html#stop">stop</a></li>
2388
2389 </ul>
2390 <ul class="events itemMembers">
2391
2392 </ul>
2393 </li>
2394
2395 <li class="item" data-name="LuCI.request">
2396 <span class="title">
2397 <a href="LuCI.request.html">LuCI.request</a>
2398
2399 </span>
2400 <ul class="members itemMembers">
2401
2402 </ul>
2403 <ul class="typedefs itemMembers">
2404
2405 <span class="subtitle">Typedefs</span>
2406
2407 <li data-name="LuCI.request.interceptorFn"><a href="LuCI.request.html#.interceptorFn">interceptorFn</a></li>
2408
2409 <li data-name="LuCI.request.RequestOptions"><a href="LuCI.request.html#.RequestOptions">RequestOptions</a></li>
2410
2411 </ul>
2412 <ul class="typedefs itemMembers">
2413
2414 </ul>
2415 <ul class="methods itemMembers">
2416
2417 <span class="subtitle">Methods</span>
2418
2419 <li data-name="LuCI.request#addInterceptor"><a href="LuCI.request.html#addInterceptor">addInterceptor</a></li>
2420
2421 <li data-name="LuCI.request#expandURL"><a href="LuCI.request.html#expandURL">expandURL</a></li>
2422
2423 <li data-name="LuCI.request#get"><a href="LuCI.request.html#get">get</a></li>
2424
2425 <li data-name="LuCI.request#post"><a href="LuCI.request.html#post">post</a></li>
2426
2427 <li data-name="LuCI.request#removeInterceptor"><a href="LuCI.request.html#removeInterceptor">removeInterceptor</a></li>
2428
2429 <li data-name="LuCI.request#request"><a href="LuCI.request.html#request">request</a></li>
2430
2431 </ul>
2432 <ul class="events itemMembers">
2433
2434 </ul>
2435 </li>
2436
2437 <li class="item" data-name="LuCI.request.poll">
2438 <span class="title">
2439 <a href="LuCI.request.poll.html">LuCI.request.poll</a>
2440
2441 </span>
2442 <ul class="members itemMembers">
2443
2444 </ul>
2445 <ul class="typedefs itemMembers">
2446
2447 <span class="subtitle">Typedefs</span>
2448
2449 <li data-name="LuCI.request.poll~callbackFn"><a href="LuCI.request.poll.html#~callbackFn">callbackFn</a></li>
2450
2451 </ul>
2452 <ul class="typedefs itemMembers">
2453
2454 </ul>
2455 <ul class="methods itemMembers">
2456
2457 <span class="subtitle">Methods</span>
2458
2459 <li data-name="LuCI.request.poll#active"><a href="LuCI.request.poll.html#active">active</a></li>
2460
2461 <li data-name="LuCI.request.poll#add"><a href="LuCI.request.poll.html#add">add</a></li>
2462
2463 <li data-name="LuCI.request.poll#remove"><a href="LuCI.request.poll.html#remove">remove</a></li>
2464
2465 <li data-name="LuCI.request.poll#start"><a href="LuCI.request.poll.html#start">start</a></li>
2466
2467 <li data-name="LuCI.request.poll#stop"><a href="LuCI.request.poll.html#stop">stop</a></li>
2468
2469 </ul>
2470 <ul class="events itemMembers">
2471
2472 </ul>
2473 </li>
2474
2475 <li class="item" data-name="LuCI.response">
2476 <span class="title">
2477 <a href="LuCI.response.html">LuCI.response</a>
2478
2479 </span>
2480 <ul class="members itemMembers">
2481
2482 <span class="subtitle">Members</span>
2483
2484 <li data-name="LuCI.response#duration"><a href="LuCI.response.html#duration">duration</a></li>
2485
2486 <li data-name="LuCI.response#headers"><a href="LuCI.response.html#headers">headers</a></li>
2487
2488 <li data-name="LuCI.response#ok"><a href="LuCI.response.html#ok">ok</a></li>
2489
2490 <li data-name="LuCI.response#status"><a href="LuCI.response.html#status">status</a></li>
2491
2492 <li data-name="LuCI.response#statusText"><a href="LuCI.response.html#statusText">statusText</a></li>
2493
2494 <li data-name="LuCI.response#url"><a href="LuCI.response.html#url">url</a></li>
2495
2496 </ul>
2497 <ul class="typedefs itemMembers">
2498
2499 </ul>
2500 <ul class="typedefs itemMembers">
2501
2502 </ul>
2503 <ul class="methods itemMembers">
2504
2505 <span class="subtitle">Methods</span>
2506
2507 <li data-name="LuCI.response#blob"><a href="LuCI.response.html#blob">blob</a></li>
2508
2509 <li data-name="LuCI.response#clone"><a href="LuCI.response.html#clone">clone</a></li>
2510
2511 <li data-name="LuCI.response#json"><a href="LuCI.response.html#json">json</a></li>
2512
2513 <li data-name="LuCI.response#text"><a href="LuCI.response.html#text">text</a></li>
2514
2515 </ul>
2516 <ul class="events itemMembers">
2517
2518 </ul>
2519 </li>
2520
2521 <li class="item" data-name="LuCI.rpc">
2522 <span class="title">
2523 <a href="LuCI.rpc.html">LuCI.rpc</a>
2524
2525 </span>
2526 <ul class="members itemMembers">
2527
2528 </ul>
2529 <ul class="typedefs itemMembers">
2530
2531 <span class="subtitle">Typedefs</span>
2532
2533 <li data-name="LuCI.rpc.DeclareOptions"><a href="LuCI.rpc.html#.DeclareOptions">DeclareOptions</a></li>
2534
2535 <li data-name="LuCI.rpc~filterFn"><a href="LuCI.rpc.html#~filterFn">filterFn</a></li>
2536
2537 <li data-name="LuCI.rpc~interceptorFn"><a href="LuCI.rpc.html#~interceptorFn">interceptorFn</a></li>
2538
2539 <li data-name="LuCI.rpc~invokeFn"><a href="LuCI.rpc.html#~invokeFn">invokeFn</a></li>
2540
2541 </ul>
2542 <ul class="typedefs itemMembers">
2543
2544 </ul>
2545 <ul class="methods itemMembers">
2546
2547 <span class="subtitle">Methods</span>
2548
2549 <li data-name="LuCI.rpc#addInterceptor"><a href="LuCI.rpc.html#addInterceptor">addInterceptor</a></li>
2550
2551 <li data-name="LuCI.rpc#declare"><a href="LuCI.rpc.html#declare">declare</a></li>
2552
2553 <li data-name="LuCI.rpc#getBaseURL"><a href="LuCI.rpc.html#getBaseURL">getBaseURL</a></li>
2554
2555 <li data-name="LuCI.rpc#getSessionID"><a href="LuCI.rpc.html#getSessionID">getSessionID</a></li>
2556
2557 <li data-name="LuCI.rpc#getStatusText"><a href="LuCI.rpc.html#getStatusText">getStatusText</a></li>
2558
2559 <li data-name="LuCI.rpc#list"><a href="LuCI.rpc.html#list">list</a></li>
2560
2561 <li data-name="LuCI.rpc#removeInterceptor"><a href="LuCI.rpc.html#removeInterceptor">removeInterceptor</a></li>
2562
2563 <li data-name="LuCI.rpc#setBaseURL"><a href="LuCI.rpc.html#setBaseURL">setBaseURL</a></li>
2564
2565 <li data-name="LuCI.rpc#setSessionID"><a href="LuCI.rpc.html#setSessionID">setSessionID</a></li>
2566
2567 </ul>
2568 <ul class="events itemMembers">
2569
2570 </ul>
2571 </li>
2572
2573 <li class="item" data-name="LuCI.session">
2574 <span class="title">
2575 <a href="LuCI.session.html">LuCI.session</a>
2576
2577 </span>
2578 <ul class="members itemMembers">
2579
2580 </ul>
2581 <ul class="typedefs itemMembers">
2582
2583 </ul>
2584 <ul class="typedefs itemMembers">
2585
2586 </ul>
2587 <ul class="methods itemMembers">
2588
2589 <span class="subtitle">Methods</span>
2590
2591 <li data-name="LuCI.session#getID"><a href="LuCI.session.html#getID">getID</a></li>
2592
2593 <li data-name="LuCI.session#getLocalData"><a href="LuCI.session.html#getLocalData">getLocalData</a></li>
2594
2595 <li data-name="LuCI.session#getToken"><a href="LuCI.session.html#getToken">getToken</a></li>
2596
2597 <li data-name="LuCI.session#setLocalData"><a href="LuCI.session.html#setLocalData">setLocalData</a></li>
2598
2599 </ul>
2600 <ul class="events itemMembers">
2601
2602 </ul>
2603 </li>
2604
2605 <li class="item" data-name="LuCI.uci">
2606 <span class="title">
2607 <a href="LuCI.uci.html">LuCI.uci</a>
2608
2609 </span>
2610 <ul class="members itemMembers">
2611
2612 </ul>
2613 <ul class="typedefs itemMembers">
2614
2615 <span class="subtitle">Typedefs</span>
2616
2617 <li data-name="LuCI.uci.ChangeRecord"><a href="LuCI.uci.html#.ChangeRecord">ChangeRecord</a></li>
2618
2619 <li data-name="LuCI.uci.SectionObject"><a href="LuCI.uci.html#.SectionObject">SectionObject</a></li>
2620
2621 <li data-name="LuCI.uci~sectionsFn"><a href="LuCI.uci.html#~sectionsFn">sectionsFn</a></li>
2622
2623 </ul>
2624 <ul class="typedefs itemMembers">
2625
2626 </ul>
2627 <ul class="methods itemMembers">
2628
2629 <span class="subtitle">Methods</span>
2630
2631 <li data-name="LuCI.uci#add"><a href="LuCI.uci.html#add">add</a></li>
2632
2633 <li data-name="LuCI.uci#apply"><a href="LuCI.uci.html#apply">apply</a></li>
2634
2635 <li data-name="LuCI.uci#changes"><a href="LuCI.uci.html#changes">changes</a></li>
2636
2637 <li data-name="LuCI.uci#createSID"><a href="LuCI.uci.html#createSID">createSID</a></li>
2638
2639 <li data-name="LuCI.uci#get"><a href="LuCI.uci.html#get">get</a></li>
2640
2641 <li data-name="LuCI.uci#get_first"><a href="LuCI.uci.html#get_first">get_first</a></li>
2642
2643 <li data-name="LuCI.uci#load"><a href="LuCI.uci.html#load">load</a></li>
2644
2645 <li data-name="LuCI.uci#move"><a href="LuCI.uci.html#move">move</a></li>
2646
2647 <li data-name="LuCI.uci#remove"><a href="LuCI.uci.html#remove">remove</a></li>
2648
2649 <li data-name="LuCI.uci#resolveSID"><a href="LuCI.uci.html#resolveSID">resolveSID</a></li>
2650
2651 <li data-name="LuCI.uci#save"><a href="LuCI.uci.html#save">save</a></li>
2652
2653 <li data-name="LuCI.uci#sections"><a href="LuCI.uci.html#sections">sections</a></li>
2654
2655 <li data-name="LuCI.uci#set"><a href="LuCI.uci.html#set">set</a></li>
2656
2657 <li data-name="LuCI.uci#set_first"><a href="LuCI.uci.html#set_first">set_first</a></li>
2658
2659 <li data-name="LuCI.uci#unload"><a href="LuCI.uci.html#unload">unload</a></li>
2660
2661 <li data-name="LuCI.uci#unset"><a href="LuCI.uci.html#unset">unset</a></li>
2662
2663 <li data-name="LuCI.uci#unset_first"><a href="LuCI.uci.html#unset_first">unset_first</a></li>
2664
2665 </ul>
2666 <ul class="events itemMembers">
2667
2668 </ul>
2669 </li>
2670
2671 <li class="item" data-name="LuCI.ui">
2672 <span class="title">
2673 <a href="LuCI.ui.html">LuCI.ui</a>
2674
2675 </span>
2676 <ul class="members itemMembers">
2677
2678 </ul>
2679 <ul class="typedefs itemMembers">
2680
2681 <span class="subtitle">Typedefs</span>
2682
2683 <li data-name="LuCI.ui.FileUploadReply"><a href="LuCI.ui.html#.FileUploadReply">FileUploadReply</a></li>
2684
2685 </ul>
2686 <ul class="typedefs itemMembers">
2687
2688 </ul>
2689 <ul class="methods itemMembers">
2690
2691 <span class="subtitle">Methods</span>
2692
2693 <li data-name="LuCI.ui#addNotification"><a href="LuCI.ui.html#addNotification">addNotification</a></li>
2694
2695 <li data-name="LuCI.ui#addValidator"><a href="LuCI.ui.html#addValidator">addValidator</a></li>
2696
2697 <li data-name="LuCI.ui#awaitReconnect"><a href="LuCI.ui.html#awaitReconnect">awaitReconnect</a></li>
2698
2699 <li data-name="LuCI.ui#createHandlerFn"><a href="LuCI.ui.html#createHandlerFn">createHandlerFn</a></li>
2700
2701 <li data-name="LuCI.ui#hideIndicator"><a href="LuCI.ui.html#hideIndicator">hideIndicator</a></li>
2702
2703 <li data-name="LuCI.ui#hideModal"><a href="LuCI.ui.html#hideModal">hideModal</a></li>
2704
2705 <li data-name="LuCI.ui#instantiateView"><a href="LuCI.ui.html#instantiateView">instantiateView</a></li>
2706
2707 <li data-name="LuCI.ui#itemlist"><a href="LuCI.ui.html#itemlist">itemlist</a></li>
2708
2709 <li data-name="LuCI.ui#pingDevice"><a href="LuCI.ui.html#pingDevice">pingDevice</a></li>
2710
2711 <li data-name="LuCI.ui#showIndicator"><a href="LuCI.ui.html#showIndicator">showIndicator</a></li>
2712
2713 <li data-name="LuCI.ui#showModal"><a href="LuCI.ui.html#showModal">showModal</a></li>
2714
2715 <li data-name="LuCI.ui#uploadFile"><a href="LuCI.ui.html#uploadFile">uploadFile</a></li>
2716
2717 </ul>
2718 <ul class="events itemMembers">
2719
2720 </ul>
2721 </li>
2722
2723 <li class="item" data-name="LuCI.ui.AbstractElement">
2724 <span class="title">
2725 <a href="LuCI.ui.AbstractElement.html">LuCI.ui.AbstractElement</a>
2726
2727 </span>
2728 <ul class="members itemMembers">
2729
2730 </ul>
2731 <ul class="typedefs itemMembers">
2732
2733 <span class="subtitle">Typedefs</span>
2734
2735 <li data-name="LuCI.ui.AbstractElement.InitOptions"><a href="LuCI.ui.AbstractElement.html#.InitOptions">InitOptions</a></li>
2736
2737 </ul>
2738 <ul class="typedefs itemMembers">
2739
2740 </ul>
2741 <ul class="methods itemMembers">
2742
2743 <span class="subtitle">Methods</span>
2744
2745 <li data-name="LuCI.ui.AbstractElement#getValue"><a href="LuCI.ui.AbstractElement.html#getValue">getValue</a></li>
2746
2747 <li data-name="LuCI.ui.AbstractElement#isChanged"><a href="LuCI.ui.AbstractElement.html#isChanged">isChanged</a></li>
2748
2749 <li data-name="LuCI.ui.AbstractElement#isValid"><a href="LuCI.ui.AbstractElement.html#isValid">isValid</a></li>
2750
2751 <li data-name="LuCI.ui.AbstractElement#registerEvents"><a href="LuCI.ui.AbstractElement.html#registerEvents">registerEvents</a></li>
2752
2753 <li data-name="LuCI.ui.AbstractElement#render"><a href="LuCI.ui.AbstractElement.html#render">render</a></li>
2754
2755 <li data-name="LuCI.ui.AbstractElement#setChangeEvents"><a href="LuCI.ui.AbstractElement.html#setChangeEvents">setChangeEvents</a></li>
2756
2757 <li data-name="LuCI.ui.AbstractElement#setPlaceholder"><a href="LuCI.ui.AbstractElement.html#setPlaceholder">setPlaceholder</a></li>
2758
2759 <li data-name="LuCI.ui.AbstractElement#setUpdateEvents"><a href="LuCI.ui.AbstractElement.html#setUpdateEvents">setUpdateEvents</a></li>
2760
2761 <li data-name="LuCI.ui.AbstractElement#setValue"><a href="LuCI.ui.AbstractElement.html#setValue">setValue</a></li>
2762
2763 <li data-name="LuCI.ui.AbstractElement#triggerValidation"><a href="LuCI.ui.AbstractElement.html#triggerValidation">triggerValidation</a></li>
2764
2765 </ul>
2766 <ul class="events itemMembers">
2767
2768 </ul>
2769 </li>
2770
2771 <li class="item" data-name="LuCI.ui.changes">
2772 <span class="title">
2773 <a href="LuCI.ui.changes.html">LuCI.ui.changes</a>
2774
2775 </span>
2776 <ul class="members itemMembers">
2777
2778 </ul>
2779 <ul class="typedefs itemMembers">
2780
2781 </ul>
2782 <ul class="typedefs itemMembers">
2783
2784 </ul>
2785 <ul class="methods itemMembers">
2786
2787 <span class="subtitle">Methods</span>
2788
2789 <li data-name="LuCI.ui.changes#apply"><a href="LuCI.ui.changes.html#apply">apply</a></li>
2790
2791 <li data-name="LuCI.ui.changes#displayChanges"><a href="LuCI.ui.changes.html#displayChanges">displayChanges</a></li>
2792
2793 <li data-name="LuCI.ui.changes#renderChangeIndicator"><a href="LuCI.ui.changes.html#renderChangeIndicator">renderChangeIndicator</a></li>
2794
2795 <li data-name="LuCI.ui.changes#revert"><a href="LuCI.ui.changes.html#revert">revert</a></li>
2796
2797 <li data-name="LuCI.ui.changes#setIndicator"><a href="LuCI.ui.changes.html#setIndicator">setIndicator</a></li>
2798
2799 </ul>
2800 <ul class="events itemMembers">
2801
2802 </ul>
2803 </li>
2804
2805 <li class="item" data-name="LuCI.ui.Checkbox">
2806 <span class="title">
2807 <a href="LuCI.ui.Checkbox.html">LuCI.ui.Checkbox</a>
2808
2809 </span>
2810 <ul class="members itemMembers">
2811
2812 </ul>
2813 <ul class="typedefs itemMembers">
2814
2815 <span class="subtitle">Typedefs</span>
2816
2817 <li data-name="LuCI.ui.Checkbox.InitOptions"><a href="LuCI.ui.Checkbox.html#.InitOptions">InitOptions</a></li>
2818
2819 </ul>
2820 <ul class="typedefs itemMembers">
2821
2822 </ul>
2823 <ul class="methods itemMembers">
2824
2825 <span class="subtitle">Methods</span>
2826
2827 <li data-name="LuCI.ui.Checkbox#getValue"><a href="LuCI.ui.Checkbox.html#getValue">getValue</a></li>
2828
2829 <li data-name="LuCI.ui.Checkbox#isChanged"><a href="LuCI.ui.Checkbox.html#isChanged">isChanged</a></li>
2830
2831 <li data-name="LuCI.ui.Checkbox#isChecked"><a href="LuCI.ui.Checkbox.html#isChecked">isChecked</a></li>
2832
2833 <li data-name="LuCI.ui.Checkbox#isValid"><a href="LuCI.ui.Checkbox.html#isValid">isValid</a></li>
2834
2835 <li data-name="LuCI.ui.Checkbox#registerEvents"><a href="LuCI.ui.Checkbox.html#registerEvents">registerEvents</a></li>
2836
2837 <li data-name="LuCI.ui.Checkbox#render"><a href="LuCI.ui.Checkbox.html#render">render</a></li>
2838
2839 <li data-name="LuCI.ui.Checkbox#setChangeEvents"><a href="LuCI.ui.Checkbox.html#setChangeEvents">setChangeEvents</a></li>
2840
2841 <li data-name="LuCI.ui.Checkbox#setPlaceholder"><a href="LuCI.ui.Checkbox.html#setPlaceholder">setPlaceholder</a></li>
2842
2843 <li data-name="LuCI.ui.Checkbox#setUpdateEvents"><a href="LuCI.ui.Checkbox.html#setUpdateEvents">setUpdateEvents</a></li>
2844
2845 <li data-name="LuCI.ui.Checkbox#setValue"><a href="LuCI.ui.Checkbox.html#setValue">setValue</a></li>
2846
2847 <li data-name="LuCI.ui.Checkbox#triggerValidation"><a href="LuCI.ui.Checkbox.html#triggerValidation">triggerValidation</a></li>
2848
2849 </ul>
2850 <ul class="events itemMembers">
2851
2852 </ul>
2853 </li>
2854
2855 <li class="item" data-name="LuCI.ui.Combobox">
2856 <span class="title">
2857 <a href="LuCI.ui.Combobox.html">LuCI.ui.Combobox</a>
2858
2859 </span>
2860 <ul class="members itemMembers">
2861
2862 </ul>
2863 <ul class="typedefs itemMembers">
2864
2865 <span class="subtitle">Typedefs</span>
2866
2867 <li data-name="LuCI.ui.Combobox.InitOptions"><a href="LuCI.ui.Combobox.html#.InitOptions">InitOptions</a></li>
2868
2869 </ul>
2870 <ul class="typedefs itemMembers">
2871
2872 </ul>
2873 <ul class="methods itemMembers">
2874
2875 <span class="subtitle">Methods</span>
2876
2877 <li data-name="LuCI.ui.Combobox#addChoices"><a href="LuCI.ui.Combobox.html#addChoices">addChoices</a></li>
2878
2879 <li data-name="LuCI.ui.Combobox#clearChoices"><a href="LuCI.ui.Combobox.html#clearChoices">clearChoices</a></li>
2880
2881 <li data-name="LuCI.ui.Combobox#closeAllDropdowns"><a href="LuCI.ui.Combobox.html#closeAllDropdowns">closeAllDropdowns</a></li>
2882
2883 <li data-name="LuCI.ui.Combobox#isChanged"><a href="LuCI.ui.Combobox.html#isChanged">isChanged</a></li>
2884
2885 <li data-name="LuCI.ui.Combobox#isValid"><a href="LuCI.ui.Combobox.html#isValid">isValid</a></li>
2886
2887 <li data-name="LuCI.ui.Combobox#registerEvents"><a href="LuCI.ui.Combobox.html#registerEvents">registerEvents</a></li>
2888
2889 <li data-name="LuCI.ui.Combobox#setChangeEvents"><a href="LuCI.ui.Combobox.html#setChangeEvents">setChangeEvents</a></li>
2890
2891 <li data-name="LuCI.ui.Combobox#setPlaceholder"><a href="LuCI.ui.Combobox.html#setPlaceholder">setPlaceholder</a></li>
2892
2893 <li data-name="LuCI.ui.Combobox#setUpdateEvents"><a href="LuCI.ui.Combobox.html#setUpdateEvents">setUpdateEvents</a></li>
2894
2895 <li data-name="LuCI.ui.Combobox#triggerValidation"><a href="LuCI.ui.Combobox.html#triggerValidation">triggerValidation</a></li>
2896
2897 </ul>
2898 <ul class="events itemMembers">
2899
2900 </ul>
2901 </li>
2902
2903 <li class="item" data-name="LuCI.ui.ComboButton">
2904 <span class="title">
2905 <a href="LuCI.ui.ComboButton.html">LuCI.ui.ComboButton</a>
2906
2907 </span>
2908 <ul class="members itemMembers">
2909
2910 </ul>
2911 <ul class="typedefs itemMembers">
2912
2913 <span class="subtitle">Typedefs</span>
2914
2915 <li data-name="LuCI.ui.ComboButton.InitOptions"><a href="LuCI.ui.ComboButton.html#.InitOptions">InitOptions</a></li>
2916
2917 </ul>
2918 <ul class="typedefs itemMembers">
2919
2920 </ul>
2921 <ul class="methods itemMembers">
2922
2923 <span class="subtitle">Methods</span>
2924
2925 <li data-name="LuCI.ui.ComboButton#addChoices"><a href="LuCI.ui.ComboButton.html#addChoices">addChoices</a></li>
2926
2927 <li data-name="LuCI.ui.ComboButton#clearChoices"><a href="LuCI.ui.ComboButton.html#clearChoices">clearChoices</a></li>
2928
2929 <li data-name="LuCI.ui.ComboButton#closeAllDropdowns"><a href="LuCI.ui.ComboButton.html#closeAllDropdowns">closeAllDropdowns</a></li>
2930
2931 <li data-name="LuCI.ui.ComboButton#isChanged"><a href="LuCI.ui.ComboButton.html#isChanged">isChanged</a></li>
2932
2933 <li data-name="LuCI.ui.ComboButton#isValid"><a href="LuCI.ui.ComboButton.html#isValid">isValid</a></li>
2934
2935 <li data-name="LuCI.ui.ComboButton#registerEvents"><a href="LuCI.ui.ComboButton.html#registerEvents">registerEvents</a></li>
2936
2937 <li data-name="LuCI.ui.ComboButton#setChangeEvents"><a href="LuCI.ui.ComboButton.html#setChangeEvents">setChangeEvents</a></li>
2938
2939 <li data-name="LuCI.ui.ComboButton#setPlaceholder"><a href="LuCI.ui.ComboButton.html#setPlaceholder">setPlaceholder</a></li>
2940
2941 <li data-name="LuCI.ui.ComboButton#setUpdateEvents"><a href="LuCI.ui.ComboButton.html#setUpdateEvents">setUpdateEvents</a></li>
2942
2943 <li data-name="LuCI.ui.ComboButton#triggerValidation"><a href="LuCI.ui.ComboButton.html#triggerValidation">triggerValidation</a></li>
2944
2945 </ul>
2946 <ul class="events itemMembers">
2947
2948 </ul>
2949 </li>
2950
2951 <li class="item" data-name="LuCI.ui.Dropdown">
2952 <span class="title">
2953 <a href="LuCI.ui.Dropdown.html">LuCI.ui.Dropdown</a>
2954
2955 </span>
2956 <ul class="members itemMembers">
2957
2958 </ul>
2959 <ul class="typedefs itemMembers">
2960
2961 <span class="subtitle">Typedefs</span>
2962
2963 <li data-name="LuCI.ui.Dropdown.InitOptions"><a href="LuCI.ui.Dropdown.html#.InitOptions">InitOptions</a></li>
2964
2965 </ul>
2966 <ul class="typedefs itemMembers">
2967
2968 </ul>
2969 <ul class="methods itemMembers">
2970
2971 <span class="subtitle">Methods</span>
2972
2973 <li data-name="LuCI.ui.Dropdown#addChoices"><a href="LuCI.ui.Dropdown.html#addChoices">addChoices</a></li>
2974
2975 <li data-name="LuCI.ui.Dropdown#clearChoices"><a href="LuCI.ui.Dropdown.html#clearChoices">clearChoices</a></li>
2976
2977 <li data-name="LuCI.ui.Dropdown#closeAllDropdowns"><a href="LuCI.ui.Dropdown.html#closeAllDropdowns">closeAllDropdowns</a></li>
2978
2979 <li data-name="LuCI.ui.Dropdown#getValue"><a href="LuCI.ui.Dropdown.html#getValue">getValue</a></li>
2980
2981 <li data-name="LuCI.ui.Dropdown#isChanged"><a href="LuCI.ui.Dropdown.html#isChanged">isChanged</a></li>
2982
2983 <li data-name="LuCI.ui.Dropdown#isValid"><a href="LuCI.ui.Dropdown.html#isValid">isValid</a></li>
2984
2985 <li data-name="LuCI.ui.Dropdown#registerEvents"><a href="LuCI.ui.Dropdown.html#registerEvents">registerEvents</a></li>
2986
2987 <li data-name="LuCI.ui.Dropdown#render"><a href="LuCI.ui.Dropdown.html#render">render</a></li>
2988
2989 <li data-name="LuCI.ui.Dropdown#setChangeEvents"><a href="LuCI.ui.Dropdown.html#setChangeEvents">setChangeEvents</a></li>
2990
2991 <li data-name="LuCI.ui.Dropdown#setPlaceholder"><a href="LuCI.ui.Dropdown.html#setPlaceholder">setPlaceholder</a></li>
2992
2993 <li data-name="LuCI.ui.Dropdown#setUpdateEvents"><a href="LuCI.ui.Dropdown.html#setUpdateEvents">setUpdateEvents</a></li>
2994
2995 <li data-name="LuCI.ui.Dropdown#setValue"><a href="LuCI.ui.Dropdown.html#setValue">setValue</a></li>
2996
2997 <li data-name="LuCI.ui.Dropdown#triggerValidation"><a href="LuCI.ui.Dropdown.html#triggerValidation">triggerValidation</a></li>
2998
2999 </ul>
3000 <ul class="events itemMembers">
3001
3002 </ul>
3003 </li>
3004
3005 <li class="item" data-name="LuCI.ui.DynamicList">
3006 <span class="title">
3007 <a href="LuCI.ui.DynamicList.html">LuCI.ui.DynamicList</a>
3008
3009 </span>
3010 <ul class="members itemMembers">
3011
3012 </ul>
3013 <ul class="typedefs itemMembers">
3014
3015 <span class="subtitle">Typedefs</span>
3016
3017 <li data-name="LuCI.ui.DynamicList.InitOptions"><a href="LuCI.ui.DynamicList.html#.InitOptions">InitOptions</a></li>
3018
3019 </ul>
3020 <ul class="typedefs itemMembers">
3021
3022 </ul>
3023 <ul class="methods itemMembers">
3024
3025 <span class="subtitle">Methods</span>
3026
3027 <li data-name="LuCI.ui.DynamicList#addChoices"><a href="LuCI.ui.DynamicList.html#addChoices">addChoices</a></li>
3028
3029 <li data-name="LuCI.ui.DynamicList#clearChoices"><a href="LuCI.ui.DynamicList.html#clearChoices">clearChoices</a></li>
3030
3031 <li data-name="LuCI.ui.DynamicList#getValue"><a href="LuCI.ui.DynamicList.html#getValue">getValue</a></li>
3032
3033 <li data-name="LuCI.ui.DynamicList#isChanged"><a href="LuCI.ui.DynamicList.html#isChanged">isChanged</a></li>
3034
3035 <li data-name="LuCI.ui.DynamicList#isValid"><a href="LuCI.ui.DynamicList.html#isValid">isValid</a></li>
3036
3037 <li data-name="LuCI.ui.DynamicList#registerEvents"><a href="LuCI.ui.DynamicList.html#registerEvents">registerEvents</a></li>
3038
3039 <li data-name="LuCI.ui.DynamicList#render"><a href="LuCI.ui.DynamicList.html#render">render</a></li>
3040
3041 <li data-name="LuCI.ui.DynamicList#setChangeEvents"><a href="LuCI.ui.DynamicList.html#setChangeEvents">setChangeEvents</a></li>
3042
3043 <li data-name="LuCI.ui.DynamicList#setPlaceholder"><a href="LuCI.ui.DynamicList.html#setPlaceholder">setPlaceholder</a></li>
3044
3045 <li data-name="LuCI.ui.DynamicList#setUpdateEvents"><a href="LuCI.ui.DynamicList.html#setUpdateEvents">setUpdateEvents</a></li>
3046
3047 <li data-name="LuCI.ui.DynamicList#setValue"><a href="LuCI.ui.DynamicList.html#setValue">setValue</a></li>
3048
3049 <li data-name="LuCI.ui.DynamicList#triggerValidation"><a href="LuCI.ui.DynamicList.html#triggerValidation">triggerValidation</a></li>
3050
3051 </ul>
3052 <ul class="events itemMembers">
3053
3054 </ul>
3055 </li>
3056
3057 <li class="item" data-name="LuCI.ui.FileUpload">
3058 <span class="title">
3059 <a href="LuCI.ui.FileUpload.html">LuCI.ui.FileUpload</a>
3060
3061 </span>
3062 <ul class="members itemMembers">
3063
3064 </ul>
3065 <ul class="typedefs itemMembers">
3066
3067 <span class="subtitle">Typedefs</span>
3068
3069 <li data-name="LuCI.ui.FileUpload.InitOptions"><a href="LuCI.ui.FileUpload.html#.InitOptions">InitOptions</a></li>
3070
3071 </ul>
3072 <ul class="typedefs itemMembers">
3073
3074 </ul>
3075 <ul class="methods itemMembers">
3076
3077 <span class="subtitle">Methods</span>
3078
3079 <li data-name="LuCI.ui.FileUpload#getValue"><a href="LuCI.ui.FileUpload.html#getValue">getValue</a></li>
3080
3081 <li data-name="LuCI.ui.FileUpload#isChanged"><a href="LuCI.ui.FileUpload.html#isChanged">isChanged</a></li>
3082
3083 <li data-name="LuCI.ui.FileUpload#isValid"><a href="LuCI.ui.FileUpload.html#isValid">isValid</a></li>
3084
3085 <li data-name="LuCI.ui.FileUpload#registerEvents"><a href="LuCI.ui.FileUpload.html#registerEvents">registerEvents</a></li>
3086
3087 <li data-name="LuCI.ui.FileUpload#render"><a href="LuCI.ui.FileUpload.html#render">render</a></li>
3088
3089 <li data-name="LuCI.ui.FileUpload#setChangeEvents"><a href="LuCI.ui.FileUpload.html#setChangeEvents">setChangeEvents</a></li>
3090
3091 <li data-name="LuCI.ui.FileUpload#setPlaceholder"><a href="LuCI.ui.FileUpload.html#setPlaceholder">setPlaceholder</a></li>
3092
3093 <li data-name="LuCI.ui.FileUpload#setUpdateEvents"><a href="LuCI.ui.FileUpload.html#setUpdateEvents">setUpdateEvents</a></li>
3094
3095 <li data-name="LuCI.ui.FileUpload#setValue"><a href="LuCI.ui.FileUpload.html#setValue">setValue</a></li>
3096
3097 <li data-name="LuCI.ui.FileUpload#triggerValidation"><a href="LuCI.ui.FileUpload.html#triggerValidation">triggerValidation</a></li>
3098
3099 </ul>
3100 <ul class="events itemMembers">
3101
3102 </ul>
3103 </li>
3104
3105 <li class="item" data-name="LuCI.ui.Hiddenfield">
3106 <span class="title">
3107 <a href="LuCI.ui.Hiddenfield.html">LuCI.ui.Hiddenfield</a>
3108
3109 </span>
3110 <ul class="members itemMembers">
3111
3112 </ul>
3113 <ul class="typedefs itemMembers">
3114
3115 </ul>
3116 <ul class="typedefs itemMembers">
3117
3118 </ul>
3119 <ul class="methods itemMembers">
3120
3121 <span class="subtitle">Methods</span>
3122
3123 <li data-name="LuCI.ui.Hiddenfield#getValue"><a href="LuCI.ui.Hiddenfield.html#getValue">getValue</a></li>
3124
3125 <li data-name="LuCI.ui.Hiddenfield#isChanged"><a href="LuCI.ui.Hiddenfield.html#isChanged">isChanged</a></li>
3126
3127 <li data-name="LuCI.ui.Hiddenfield#isValid"><a href="LuCI.ui.Hiddenfield.html#isValid">isValid</a></li>
3128
3129 <li data-name="LuCI.ui.Hiddenfield#registerEvents"><a href="LuCI.ui.Hiddenfield.html#registerEvents">registerEvents</a></li>
3130
3131 <li data-name="LuCI.ui.Hiddenfield#render"><a href="LuCI.ui.Hiddenfield.html#render">render</a></li>
3132
3133 <li data-name="LuCI.ui.Hiddenfield#setChangeEvents"><a href="LuCI.ui.Hiddenfield.html#setChangeEvents">setChangeEvents</a></li>
3134
3135 <li data-name="LuCI.ui.Hiddenfield#setPlaceholder"><a href="LuCI.ui.Hiddenfield.html#setPlaceholder">setPlaceholder</a></li>
3136
3137 <li data-name="LuCI.ui.Hiddenfield#setUpdateEvents"><a href="LuCI.ui.Hiddenfield.html#setUpdateEvents">setUpdateEvents</a></li>
3138
3139 <li data-name="LuCI.ui.Hiddenfield#setValue"><a href="LuCI.ui.Hiddenfield.html#setValue">setValue</a></li>
3140
3141 <li data-name="LuCI.ui.Hiddenfield#triggerValidation"><a href="LuCI.ui.Hiddenfield.html#triggerValidation">triggerValidation</a></li>
3142
3143 </ul>
3144 <ul class="events itemMembers">
3145
3146 </ul>
3147 </li>
3148
3149 <li class="item" data-name="LuCI.ui.menu">
3150 <span class="title">
3151 <a href="LuCI.ui.menu.html">LuCI.ui.menu</a>
3152
3153 </span>
3154 <ul class="members itemMembers">
3155
3156 </ul>
3157 <ul class="typedefs itemMembers">
3158
3159 <span class="subtitle">Typedefs</span>
3160
3161 <li data-name="LuCI.ui.menu.MenuNode"><a href="LuCI.ui.menu.html#.MenuNode">MenuNode</a></li>
3162
3163 </ul>
3164 <ul class="typedefs itemMembers">
3165
3166 </ul>
3167 <ul class="methods itemMembers">
3168
3169 <span class="subtitle">Methods</span>
3170
3171 <li data-name="LuCI.ui.menu#flushCache"><a href="LuCI.ui.menu.html#flushCache">flushCache</a></li>
3172
3173 <li data-name="LuCI.ui.menu#getChildren"><a href="LuCI.ui.menu.html#getChildren">getChildren</a></li>
3174
3175 <li data-name="LuCI.ui.menu#load"><a href="LuCI.ui.menu.html#load">load</a></li>
3176
3177 </ul>
3178 <ul class="events itemMembers">
3179
3180 </ul>
3181 </li>
3182
3183 <li class="item" data-name="LuCI.ui.Select">
3184 <span class="title">
3185 <a href="LuCI.ui.Select.html">LuCI.ui.Select</a>
3186
3187 </span>
3188 <ul class="members itemMembers">
3189
3190 </ul>
3191 <ul class="typedefs itemMembers">
3192
3193 <span class="subtitle">Typedefs</span>
3194
3195 <li data-name="LuCI.ui.Select.InitOptions"><a href="LuCI.ui.Select.html#.InitOptions">InitOptions</a></li>
3196
3197 </ul>
3198 <ul class="typedefs itemMembers">
3199
3200 </ul>
3201 <ul class="methods itemMembers">
3202
3203 <span class="subtitle">Methods</span>
3204
3205 <li data-name="LuCI.ui.Select#getValue"><a href="LuCI.ui.Select.html#getValue">getValue</a></li>
3206
3207 <li data-name="LuCI.ui.Select#isChanged"><a href="LuCI.ui.Select.html#isChanged">isChanged</a></li>
3208
3209 <li data-name="LuCI.ui.Select#isValid"><a href="LuCI.ui.Select.html#isValid">isValid</a></li>
3210
3211 <li data-name="LuCI.ui.Select#registerEvents"><a href="LuCI.ui.Select.html#registerEvents">registerEvents</a></li>
3212
3213 <li data-name="LuCI.ui.Select#render"><a href="LuCI.ui.Select.html#render">render</a></li>
3214
3215 <li data-name="LuCI.ui.Select#setChangeEvents"><a href="LuCI.ui.Select.html#setChangeEvents">setChangeEvents</a></li>
3216
3217 <li data-name="LuCI.ui.Select#setPlaceholder"><a href="LuCI.ui.Select.html#setPlaceholder">setPlaceholder</a></li>
3218
3219 <li data-name="LuCI.ui.Select#setUpdateEvents"><a href="LuCI.ui.Select.html#setUpdateEvents">setUpdateEvents</a></li>
3220
3221 <li data-name="LuCI.ui.Select#setValue"><a href="LuCI.ui.Select.html#setValue">setValue</a></li>
3222
3223 <li data-name="LuCI.ui.Select#triggerValidation"><a href="LuCI.ui.Select.html#triggerValidation">triggerValidation</a></li>
3224
3225 </ul>
3226 <ul class="events itemMembers">
3227
3228 </ul>
3229 </li>
3230
3231 <li class="item" data-name="LuCI.ui.tabs">
3232 <span class="title">
3233 <a href="LuCI.ui.tabs.html">LuCI.ui.tabs</a>
3234
3235 </span>
3236 <ul class="members itemMembers">
3237
3238 </ul>
3239 <ul class="typedefs itemMembers">
3240
3241 </ul>
3242 <ul class="typedefs itemMembers">
3243
3244 </ul>
3245 <ul class="methods itemMembers">
3246
3247 <span class="subtitle">Methods</span>
3248
3249 <li data-name="LuCI.ui.tabs#initTabGroup"><a href="LuCI.ui.tabs.html#initTabGroup">initTabGroup</a></li>
3250
3251 <li data-name="LuCI.ui.tabs#isEmptyPane"><a href="LuCI.ui.tabs.html#isEmptyPane">isEmptyPane</a></li>
3252
3253 </ul>
3254 <ul class="events itemMembers">
3255
3256 </ul>
3257 </li>
3258
3259 <li class="item" data-name="LuCI.ui.Textarea">
3260 <span class="title">
3261 <a href="LuCI.ui.Textarea.html">LuCI.ui.Textarea</a>
3262
3263 </span>
3264 <ul class="members itemMembers">
3265
3266 </ul>
3267 <ul class="typedefs itemMembers">
3268
3269 <span class="subtitle">Typedefs</span>
3270
3271 <li data-name="LuCI.ui.Textarea.InitOptions"><a href="LuCI.ui.Textarea.html#.InitOptions">InitOptions</a></li>
3272
3273 </ul>
3274 <ul class="typedefs itemMembers">
3275
3276 </ul>
3277 <ul class="methods itemMembers">
3278
3279 <span class="subtitle">Methods</span>
3280
3281 <li data-name="LuCI.ui.Textarea#getValue"><a href="LuCI.ui.Textarea.html#getValue">getValue</a></li>
3282
3283 <li data-name="LuCI.ui.Textarea#isChanged"><a href="LuCI.ui.Textarea.html#isChanged">isChanged</a></li>
3284
3285 <li data-name="LuCI.ui.Textarea#isValid"><a href="LuCI.ui.Textarea.html#isValid">isValid</a></li>
3286
3287 <li data-name="LuCI.ui.Textarea#registerEvents"><a href="LuCI.ui.Textarea.html#registerEvents">registerEvents</a></li>
3288
3289 <li data-name="LuCI.ui.Textarea#render"><a href="LuCI.ui.Textarea.html#render">render</a></li>
3290
3291 <li data-name="LuCI.ui.Textarea#setChangeEvents"><a href="LuCI.ui.Textarea.html#setChangeEvents">setChangeEvents</a></li>
3292
3293 <li data-name="LuCI.ui.Textarea#setPlaceholder"><a href="LuCI.ui.Textarea.html#setPlaceholder">setPlaceholder</a></li>
3294
3295 <li data-name="LuCI.ui.Textarea#setUpdateEvents"><a href="LuCI.ui.Textarea.html#setUpdateEvents">setUpdateEvents</a></li>
3296
3297 <li data-name="LuCI.ui.Textarea#setValue"><a href="LuCI.ui.Textarea.html#setValue">setValue</a></li>
3298
3299 <li data-name="LuCI.ui.Textarea#triggerValidation"><a href="LuCI.ui.Textarea.html#triggerValidation">triggerValidation</a></li>
3300
3301 </ul>
3302 <ul class="events itemMembers">
3303
3304 </ul>
3305 </li>
3306
3307 <li class="item" data-name="LuCI.ui.Textfield">
3308 <span class="title">
3309 <a href="LuCI.ui.Textfield.html">LuCI.ui.Textfield</a>
3310
3311 </span>
3312 <ul class="members itemMembers">
3313
3314 </ul>
3315 <ul class="typedefs itemMembers">
3316
3317 <span class="subtitle">Typedefs</span>
3318
3319 <li data-name="LuCI.ui.Textfield.InitOptions"><a href="LuCI.ui.Textfield.html#.InitOptions">InitOptions</a></li>
3320
3321 </ul>
3322 <ul class="typedefs itemMembers">
3323
3324 </ul>
3325 <ul class="methods itemMembers">
3326
3327 <span class="subtitle">Methods</span>
3328
3329 <li data-name="LuCI.ui.Textfield#getValue"><a href="LuCI.ui.Textfield.html#getValue">getValue</a></li>
3330
3331 <li data-name="LuCI.ui.Textfield#isChanged"><a href="LuCI.ui.Textfield.html#isChanged">isChanged</a></li>
3332
3333 <li data-name="LuCI.ui.Textfield#isValid"><a href="LuCI.ui.Textfield.html#isValid">isValid</a></li>
3334
3335 <li data-name="LuCI.ui.Textfield#registerEvents"><a href="LuCI.ui.Textfield.html#registerEvents">registerEvents</a></li>
3336
3337 <li data-name="LuCI.ui.Textfield#render"><a href="LuCI.ui.Textfield.html#render">render</a></li>
3338
3339 <li data-name="LuCI.ui.Textfield#setChangeEvents"><a href="LuCI.ui.Textfield.html#setChangeEvents">setChangeEvents</a></li>
3340
3341 <li data-name="LuCI.ui.Textfield#setPlaceholder"><a href="LuCI.ui.Textfield.html#setPlaceholder">setPlaceholder</a></li>
3342
3343 <li data-name="LuCI.ui.Textfield#setUpdateEvents"><a href="LuCI.ui.Textfield.html#setUpdateEvents">setUpdateEvents</a></li>
3344
3345 <li data-name="LuCI.ui.Textfield#setValue"><a href="LuCI.ui.Textfield.html#setValue">setValue</a></li>
3346
3347 <li data-name="LuCI.ui.Textfield#triggerValidation"><a href="LuCI.ui.Textfield.html#triggerValidation">triggerValidation</a></li>
3348
3349 </ul>
3350 <ul class="events itemMembers">
3351
3352 </ul>
3353 </li>
3354
3355 <li class="item" data-name="LuCI.view">
3356 <span class="title">
3357 <a href="LuCI.view.html">LuCI.view</a>
3358
3359 </span>
3360 <ul class="members itemMembers">
3361
3362 </ul>
3363 <ul class="typedefs itemMembers">
3364
3365 </ul>
3366 <ul class="typedefs itemMembers">
3367
3368 </ul>
3369 <ul class="methods itemMembers">
3370
3371 <span class="subtitle">Methods</span>
3372
3373 <li data-name="LuCI.view#addFooter"><a href="LuCI.view.html#addFooter">addFooter</a></li>
3374
3375 <li data-name="LuCI.view#handleReset"><a href="LuCI.view.html#handleReset">handleReset</a></li>
3376
3377 <li data-name="LuCI.view#handleSave"><a href="LuCI.view.html#handleSave">handleSave</a></li>
3378
3379 <li data-name="LuCI.view#handleSaveApply"><a href="LuCI.view.html#handleSaveApply">handleSaveApply</a></li>
3380
3381 <li data-name="LuCI.view#load"><a href="LuCI.view.html#load">load</a></li>
3382
3383 <li data-name="LuCI.view#render"><a href="LuCI.view.html#render">render</a></li>
3384
3385 </ul>
3386 <ul class="events itemMembers">
3387
3388 </ul>
3389 </li>
3390
3391 <li class="item" data-name="LuCI.xhr">
3392 <span class="title">
3393 <a href="LuCI.xhr.html">LuCI.xhr</a>
3394
3395 </span>
3396 <ul class="members itemMembers">
3397
3398 </ul>
3399 <ul class="typedefs itemMembers">
3400
3401 </ul>
3402 <ul class="typedefs itemMembers">
3403
3404 </ul>
3405 <ul class="methods itemMembers">
3406
3407 <span class="subtitle">Methods</span>
3408
3409 <li data-name="LuCI.xhr#abort"><a href="LuCI.xhr.html#abort">abort</a></li>
3410
3411 <li data-name="LuCI.xhr#busy"><a href="LuCI.xhr.html#busy">busy</a></li>
3412
3413 <li data-name="LuCI.xhr#cancel"><a href="LuCI.xhr.html#cancel">cancel</a></li>
3414
3415 <li data-name="LuCI.xhr#get"><a href="LuCI.xhr.html#get">get</a></li>
3416
3417 <li data-name="LuCI.xhr#post"><a href="LuCI.xhr.html#post">post</a></li>
3418
3419 <li data-name="LuCI.xhr#send_form"><a href="LuCI.xhr.html#send_form">send_form</a></li>
3420
3421 </ul>
3422 <ul class="events itemMembers">
3423
3424 </ul>
3425 </li>
3426
3427 </ul>
3428 </div>
3429 <div class="main">
3430 <h1 class="page-title" data-filename="form.js.html">Source: form.js</h1>
3431
3432
3433
3434
3435 <section>
3436 <article>
3437 <pre id="source-code" class="prettyprint source "><code>'use strict';
3438 'require ui';
3439 'require uci';
3440 'require rpc';
3441 'require dom';
3442 'require baseclass';
3443
3444 var scope = this;
3445
3446 var callSessionAccess = rpc.declare({
3447 object: 'session',
3448 method: 'access',
3449 params: [ 'scope', 'object', 'function' ],
3450 expect: { 'access': false }
3451 });
3452
3453 var CBIJSONConfig = baseclass.extend({
3454 __init__: function(data) {
3455 data = Object.assign({}, data);
3456
3457 this.data = {};
3458
3459 var num_sections = 0,
3460 section_ids = [];
3461
3462 for (var sectiontype in data) {
3463 if (!data.hasOwnProperty(sectiontype))
3464 continue;
3465
3466 if (Array.isArray(data[sectiontype])) {
3467 for (var i = 0, index = 0; i &lt; data[sectiontype].length; i++) {
3468 var item = data[sectiontype][i],
3469 anonymous, name;
3470
3471 if (!L.isObject(item))
3472 continue;
3473
3474 if (typeof(item['.name']) == 'string') {
3475 name = item['.name'];
3476 anonymous = false;
3477 }
3478 else {
3479 name = sectiontype + num_sections;
3480 anonymous = true;
3481 }
3482
3483 if (!this.data.hasOwnProperty(name))
3484 section_ids.push(name);
3485
3486 this.data[name] = Object.assign(item, {
3487 '.index': num_sections++,
3488 '.anonymous': anonymous,
3489 '.name': name,
3490 '.type': sectiontype
3491 });
3492 }
3493 }
3494 else if (L.isObject(data[sectiontype])) {
3495 this.data[sectiontype] = Object.assign(data[sectiontype], {
3496 '.anonymous': false,
3497 '.name': sectiontype,
3498 '.type': sectiontype
3499 });
3500
3501 section_ids.push(sectiontype);
3502 num_sections++;
3503 }
3504 }
3505
3506 section_ids.sort(L.bind(function(a, b) {
3507 var indexA = (this.data[a]['.index'] != null) ? +this.data[a]['.index'] : 9999,
3508 indexB = (this.data[b]['.index'] != null) ? +this.data[b]['.index'] : 9999;
3509
3510 if (indexA != indexB)
3511 return (indexA - indexB);
3512
3513 return (a > b);
3514 }, this));
3515
3516 for (var i = 0; i &lt; section_ids.length; i++)
3517 this.data[section_ids[i]]['.index'] = i;
3518 },
3519
3520 load: function() {
3521 return Promise.resolve(this.data);
3522 },
3523
3524 save: function() {
3525 return Promise.resolve();
3526 },
3527
3528 get: function(config, section, option) {
3529 if (section == null)
3530 return null;
3531
3532 if (option == null)
3533 return this.data[section];
3534
3535 if (!this.data.hasOwnProperty(section))
3536 return null;
3537
3538 var value = this.data[section][option];
3539
3540 if (Array.isArray(value))
3541 return value;
3542
3543 if (value != null)
3544 return String(value);
3545
3546 return null;
3547 },
3548
3549 set: function(config, section, option, value) {
3550 if (section == null || option == null || option.charAt(0) == '.')
3551 return;
3552
3553 if (!this.data.hasOwnProperty(section))
3554 return;
3555
3556 if (value == null)
3557 delete this.data[section][option];
3558 else if (Array.isArray(value))
3559 this.data[section][option] = value;
3560 else
3561 this.data[section][option] = String(value);
3562 },
3563
3564 unset: function(config, section, option) {
3565 return this.set(config, section, option, null);
3566 },
3567
3568 sections: function(config, sectiontype, callback) {
3569 var rv = [];
3570
3571 for (var section_id in this.data)
3572 if (sectiontype == null || this.data[section_id]['.type'] == sectiontype)
3573 rv.push(this.data[section_id]);
3574
3575 rv.sort(function(a, b) { return a['.index'] - b['.index'] });
3576
3577 if (typeof(callback) == 'function')
3578 for (var i = 0; i &lt; rv.length; i++)
3579 callback.call(this, rv[i], rv[i]['.name']);
3580
3581 return rv;
3582 },
3583
3584 add: function(config, sectiontype, sectionname) {
3585 var num_sections_type = 0, next_index = 0;
3586
3587 for (var name in this.data) {
3588 num_sections_type += (this.data[name]['.type'] == sectiontype);
3589 next_index = Math.max(next_index, this.data[name]['.index']);
3590 }
3591
3592 var section_id = sectionname || sectiontype + num_sections_type;
3593
3594 if (!this.data.hasOwnProperty(section_id)) {
3595 this.data[section_id] = {
3596 '.name': section_id,
3597 '.type': sectiontype,
3598 '.anonymous': (sectionname == null),
3599 '.index': next_index + 1
3600 };
3601 }
3602
3603 return section_id;
3604 },
3605
3606 remove: function(config, section) {
3607 if (this.data.hasOwnProperty(section))
3608 delete this.data[section];
3609 },
3610
3611 resolveSID: function(config, section_id) {
3612 return section_id;
3613 },
3614
3615 move: function(config, section_id1, section_id2, after) {
3616 return uci.move.apply(this, [config, section_id1, section_id2, after]);
3617 }
3618 });
3619
3620 /**
3621 * @class AbstractElement
3622 * @memberof LuCI.form
3623 * @hideconstructor
3624 * @classdesc
3625 *
3626 * The `AbstractElement` class serves as abstract base for the different form
3627 * elements implemented by `LuCI.form`. It provides the common logic for
3628 * loading and rendering values, for nesting elements and for defining common
3629 * properties.
3630 *
3631 * This class is private and not directly accessible by user code.
3632 */
3633 var CBIAbstractElement = baseclass.extend(/** @lends LuCI.form.AbstractElement.prototype */ {
3634 __init__: function(title, description) {
3635 this.title = title || '';
3636 this.description = description || '';
3637 this.children = [];
3638 },
3639
3640 /**
3641 * Add another form element as children to this element.
3642 *
3643 * @param {AbstractElement} element
3644 * The form element to add.
3645 */
3646 append: function(obj) {
3647 this.children.push(obj);
3648 },
3649
3650 /**
3651 * Parse this elements form input.
3652 *
3653 * The `parse()` function recursively walks the form element tree and
3654 * triggers input value reading and validation for each encountered element.
3655 *
3656 * Elements which are hidden due to unsatisified dependencies are skipped.
3657 *
3658 * @returns {Promise&lt;void>}
3659 * Returns a promise resolving once this element's value and the values of
3660 * all child elements have been parsed. The returned promise is rejected
3661 * if any parsed values are not meeting the validation constraints of their
3662 * respective elements.
3663 */
3664 parse: function() {
3665 var args = arguments;
3666 this.children.forEach(function(child) {
3667 child.parse.apply(child, args);
3668 });
3669 },
3670
3671 /**
3672 * Render the form element.
3673 *
3674 * The `render()` function recursively walks the form element tree and
3675 * renders the markup for each element, returning the assembled DOM tree.
3676 *
3677 * @abstract
3678 * @returns {Node|Promise&lt;Node>}
3679 * May return a DOM Node or a promise resolving to a DOM node containing
3680 * the form element's markup, including the markup of any child elements.
3681 */
3682 render: function() {
3683 L.error('InternalError', 'Not implemented');
3684 },
3685
3686 /** @private */
3687 loadChildren: function(/* ... */) {
3688 var tasks = [];
3689
3690 if (Array.isArray(this.children))
3691 for (var i = 0; i &lt; this.children.length; i++)
3692 if (!this.children[i].disable)
3693 tasks.push(this.children[i].load.apply(this.children[i], arguments));
3694
3695 return Promise.all(tasks);
3696 },
3697
3698 /** @private */
3699 renderChildren: function(tab_name /*, ... */) {
3700 var tasks = [],
3701 index = 0;
3702
3703 if (Array.isArray(this.children))
3704 for (var i = 0; i &lt; this.children.length; i++)
3705 if (tab_name === null || this.children[i].tab === tab_name)
3706 if (!this.children[i].disable)
3707 tasks.push(this.children[i].render.apply(
3708 this.children[i], this.varargs(arguments, 1, index++)));
3709
3710 return Promise.all(tasks);
3711 },
3712
3713 /**
3714 * Strip any HTML tags from the given input string.
3715 *
3716 * @param {string} input
3717 * The input string to clean.
3718 *
3719 * @returns {string}
3720 * The cleaned input string with HTML removes removed.
3721 */
3722 stripTags: function(s) {
3723 if (typeof(s) == 'string' &amp;&amp; !s.match(/[&lt;>]/))
3724 return s;
3725
3726 var x = E('div', {}, s);
3727 return x.textContent || x.innerText || '';
3728 },
3729
3730 /**
3731 * Format the given named property as title string.
3732 *
3733 * This function looks up the given named property and formats its value
3734 * suitable for use as element caption or description string. It also
3735 * strips any HTML tags from the result.
3736 *
3737 * If the property value is a string, it is passed to `String.format()`
3738 * along with any additional parameters passed to `titleFn()`.
3739 *
3740 * If the property value is a function, it is invoked with any additional
3741 * `titleFn()` parameters as arguments and the obtained return value is
3742 * converted to a string.
3743 *
3744 * In all other cases, `null` is returned.
3745 *
3746 * @param {string} property
3747 * The name of the element property to use.
3748 *
3749 * @param {...*} fmt_args
3750 * Extra values to format the title string with.
3751 *
3752 * @returns {string|null}
3753 * The formatted title string or `null` if the property did not exist or
3754 * was neither a string nor a function.
3755 */
3756 titleFn: function(attr /*, ... */) {
3757 var s = null;
3758
3759 if (typeof(this[attr]) == 'function')
3760 s = this[attr].apply(this, this.varargs(arguments, 1));
3761 else if (typeof(this[attr]) == 'string')
3762 s = (arguments.length > 1) ? ''.format.apply(this[attr], this.varargs(arguments, 1)) : this[attr];
3763
3764 if (s != null)
3765 s = this.stripTags(String(s)).trim();
3766
3767 if (s == null || s == '')
3768 return null;
3769
3770 return s;
3771 }
3772 });
3773
3774 /**
3775 * @constructor Map
3776 * @memberof LuCI.form
3777 * @augments LuCI.form.AbstractElement
3778 *
3779 * @classdesc
3780 *
3781 * The `Map` class represents one complete form. A form usually maps one UCI
3782 * configuraton file and is divided into multiple sections containing multiple
3783 * fields each.
3784 *
3785 * It serves as main entry point into the `LuCI.form` for typical view code.
3786 *
3787 * @param {string} config
3788 * The UCI configuration to map. It is automatically loaded along when the
3789 * resulting map instance.
3790 *
3791 * @param {string} [title]
3792 * The title caption of the form. A form title is usually rendered as separate
3793 * headline element before the actual form contents. If omitted, the
3794 * corresponding headline element will not be rendered.
3795 *
3796 * @param {string} [description]
3797 * The description text of the form which is usually rendered as text
3798 * paragraph below the form title and before the actual form conents.
3799 * If omitted, the corresponding paragraph element will not be rendered.
3800 */
3801 var CBIMap = CBIAbstractElement.extend(/** @lends LuCI.form.Map.prototype */ {
3802 __init__: function(config /*, ... */) {
3803 this.super('__init__', this.varargs(arguments, 1));
3804
3805 this.config = config;
3806 this.parsechain = [ config ];
3807 this.data = uci;
3808 },
3809
3810 /**
3811 * Toggle readonly state of the form.
3812 *
3813 * If set to `true`, the Map instance is marked readonly and any form
3814 * option elements added to it will inherit the readonly state.
3815 *
3816 * If left unset, the Map will test the access permission of the primary
3817 * uci configuration upon loading and mark the form readonly if no write
3818 * permissions are granted.
3819 *
3820 * @name LuCI.form.Map.prototype#readonly
3821 * @type boolean
3822 */
3823
3824 /**
3825 * Find all DOM nodes within this Map which match the given search
3826 * parameters. This function is essentially a convenience wrapper around
3827 * `querySelectorAll()`.
3828 *
3829 * This function is sensitive to the amount of arguments passed to it;
3830 * if only one argument is specified, it is used as selector-expression
3831 * as-is. When two arguments are passed, the first argument is treated
3832 * as attribute name, the second one as attribute value to match.
3833 *
3834 * As an example, `map.findElements('input')` would find all `&lt;input>`
3835 * nodes while `map.findElements('type', 'text')` would find any DOM node
3836 * with a `type="text"` attribute.
3837 *
3838 * @param {string} selector_or_attrname
3839 * If invoked with only one parameter, this argument is a
3840 * `querySelectorAll()` compatible selector expression. If invoked with
3841 * two parameters, this argument is the attribute name to filter for.
3842 *
3843 * @param {string} [attrvalue]
3844 * In case the function is invoked with two parameters, this argument
3845 * specifies the attribute value to match.
3846 *
3847 * @throws {InternalError}
3848 * Throws an `InternalError` if more than two function parameters are
3849 * passed.
3850 *
3851 * @returns {NodeList}
3852 * Returns a (possibly empty) DOM `NodeList` containing the found DOM nodes.
3853 */
3854 findElements: function(/* ... */) {
3855 var q = null;
3856
3857 if (arguments.length == 1)
3858 q = arguments[0];
3859 else if (arguments.length == 2)
3860 q = '[%s="%s"]'.format(arguments[0], arguments[1]);
3861 else
3862 L.error('InternalError', 'Expecting one or two arguments to findElements()');
3863
3864 return this.root.querySelectorAll(q);
3865 },
3866
3867 /**
3868 * Find the first DOM node within this Map which matches the given search
3869 * parameters. This function is essentially a convenience wrapper around
3870 * `findElements()` which only returns the first found node.
3871 *
3872 * This function is sensitive to the amount of arguments passed to it;
3873 * if only one argument is specified, it is used as selector-expression
3874 * as-is. When two arguments are passed, the first argument is treated
3875 * as attribute name, the second one as attribute value to match.
3876 *
3877 * As an example, `map.findElement('input')` would find the first `&lt;input>`
3878 * node while `map.findElement('type', 'text')` would find the first DOM
3879 * node with a `type="text"` attribute.
3880 *
3881 * @param {string} selector_or_attrname
3882 * If invoked with only one parameter, this argument is a `querySelector()`
3883 * compatible selector expression. If invoked with two parameters, this
3884 * argument is the attribute name to filter for.
3885 *
3886 * @param {string} [attrvalue]
3887 * In case the function is invoked with two parameters, this argument
3888 * specifies the attribute value to match.
3889 *
3890 * @throws {InternalError}
3891 * Throws an `InternalError` if more than two function parameters are
3892 * passed.
3893 *
3894 * @returns {Node|null}
3895 * Returns the first found DOM node or `null` if no element matched.
3896 */
3897 findElement: function(/* ... */) {
3898 var res = this.findElements.apply(this, arguments);
3899 return res.length ? res[0] : null;
3900 },
3901
3902 /**
3903 * Tie another UCI configuration to the map.
3904 *
3905 * By default, a map instance will only load the UCI configuration file
3906 * specified in the constructor but sometimes access to values from
3907 * further configuration files is required. This function allows for such
3908 * use cases by registering further UCI configuration files which are
3909 * needed by the map.
3910 *
3911 * @param {string} config
3912 * The additional UCI configuration file to tie to the map. If the given
3913 * config already is in the list of required files, it will be ignored.
3914 */
3915 chain: function(config) {
3916 if (this.parsechain.indexOf(config) == -1)
3917 this.parsechain.push(config);
3918 },
3919
3920 /**
3921 * Add a configuration section to the map.
3922 *
3923 * LuCI forms follow the structure of the underlying UCI configurations,
3924 * means that a map, which represents a single UCI configuration, is
3925 * divided into multiple sections which in turn contain an arbitrary
3926 * number of options.
3927 *
3928 * While UCI itself only knows two kinds of sections - named and anonymous
3929 * ones - the form class offers various flavors of form section elements
3930 * to present configuration sections in different ways. Refer to the
3931 * documentation of the different section classes for details.
3932 *
3933 * @param {LuCI.form.AbstractSection} sectionclass
3934 * The section class to use for rendering the configuration section.
3935 * Note that this value must be the class itself, not a class instance
3936 * obtained from calling `new`. It must also be a class dervied from
3937 * `LuCI.form.AbstractSection`.
3938 *
3939 * @param {...string} classargs
3940 * Additional arguments which are passed as-is to the contructor of the
3941 * given section class. Refer to the class specific constructor
3942 * documentation for details.
3943 *
3944 * @returns {LuCI.form.AbstractSection}
3945 * Returns the instantiated section class instance.
3946 */
3947 section: function(cbiClass /*, ... */) {
3948 if (!CBIAbstractSection.isSubclass(cbiClass))
3949 L.error('TypeError', 'Class must be a descendent of CBIAbstractSection');
3950
3951 var obj = cbiClass.instantiate(this.varargs(arguments, 1, this));
3952 this.append(obj);
3953 return obj;
3954 },
3955
3956 /**
3957 * Load the configuration covered by this map.
3958 *
3959 * The `load()` function first loads all referenced UCI configurations,
3960 * then it recursively walks the form element tree and invokes the
3961 * load function of each child element.
3962 *
3963 * @returns {Promise&lt;void>}
3964 * Returns a promise resolving once the entire form completed loading all
3965 * data. The promise may reject with an error if any configuration failed
3966 * to load or if any of the child elements load functions rejected with
3967 * an error.
3968 */
3969 load: function() {
3970 var doCheckACL = (!(this instanceof CBIJSONMap) &amp;&amp; this.readonly == null),
3971 loadTasks = [ doCheckACL ? callSessionAccess('uci', this.config, 'write') : true ],
3972 configs = this.parsechain || [ this.config ];
3973
3974 loadTasks.push.apply(loadTasks, configs.map(L.bind(function(config, i) {
3975 return i ? L.resolveDefault(this.data.load(config)) : this.data.load(config);
3976 }, this)));
3977
3978 return Promise.all(loadTasks).then(L.bind(function(res) {
3979 if (res[0] === false)
3980 this.readonly = true;
3981
3982 return this.loadChildren();
3983 }, this));
3984 },
3985
3986 /**
3987 * Parse the form input values.
3988 *
3989 * The `parse()` function recursively walks the form element tree and
3990 * triggers input value reading and validation for each child element.
3991 *
3992 * Elements which are hidden due to unsatisified dependencies are skipped.
3993 *
3994 * @returns {Promise&lt;void>}
3995 * Returns a promise resolving once the entire form completed parsing all
3996 * input values. The returned promise is rejected if any parsed values are
3997 * not meeting the validation constraints of their respective elements.
3998 */
3999 parse: function() {
4000 var tasks = [];
4001
4002 if (Array.isArray(this.children))
4003 for (var i = 0; i &lt; this.children.length; i++)
4004 tasks.push(this.children[i].parse());
4005
4006 return Promise.all(tasks);
4007 },
4008
4009 /**
4010 * Save the form input values.
4011 *
4012 * This function parses the current form, saves the resulting UCI changes,
4013 * reloads the UCI configuration data and redraws the form elements.
4014 *
4015 * @param {function} [cb]
4016 * An optional callback function that is invoked after the form is parsed
4017 * but before the changed UCI data is saved. This is useful to perform
4018 * additional data manipulation steps before saving the changes.
4019 *
4020 * @param {boolean} [silent=false]
4021 * If set to `true`, trigger an alert message to the user in case saving
4022 * the form data failes. Otherwise fail silently.
4023 *
4024 * @returns {Promise&lt;void>}
4025 * Returns a promise resolving once the entire save operation is complete.
4026 * The returned promise is rejected if any step of the save operation
4027 * failed.
4028 */
4029 save: function(cb, silent) {
4030 this.checkDepends();
4031
4032 return this.parse()
4033 .then(cb)
4034 .then(this.data.save.bind(this.data))
4035 .then(this.load.bind(this))
4036 .catch(function(e) {
4037 if (!silent) {
4038 ui.showModal(_('Save error'), [
4039 E('p', {}, [ _('An error occurred while saving the form:') ]),
4040 E('p', {}, [ E('em', { 'style': 'white-space:pre' }, [ e.message ]) ]),
4041 E('div', { 'class': 'right' }, [
4042 E('button', { 'class': 'btn', 'click': ui.hideModal }, [ _('Dismiss') ])
4043 ])
4044 ]);
4045 }
4046
4047 return Promise.reject(e);
4048 }).then(this.renderContents.bind(this));
4049 },
4050
4051 /**
4052 * Reset the form by re-rendering its contents. This will revert all
4053 * unsaved user inputs to their initial form state.
4054 *
4055 * @returns {Promise&lt;Node>}
4056 * Returns a promise resolving to the toplevel form DOM node once the
4057 * re-rendering is complete.
4058 */
4059 reset: function() {
4060 return this.renderContents();
4061 },
4062
4063 /**
4064 * Render the form markup.
4065 *
4066 * @returns {Promise&lt;Node>}
4067 * Returns a promise resolving to the toplevel form DOM node once the
4068 * rendering is complete.
4069 */
4070 render: function() {
4071 return this.load().then(this.renderContents.bind(this));
4072 },
4073
4074 /** @private */
4075 renderContents: function() {
4076 var mapEl = this.root || (this.root = E('div', {
4077 'id': 'cbi-%s'.format(this.config),
4078 'class': 'cbi-map',
4079 'cbi-dependency-check': L.bind(this.checkDepends, this)
4080 }));
4081
4082 dom.bindClassInstance(mapEl, this);
4083
4084 return this.renderChildren(null).then(L.bind(function(nodes) {
4085 var initialRender = !mapEl.firstChild;
4086
4087 dom.content(mapEl, null);
4088
4089 if (this.title != null &amp;&amp; this.title != '')
4090 mapEl.appendChild(E('h2', { 'name': 'content' }, this.title));
4091
4092 if (this.description != null &amp;&amp; this.description != '')
4093 mapEl.appendChild(E('div', { 'class': 'cbi-map-descr' }, this.description));
4094
4095 if (this.tabbed)
4096 dom.append(mapEl, E('div', { 'class': 'cbi-map-tabbed' }, nodes));
4097 else
4098 dom.append(mapEl, nodes);
4099
4100 if (!initialRender) {
4101 mapEl.classList.remove('flash');
4102
4103 window.setTimeout(function() {
4104 mapEl.classList.add('flash');
4105 }, 1);
4106 }
4107
4108 this.checkDepends();
4109
4110 var tabGroups = mapEl.querySelectorAll('.cbi-map-tabbed, .cbi-section-node-tabbed');
4111
4112 for (var i = 0; i &lt; tabGroups.length; i++)
4113 ui.tabs.initTabGroup(tabGroups[i].childNodes);
4114
4115 return mapEl;
4116 }, this));
4117 },
4118
4119 /**
4120 * Find a form option element instance.
4121 *
4122 * @param {string} name_or_id
4123 * The name or the full ID of the option element to look up.
4124 *
4125 * @param {string} [section_id]
4126 * The ID of the UCI section containing the option to look up. May be
4127 * omitted if a full ID is passed as first argument.
4128 *
4129 * @param {string} [config]
4130 * The name of the UCI configuration the option instance is belonging to.
4131 * Defaults to the main UCI configuration of the map if omitted.
4132 *
4133 * @returns {Array&lt;LuCI.form.AbstractValue,string>|null}
4134 * Returns a two-element array containing the form option instance as
4135 * first item and the corresponding UCI section ID as second item.
4136 * Returns `null` if the option could not be found.
4137 */
4138 lookupOption: function(name, section_id, config_name) {
4139 var id, elem, sid, inst;
4140
4141 if (name.indexOf('.') > -1)
4142 id = 'cbid.%s'.format(name);
4143 else
4144 id = 'cbid.%s.%s.%s'.format(config_name || this.config, section_id, name);
4145
4146 elem = this.findElement('data-field', id);
4147 sid = elem ? id.split(/\./)[2] : null;
4148 inst = elem ? dom.findClassInstance(elem) : null;
4149
4150 return (inst instanceof CBIAbstractValue) ? [ inst, sid ] : null;
4151 },
4152
4153 /** @private */
4154 checkDepends: function(ev, n) {
4155 var changed = false;
4156
4157 for (var i = 0, s = this.children[0]; (s = this.children[i]) != null; i++)
4158 if (s.checkDepends(ev, n))
4159 changed = true;
4160
4161 if (changed &amp;&amp; (n || 0) &lt; 10)
4162 this.checkDepends(ev, (n || 10) + 1);
4163
4164 ui.tabs.updateTabs(ev, this.root);
4165 },
4166
4167 /** @private */
4168 isDependencySatisfied: function(depends, config_name, section_id) {
4169 var def = false;
4170
4171 if (!Array.isArray(depends) || !depends.length)
4172 return true;
4173
4174 for (var i = 0; i &lt; depends.length; i++) {
4175 var istat = true,
4176 reverse = depends[i]['!reverse'],
4177 contains = depends[i]['!contains'];
4178
4179 for (var dep in depends[i]) {
4180 if (dep == '!reverse' || dep == '!contains') {
4181 continue;
4182 }
4183 else if (dep == '!default') {
4184 def = true;
4185 istat = false;
4186 }
4187 else {
4188 var res = this.lookupOption(dep, section_id, config_name),
4189 val = (res &amp;&amp; res[0].isActive(res[1])) ? res[0].formvalue(res[1]) : null;
4190
4191 var equal = contains
4192 ? isContained(val, depends[i][dep])
4193 : isEqual(val, depends[i][dep]);
4194
4195 istat = (istat &amp;&amp; equal);
4196 }
4197 }
4198
4199 if (istat ^ reverse)
4200 return true;
4201 }
4202
4203 return def;
4204 }
4205 });
4206
4207 /**
4208 * @constructor JSONMap
4209 * @memberof LuCI.form
4210 * @augments LuCI.form.Map
4211 *
4212 * @classdesc
4213 *
4214 * A `JSONMap` class functions similar to [LuCI.form.Map]{@link LuCI.form.Map}
4215 * but uses a multidimensional JavaScript object instead of UCI configuration
4216 * as data source.
4217 *
4218 * @param {Object&lt;string, Object&lt;string, *>|Array&lt;Object&lt;string, *>>>} data
4219 * The JavaScript object to use as data source. Internally, the object is
4220 * converted into an UCI-like format. Its toplevel keys are treated like UCI
4221 * section types while the object or array-of-object values are treated as
4222 * section contents.
4223 *
4224 * @param {string} [title]
4225 * The title caption of the form. A form title is usually rendered as separate
4226 * headline element before the actual form contents. If omitted, the
4227 * corresponding headline element will not be rendered.
4228 *
4229 * @param {string} [description]
4230 * The description text of the form which is usually rendered as text
4231 * paragraph below the form title and before the actual form conents.
4232 * If omitted, the corresponding paragraph element will not be rendered.
4233 */
4234 var CBIJSONMap = CBIMap.extend(/** @lends LuCI.form.JSONMap.prototype */ {
4235 __init__: function(data /*, ... */) {
4236 this.super('__init__', this.varargs(arguments, 1, 'json'));
4237
4238 this.config = 'json';
4239 this.parsechain = [ 'json' ];
4240 this.data = new CBIJSONConfig(data);
4241 }
4242 });
4243
4244 /**
4245 * @class AbstractSection
4246 * @memberof LuCI.form
4247 * @augments LuCI.form.AbstractElement
4248 * @hideconstructor
4249 * @classdesc
4250 *
4251 * The `AbstractSection` class serves as abstract base for the different form
4252 * section styles implemented by `LuCI.form`. It provides the common logic for
4253 * enumerating underlying configuration section instances, for registering
4254 * form options and for handling tabs to segment child options.
4255 *
4256 * This class is private and not directly accessible by user code.
4257 */
4258 var CBIAbstractSection = CBIAbstractElement.extend(/** @lends LuCI.form.AbstractSection.prototype */ {
4259 __init__: function(map, sectionType /*, ... */) {
4260 this.super('__init__', this.varargs(arguments, 2));
4261
4262 this.sectiontype = sectionType;
4263 this.map = map;
4264 this.config = map.config;
4265
4266 this.optional = true;
4267 this.addremove = false;
4268 this.dynamic = false;
4269 },
4270
4271 /**
4272 * Access the parent option container instance.
4273 *
4274 * In case this section is nested within an option element container,
4275 * this property will hold a reference to the parent option instance.
4276 *
4277 * If this section is not nested, the property is `null`.
4278 *
4279 * @name LuCI.form.AbstractSection.prototype#parentoption
4280 * @type LuCI.form.AbstractValue
4281 * @readonly
4282 */
4283
4284 /**
4285 * Enumerate the UCI section IDs covered by this form section element.
4286 *
4287 * @abstract
4288 * @throws {InternalError}
4289 * Throws an `InternalError` exception if the function is not implemented.
4290 *
4291 * @returns {string[]}
4292 * Returns an array of UCI section IDs covered by this form element.
4293 * The sections will be rendered in the same order as the returned array.
4294 */
4295 cfgsections: function() {
4296 L.error('InternalError', 'Not implemented');
4297 },
4298
4299 /**
4300 * Filter UCI section IDs to render.
4301 *
4302 * The filter function is invoked for each UCI section ID of a given type
4303 * and controls whether the given UCI section is rendered or ignored by
4304 * the form section element.
4305 *
4306 * The default implementation always returns `true`. User code or
4307 * classes extending `AbstractSection` may overwrite this function with
4308 * custom implementations.
4309 *
4310 * @abstract
4311 * @param {string} section_id
4312 * The UCI section ID to test.
4313 *
4314 * @returns {boolean}
4315 * Returns `true` when the given UCI section ID should be handled and
4316 * `false` when it should be ignored.
4317 */
4318 filter: function(section_id) {
4319 return true;
4320 },
4321
4322 /**
4323 * Load the configuration covered by this section.
4324 *
4325 * The `load()` function recursively walks the section element tree and
4326 * invokes the load function of each child option element.
4327 *
4328 * @returns {Promise&lt;void>}
4329 * Returns a promise resolving once the values of all child elements have
4330 * been loaded. The promise may reject with an error if any of the child
4331 * elements load functions rejected with an error.
4332 */
4333 load: function() {
4334 var section_ids = this.cfgsections(),
4335 tasks = [];
4336
4337 if (Array.isArray(this.children))
4338 for (var i = 0; i &lt; section_ids.length; i++)
4339 tasks.push(this.loadChildren(section_ids[i])
4340 .then(Function.prototype.bind.call(function(section_id, set_values) {
4341 for (var i = 0; i &lt; set_values.length; i++)
4342 this.children[i].cfgvalue(section_id, set_values[i]);
4343 }, this, section_ids[i])));
4344
4345 return Promise.all(tasks);
4346 },
4347
4348 /**
4349 * Parse this sections form input.
4350 *
4351 * The `parse()` function recursively walks the section element tree and
4352 * triggers input value reading and validation for each encountered child
4353 * option element.
4354 *
4355 * Options which are hidden due to unsatisified dependencies are skipped.
4356 *
4357 * @returns {Promise&lt;void>}
4358 * Returns a promise resolving once the values of all child elements have
4359 * been parsed. The returned promise is rejected if any parsed values are
4360 * not meeting the validation constraints of their respective elements.
4361 */
4362 parse: function() {
4363 var section_ids = this.cfgsections(),
4364 tasks = [];
4365
4366 if (Array.isArray(this.children))
4367 for (var i = 0; i &lt; section_ids.length; i++)
4368 for (var j = 0; j &lt; this.children.length; j++)
4369 tasks.push(this.children[j].parse(section_ids[i]));
4370
4371 return Promise.all(tasks);
4372 },
4373
4374 /**
4375 * Add an option tab to the section.
4376 *
4377 * The child option elements of a section may be divided into multiple
4378 * tabs to provide a better overview to the user.
4379 *
4380 * Before options can be moved into a tab pane, the corresponding tab
4381 * has to be defined first, which is done by calling this function.
4382 *
4383 * Note that once tabs are defined, user code must use the `taboption()`
4384 * method to add options to specific tabs. Option elements added by
4385 * `option()` will not be assigned to any tab and not be rendered in this
4386 * case.
4387 *
4388 * @param {string} name
4389 * The name of the tab to register. It may be freely chosen and just serves
4390 * as an identifier to differentiate tabs.
4391 *
4392 * @param {string} title
4393 * The human readable caption of the tab.
4394 *
4395 * @param {string} [description]
4396 * An additional description text for the corresponding tab pane. It is
4397 * displayed as text paragraph below the tab but before the tab pane
4398 * contents. If omitted, no description will be rendered.
4399 *
4400 * @throws {Error}
4401 * Throws an exeption if a tab with the same `name` already exists.
4402 */
4403 tab: function(name, title, description) {
4404 if (this.tabs &amp;&amp; this.tabs[name])
4405 throw 'Tab already declared';
4406
4407 var entry = {
4408 name: name,
4409 title: title,
4410 description: description,
4411 children: []
4412 };
4413
4414 this.tabs = this.tabs || [];
4415 this.tabs.push(entry);
4416 this.tabs[name] = entry;
4417
4418 this.tab_names = this.tab_names || [];
4419 this.tab_names.push(name);
4420 },
4421
4422 /**
4423 * Add a configuration option widget to the section.
4424 *
4425 * Note that [taboption()]{@link LuCI.form.AbstractSection#taboption}
4426 * should be used instead if this form section element uses tabs.
4427 *
4428 * @param {LuCI.form.AbstractValue} optionclass
4429 * The option class to use for rendering the configuration option. Note
4430 * that this value must be the class itself, not a class instance obtained
4431 * from calling `new`. It must also be a class dervied from
4432 * [LuCI.form.AbstractSection]{@link LuCI.form.AbstractSection}.
4433 *
4434 * @param {...*} classargs
4435 * Additional arguments which are passed as-is to the contructor of the
4436 * given option class. Refer to the class specific constructor
4437 * documentation for details.
4438 *
4439 * @throws {TypeError}
4440 * Throws a `TypeError` exception in case the passed class value is not a
4441 * descendent of `AbstractValue`.
4442 *
4443 * @returns {LuCI.form.AbstractValue}
4444 * Returns the instantiated option class instance.
4445 */
4446 option: function(cbiClass /*, ... */) {
4447 if (!CBIAbstractValue.isSubclass(cbiClass))
4448 throw L.error('TypeError', 'Class must be a descendent of CBIAbstractValue');
4449
4450 var obj = cbiClass.instantiate(this.varargs(arguments, 1, this.map, this));
4451 this.append(obj);
4452 return obj;
4453 },
4454
4455 /**
4456 * Add a configuration option widget to a tab of the section.
4457 *
4458 * @param {string} tabname
4459 * The name of the section tab to add the option element to.
4460 *
4461 * @param {LuCI.form.AbstractValue} optionclass
4462 * The option class to use for rendering the configuration option. Note
4463 * that this value must be the class itself, not a class instance obtained
4464 * from calling `new`. It must also be a class dervied from
4465 * [LuCI.form.AbstractSection]{@link LuCI.form.AbstractSection}.
4466 *
4467 * @param {...*} classargs
4468 * Additional arguments which are passed as-is to the contructor of the
4469 * given option class. Refer to the class specific constructor
4470 * documentation for details.
4471 *
4472 * @throws {ReferenceError}
4473 * Throws a `ReferenceError` exception when the given tab name does not
4474 * exist.
4475 *
4476 * @throws {TypeError}
4477 * Throws a `TypeError` exception in case the passed class value is not a
4478 * descendent of `AbstractValue`.
4479 *
4480 * @returns {LuCI.form.AbstractValue}
4481 * Returns the instantiated option class instance.
4482 */
4483 taboption: function(tabName /*, ... */) {
4484 if (!this.tabs || !this.tabs[tabName])
4485 throw L.error('ReferenceError', 'Associated tab not declared');
4486
4487 var obj = this.option.apply(this, this.varargs(arguments, 1));
4488 obj.tab = tabName;
4489 this.tabs[tabName].children.push(obj);
4490 return obj;
4491 },
4492
4493 /**
4494 * Query underlying option configuration values.
4495 *
4496 * This function is sensitive to the amount of arguments passed to it;
4497 * if only one argument is specified, the configuration values of all
4498 * options within this section are returned as dictionary.
4499 *
4500 * If both the section ID and an option name are supplied, this function
4501 * returns the configuration value of the specified option only.
4502 *
4503 * @param {string} section_id
4504 * The configuration section ID
4505 *
4506 * @param {string} [option]
4507 * The name of the option to query
4508 *
4509 * @returns {null|string|string[]|Object&lt;string, null|string|string[]>}
4510 * Returns either a dictionary of option names and their corresponding
4511 * configuration values or just a single configuration value, depending
4512 * on the amount of passed arguments.
4513 */
4514 cfgvalue: function(section_id, option) {
4515 var rv = (arguments.length == 1) ? {} : null;
4516
4517 for (var i = 0, o; (o = this.children[i]) != null; i++)
4518 if (rv)
4519 rv[o.option] = o.cfgvalue(section_id);
4520 else if (o.option == option)
4521 return o.cfgvalue(section_id);
4522
4523 return rv;
4524 },
4525
4526 /**
4527 * Query underlying option widget input values.
4528 *
4529 * This function is sensitive to the amount of arguments passed to it;
4530 * if only one argument is specified, the widget input values of all
4531 * options within this section are returned as dictionary.
4532 *
4533 * If both the section ID and an option name are supplied, this function
4534 * returns the widget input value of the specified option only.
4535 *
4536 * @param {string} section_id
4537 * The configuration section ID
4538 *
4539 * @param {string} [option]
4540 * The name of the option to query
4541 *
4542 * @returns {null|string|string[]|Object&lt;string, null|string|string[]>}
4543 * Returns either a dictionary of option names and their corresponding
4544 * widget input values or just a single widget input value, depending
4545 * on the amount of passed arguments.
4546 */
4547 formvalue: function(section_id, option) {
4548 var rv = (arguments.length == 1) ? {} : null;
4549
4550 for (var i = 0, o; (o = this.children[i]) != null; i++) {
4551 var func = this.map.root ? this.children[i].formvalue : this.children[i].cfgvalue;
4552
4553 if (rv)
4554 rv[o.option] = func.call(o, section_id);
4555 else if (o.option == option)
4556 return func.call(o, section_id);
4557 }
4558
4559 return rv;
4560 },
4561
4562 /**
4563 * Obtain underlying option LuCI.ui widget instances.
4564 *
4565 * This function is sensitive to the amount of arguments passed to it;
4566 * if only one argument is specified, the LuCI.ui widget instances of all
4567 * options within this section are returned as dictionary.
4568 *
4569 * If both the section ID and an option name are supplied, this function
4570 * returns the LuCI.ui widget instance value of the specified option only.
4571 *
4572 * @param {string} section_id
4573 * The configuration section ID
4574 *
4575 * @param {string} [option]
4576 * The name of the option to query
4577 *
4578 * @returns {null|LuCI.ui.AbstractElement|Object&lt;string, null|LuCI.ui.AbstractElement>}
4579 * Returns either a dictionary of option names and their corresponding
4580 * widget input values or just a single widget input value, depending
4581 * on the amount of passed arguments.
4582 */
4583 getUIElement: function(section_id, option) {
4584 var rv = (arguments.length == 1) ? {} : null;
4585
4586 for (var i = 0, o; (o = this.children[i]) != null; i++)
4587 if (rv)
4588 rv[o.option] = o.getUIElement(section_id);
4589 else if (o.option == option)
4590 return o.getUIElement(section_id);
4591
4592 return rv;
4593 },
4594
4595 /**
4596 * Obtain underlying option objects.
4597 *
4598 * This function is sensitive to the amount of arguments passed to it;
4599 * if no option name is specified, all options within this section are
4600 * returned as dictionary.
4601 *
4602 * If an option name is supplied, this function returns the matching
4603 * LuCI.form.AbstractValue instance only.
4604 *
4605 * @param {string} [option]
4606 * The name of the option object to obtain
4607 *
4608 * @returns {null|LuCI.form.AbstractValue|Object&lt;string, LuCI.form.AbstractValue>}
4609 * Returns either a dictionary of option names and their corresponding
4610 * option instance objects or just a single object instance value,
4611 * depending on the amount of passed arguments.
4612 */
4613 getOption: function(option) {
4614 var rv = (arguments.length == 0) ? {} : null;
4615
4616 for (var i = 0, o; (o = this.children[i]) != null; i++)
4617 if (rv)
4618 rv[o.option] = o;
4619 else if (o.option == option)
4620 return o;
4621
4622 return rv;
4623 },
4624
4625 /** @private */
4626 renderUCISection: function(section_id) {
4627 var renderTasks = [];
4628
4629 if (!this.tabs)
4630 return this.renderOptions(null, section_id);
4631
4632 for (var i = 0; i &lt; this.tab_names.length; i++)
4633 renderTasks.push(this.renderOptions(this.tab_names[i], section_id));
4634
4635 return Promise.all(renderTasks)
4636 .then(this.renderTabContainers.bind(this, section_id));
4637 },
4638
4639 /** @private */
4640 renderTabContainers: function(section_id, nodes) {
4641 var config_name = this.uciconfig || this.map.config,
4642 containerEls = E([]);
4643
4644 for (var i = 0; i &lt; nodes.length; i++) {
4645 var tab_name = this.tab_names[i],
4646 tab_data = this.tabs[tab_name],
4647 containerEl = E('div', {
4648 'id': 'container.%s.%s.%s'.format(config_name, section_id, tab_name),
4649 'data-tab': tab_name,
4650 'data-tab-title': tab_data.title,
4651 'data-tab-active': tab_name === this.selected_tab
4652 });
4653
4654 if (tab_data.description != null &amp;&amp; tab_data.description != '')
4655 containerEl.appendChild(
4656 E('div', { 'class': 'cbi-tab-descr' }, tab_data.description));
4657
4658 containerEl.appendChild(nodes[i]);
4659 containerEls.appendChild(containerEl);
4660 }
4661
4662 return containerEls;
4663 },
4664
4665 /** @private */
4666 renderOptions: function(tab_name, section_id) {
4667 var in_table = (this instanceof CBITableSection);
4668 return this.renderChildren(tab_name, section_id, in_table).then(function(nodes) {
4669 var optionEls = E([]);
4670 for (var i = 0; i &lt; nodes.length; i++)
4671 optionEls.appendChild(nodes[i]);
4672 return optionEls;
4673 });
4674 },
4675
4676 /** @private */
4677 checkDepends: function(ev, n) {
4678 var changed = false,
4679 sids = this.cfgsections();
4680
4681 for (var i = 0, sid = sids[0]; (sid = sids[i]) != null; i++) {
4682 for (var j = 0, o = this.children[0]; (o = this.children[j]) != null; j++) {
4683 var isActive = o.isActive(sid),
4684 isSatisified = o.checkDepends(sid);
4685
4686 if (isActive != isSatisified) {
4687 o.setActive(sid, !isActive);
4688 isActive = !isActive;
4689 changed = true;
4690 }
4691
4692 if (!n &amp;&amp; isActive)
4693 o.triggerValidation(sid);
4694 }
4695 }
4696
4697 return changed;
4698 }
4699 });
4700
4701
4702 var isEqual = function(x, y) {
4703 if (typeof(y) == 'object' &amp;&amp; y instanceof RegExp)
4704 return (x == null) ? false : y.test(x);
4705
4706 if (x != null &amp;&amp; y != null &amp;&amp; typeof(x) != typeof(y))
4707 return false;
4708
4709 if ((x == null &amp;&amp; y != null) || (x != null &amp;&amp; y == null))
4710 return false;
4711
4712 if (Array.isArray(x)) {
4713 if (x.length != y.length)
4714 return false;
4715
4716 for (var i = 0; i &lt; x.length; i++)
4717 if (!isEqual(x[i], y[i]))
4718 return false;
4719 }
4720 else if (typeof(x) == 'object') {
4721 for (var k in x) {
4722 if (x.hasOwnProperty(k) &amp;&amp; !y.hasOwnProperty(k))
4723 return false;
4724
4725 if (!isEqual(x[k], y[k]))
4726 return false;
4727 }
4728
4729 for (var k in y)
4730 if (y.hasOwnProperty(k) &amp;&amp; !x.hasOwnProperty(k))
4731 return false;
4732 }
4733 else if (x != y) {
4734 return false;
4735 }
4736
4737 return true;
4738 };
4739
4740 var isContained = function(x, y) {
4741 if (Array.isArray(x)) {
4742 for (var i = 0; i &lt; x.length; i++)
4743 if (x[i] == y)
4744 return true;
4745 }
4746 else if (L.isObject(x)) {
4747 if (x.hasOwnProperty(y) &amp;&amp; x[y] != null)
4748 return true;
4749 }
4750 else if (typeof(x) == 'string') {
4751 return (x.indexOf(y) > -1);
4752 }
4753
4754 return false;
4755 };
4756
4757 /**
4758 * @class AbstractValue
4759 * @memberof LuCI.form
4760 * @augments LuCI.form.AbstractElement
4761 * @hideconstructor
4762 * @classdesc
4763 *
4764 * The `AbstractValue` class serves as abstract base for the different form
4765 * option styles implemented by `LuCI.form`. It provides the common logic for
4766 * handling option input values, for dependencies among options and for
4767 * validation constraints that should be applied to entered values.
4768 *
4769 * This class is private and not directly accessible by user code.
4770 */
4771 var CBIAbstractValue = CBIAbstractElement.extend(/** @lends LuCI.form.AbstractValue.prototype */ {
4772 __init__: function(map, section, option /*, ... */) {
4773 this.super('__init__', this.varargs(arguments, 3));
4774
4775 this.section = section;
4776 this.option = option;
4777 this.map = map;
4778 this.config = map.config;
4779
4780 this.deps = [];
4781 this.initial = {};
4782 this.rmempty = true;
4783 this.default = null;
4784 this.size = null;
4785 this.optional = false;
4786 },
4787
4788 /**
4789 * If set to `false`, the underlying option value is retained upon saving
4790 * the form when the option element is disabled due to unsatisfied
4791 * dependency constraints.
4792 *
4793 * @name LuCI.form.AbstractValue.prototype#rmempty
4794 * @type boolean
4795 * @default true
4796 */
4797
4798 /**
4799 * If set to `true`, the underlying ui input widget is allowed to be empty,
4800 * otherwise the option element is marked invalid when no value is entered
4801 * or selected by the user.
4802 *
4803 * @name LuCI.form.AbstractValue.prototype#optional
4804 * @type boolean
4805 * @default false
4806 */
4807
4808 /**
4809 * Sets a default value to use when the underlying UCI option is not set.
4810 *
4811 * @name LuCI.form.AbstractValue.prototype#default
4812 * @type *
4813 * @default null
4814 */
4815
4816 /**
4817 * Specifies a datatype constraint expression to validate input values
4818 * against. Refer to {@link LuCI.validation} for details on the format.
4819 *
4820 * If the user entered input does not match the datatype validation, the
4821 * option element is marked as invalid.
4822 *
4823 * @name LuCI.form.AbstractValue.prototype#datatype
4824 * @type string
4825 * @default null
4826 */
4827
4828 /**
4829 * Specifies a custom validation function to test the user input for
4830 * validity. The validation function must return `true` to accept the
4831 * value. Any other return value type is converted to a string and
4832 * displayed to the user as validation error message.
4833 *
4834 * If the user entered input does not pass the validation function, the
4835 * option element is marked as invalid.
4836 *
4837 * @name LuCI.form.AbstractValue.prototype#validate
4838 * @type function
4839 * @default null
4840 */
4841
4842 /**
4843 * Override the UCI configuration name to read the option value from.
4844 *
4845 * By default, the configuration name is inherited from the parent Map.
4846 * By setting this property, a deviating configuration may be specified.
4847 *
4848 * The default is null, means inheriting from the parent form.
4849 *
4850 * @name LuCI.form.AbstractValue.prototype#uciconfig
4851 * @type string
4852 * @default null
4853 */
4854
4855 /**
4856 * Override the UCI section name to read the option value from.
4857 *
4858 * By default, the section ID is inherited from the parent section element.
4859 * By setting this property, a deviating section may be specified.
4860 *
4861 * The default is null, means inheriting from the parent section.
4862 *
4863 * @name LuCI.form.AbstractValue.prototype#ucisection
4864 * @type string
4865 * @default null
4866 */
4867
4868 /**
4869 * Override the UCI option name to read the value from.
4870 *
4871 * By default, the elements name, which is passed as third argument to
4872 * the constructor, is used as UCI option name. By setting this property,
4873 * a deviating UCI option may be specified.
4874 *
4875 * The default is null, means using the option element name.
4876 *
4877 * @name LuCI.form.AbstractValue.prototype#ucioption
4878 * @type string
4879 * @default null
4880 */
4881
4882 /**
4883 * Mark grid section option element as editable.
4884 *
4885 * Options which are displayed in the table portion of a `GridSection`
4886 * instance are rendered as readonly text by default. By setting the
4887 * `editable` property of a child option element to `true`, that element
4888 * is rendered as full input widget within its cell instead of a text only
4889 * preview.
4890 *
4891 * This property has no effect on options that are not children of grid
4892 * section elements.
4893 *
4894 * @name LuCI.form.AbstractValue.prototype#editable
4895 * @type boolean
4896 * @default false
4897 */
4898
4899 /**
4900 * Move grid section option element into the table, the modal popup or both.
4901 *
4902 * If this property is `null` (the default), the option element is
4903 * displayed in both the table preview area and the per-section instance
4904 * modal popup of a grid section. When it is set to `false` the option
4905 * is only shown in the table but not the modal popup. When set to `true`,
4906 * the option is only visible in the modal popup but not the table.
4907 *
4908 * This property has no effect on options that are not children of grid
4909 * section elements.
4910 *
4911 * @name LuCI.form.AbstractValue.prototype#modalonly
4912 * @type boolean
4913 * @default null
4914 */
4915
4916 /**
4917 * Make option element readonly.
4918 *
4919 * This property defaults to the readonly state of the parent form element.
4920 * When set to `true`, the underlying widget is rendered in disabled state,
4921 * means its contents cannot be changed and the widget cannot be interacted
4922 * with.
4923 *
4924 * @name LuCI.form.AbstractValue.prototype#readonly
4925 * @type boolean
4926 * @default false
4927 */
4928
4929 /**
4930 * Override the cell width of a table or grid section child option.
4931 *
4932 * If the property is set to a numeric value, it is treated as pixel width
4933 * which is set on the containing cell element of the option, essentially
4934 * forcing a certain column width. When the property is set to a string
4935 * value, it is applied as-is to the CSS `width` property.
4936 *
4937 * This property has no effect on options that are not children of grid or
4938 * table section elements.
4939 *
4940 * @name LuCI.form.AbstractValue.prototype#width
4941 * @type number|string
4942 * @default null
4943 */
4944
4945 /**
4946 * Register a custom value change handler.
4947 *
4948 * If this property is set to a function value, the function is invoked
4949 * whenever the value of the underlying UI input element is changing.
4950 *
4951 * The invoked handler function will receive the DOM click element as
4952 * first and the underlying configuration section ID as well as the input
4953 * value as second and third argument respectively.
4954 *
4955 * @name LuCI.form.AbstractValue.prototype#onchange
4956 * @type function
4957 * @default null
4958 */
4959
4960 /**
4961 * Add a dependency contraint to the option.
4962 *
4963 * Dependency constraints allow making the presence of option elements
4964 * dependant on the current values of certain other options within the
4965 * same form. An option element with unsatisfied dependencies will be
4966 * hidden from the view and its current value is omitted when saving.
4967 *
4968 * Multiple constraints (that is, multiple calls to `depends()`) are
4969 * treated as alternatives, forming a logical "or" expression.
4970 *
4971 * By passing an object of name => value pairs as first argument, it is
4972 * possible to depend on multiple options simultaneously, allowing to form
4973 * a logical "and" expression.
4974 *
4975 * Option names may be given in "dot notation" which allows to reference
4976 * option elements outside of the current form section. If a name without
4977 * dot is specified, it refers to an option within the same configuration
4978 * section. If specified as &lt;code>configname.sectionid.optionname&lt;/code>,
4979 * options anywhere within the same form may be specified.
4980 *
4981 * The object notation also allows for a number of special keys which are
4982 * not treated as option names but as modifiers to influence the dependency
4983 * constraint evaluation. The associated value of these special "tag" keys
4984 * is ignored. The recognized tags are:
4985 *
4986 * &lt;ul>
4987 * &lt;li>
4988 * &lt;code>!reverse&lt;/code>&lt;br>
4989 * Invert the dependency, instead of requiring another option to be
4990 * equal to the dependency value, that option should &lt;em>not&lt;/em> be
4991 * equal.
4992 * &lt;/li>
4993 * &lt;li>
4994 * &lt;code>!contains&lt;/code>&lt;br>
4995 * Instead of requiring an exact match, the dependency is considered
4996 * satisfied when the dependency value is contained within the option
4997 * value.
4998 * &lt;/li>
4999 * &lt;li>
5000 * &lt;code>!default&lt;/code>&lt;br>
5001 * The dependency is always satisfied
5002 * &lt;/li>
5003 * &lt;/ul>
5004 *
5005 * Examples:
5006 *
5007 * &lt;ul>
5008 * &lt;li>
5009 * &lt;code>opt.depends("foo", "test")&lt;/code>&lt;br>
5010 * Require the value of `foo` to be `test`.
5011 * &lt;/li>
5012 * &lt;li>
5013 * &lt;code>opt.depends({ foo: "test" })&lt;/code>&lt;br>
5014 * Equivalent to the previous example.
5015 * &lt;/li>
5016 * &lt;li>
5017 * &lt;code>opt.depends({ foo: /test/ })&lt;/code>&lt;br>
5018 * Require the value of `foo` to match the regular expression `/test/`.
5019 * &lt;/li>
5020 * &lt;li>
5021 * &lt;code>opt.depends({ foo: "test", bar: "qrx" })&lt;/code>&lt;br>
5022 * Require the value of `foo` to be `test` and the value of `bar` to be
5023 * `qrx`.
5024 * &lt;/li>
5025 * &lt;li>
5026 * &lt;code>opt.depends({ foo: "test" })&lt;br>
5027 * opt.depends({ bar: "qrx" })&lt;/code>&lt;br>
5028 * Require either &lt;code>foo&lt;/code> to be set to &lt;code>test&lt;/code>,
5029 * &lt;em>or&lt;/em> the &lt;code>bar&lt;/code> option to be &lt;code>qrx&lt;/code>.
5030 * &lt;/li>
5031 * &lt;li>
5032 * &lt;code>opt.depends("test.section1.foo", "bar")&lt;/code>&lt;br>
5033 * Require the "foo" form option within the "section1" section to be
5034 * set to "bar".
5035 * &lt;/li>
5036 * &lt;li>
5037 * &lt;code>opt.depends({ foo: "test", "!contains": true })&lt;/code>&lt;br>
5038 * Require the "foo" option value to contain the substring "test".
5039 * &lt;/li>
5040 * &lt;/ul>
5041 *
5042 * @param {string|Object&lt;string, string|RegExp>} optionname_or_depends
5043 * The name of the option to depend on or an object describing multiple
5044 * dependencies which must be satified (a logical "and" expression).
5045 *
5046 * @param {string} optionvalue|RegExp
5047 * When invoked with a plain option name as first argument, this parameter
5048 * specifies the expected value. In case an object is passed as first
5049 * argument, this parameter is ignored.
5050 */
5051 depends: function(field, value) {
5052 var deps;
5053
5054 if (typeof(field) === 'string')
5055 deps = {}, deps[field] = value;
5056 else
5057 deps = field;
5058
5059 this.deps.push(deps);
5060 },
5061
5062 /** @private */
5063 transformDepList: function(section_id, deplist) {
5064 var list = deplist || this.deps,
5065 deps = [];
5066
5067 if (Array.isArray(list)) {
5068 for (var i = 0; i &lt; list.length; i++) {
5069 var dep = {};
5070
5071 for (var k in list[i]) {
5072 if (list[i].hasOwnProperty(k)) {
5073 if (k.charAt(0) === '!')
5074 dep[k] = list[i][k];
5075 else if (k.indexOf('.') !== -1)
5076 dep['cbid.%s'.format(k)] = list[i][k];
5077 else
5078 dep['cbid.%s.%s.%s'.format(
5079 this.uciconfig || this.section.uciconfig || this.map.config,
5080 this.ucisection || section_id,
5081 k
5082 )] = list[i][k];
5083 }
5084 }
5085
5086 for (var k in dep) {
5087 if (dep.hasOwnProperty(k)) {
5088 deps.push(dep);
5089 break;
5090 }
5091 }
5092 }
5093 }
5094
5095 return deps;
5096 },
5097
5098 /** @private */
5099 transformChoices: function() {
5100 if (!Array.isArray(this.keylist) || this.keylist.length == 0)
5101 return null;
5102
5103 var choices = {};
5104
5105 for (var i = 0; i &lt; this.keylist.length; i++)
5106 choices[this.keylist[i]] = this.vallist[i];
5107
5108 return choices;
5109 },
5110
5111 /** @private */
5112 checkDepends: function(section_id) {
5113 var config_name = this.uciconfig || this.section.uciconfig || this.map.config,
5114 active = this.map.isDependencySatisfied(this.deps, config_name, section_id);
5115
5116 if (active)
5117 this.updateDefaultValue(section_id);
5118
5119 return active;
5120 },
5121
5122 /** @private */
5123 updateDefaultValue: function(section_id) {
5124 if (!L.isObject(this.defaults))
5125 return;
5126
5127 var config_name = this.uciconfig || this.section.uciconfig || this.map.config,
5128 cfgvalue = L.toArray(this.cfgvalue(section_id))[0],
5129 default_defval = null, satisified_defval = null;
5130
5131 for (var value in this.defaults) {
5132 if (!this.defaults[value] || this.defaults[value].length == 0) {
5133 default_defval = value;
5134 continue;
5135 }
5136 else if (this.map.isDependencySatisfied(this.defaults[value], config_name, section_id)) {
5137 satisified_defval = value;
5138 break;
5139 }
5140 }
5141
5142 if (satisified_defval == null)
5143 satisified_defval = default_defval;
5144
5145 var node = this.map.findElement('id', this.cbid(section_id));
5146 if (node &amp;&amp; node.getAttribute('data-changed') != 'true' &amp;&amp; satisified_defval != null &amp;&amp; cfgvalue == null)
5147 dom.callClassMethod(node, 'setValue', satisified_defval);
5148
5149 this.default = satisified_defval;
5150 },
5151
5152 /**
5153 * Obtain the internal ID ("cbid") of the element instance.
5154 *
5155 * Since each form section element may map multiple underlying
5156 * configuration sections, the configuration section ID is required to
5157 * form a fully qualified ID pointing to the specific element instance
5158 * within the given specific section.
5159 *
5160 * @param {string} section_id
5161 * The configuration section ID
5162 *
5163 * @throws {TypeError}
5164 * Throws a `TypeError` exception when no `section_id` was specified.
5165 *
5166 * @returns {string}
5167 * Returns the element ID.
5168 */
5169 cbid: function(section_id) {
5170 if (section_id == null)
5171 L.error('TypeError', 'Section ID required');
5172
5173 return 'cbid.%s.%s.%s'.format(
5174 this.uciconfig || this.section.uciconfig || this.map.config,
5175 section_id, this.option);
5176 },
5177
5178 /**
5179 * Load the underlying configuration value.
5180 *
5181 * The default implementation of this method reads and returns the
5182 * underlying UCI option value (or the related JavaScript property for
5183 * `JSONMap` instances). It may be overwritten by user code to load data
5184 * from nonstandard sources.
5185 *
5186 * @param {string} section_id
5187 * The configuration section ID
5188 *
5189 * @throws {TypeError}
5190 * Throws a `TypeError` exception when no `section_id` was specified.
5191 *
5192 * @returns {*|Promise&lt;*>}
5193 * Returns the configuration value to initialize the option element with.
5194 * The return value of this function is filtered through `Promise.resolve()`
5195 * so it may return promises if overridden by user code.
5196 */
5197 load: function(section_id) {
5198 if (section_id == null)
5199 L.error('TypeError', 'Section ID required');
5200
5201 return this.map.data.get(
5202 this.uciconfig || this.section.uciconfig || this.map.config,
5203 this.ucisection || section_id,
5204 this.ucioption || this.option);
5205 },
5206
5207 /**
5208 * Obtain the underlying `LuCI.ui` element instance.
5209 *
5210 * @param {string} section_id
5211 * The configuration section ID
5212 *
5213 * @throws {TypeError}
5214 * Throws a `TypeError` exception when no `section_id` was specified.
5215 *
5216 * @return {LuCI.ui.AbstractElement|null}
5217 * Returns the `LuCI.ui` element instance or `null` in case the form
5218 * option implementation does not use `LuCI.ui` widgets.
5219 */
5220 getUIElement: function(section_id) {
5221 var node = this.map.findElement('id', this.cbid(section_id)),
5222 inst = node ? dom.findClassInstance(node) : null;
5223 return (inst instanceof ui.AbstractElement) ? inst : null;
5224 },
5225
5226 /**
5227 * Query the underlying configuration value.
5228 *
5229 * The default implementation of this method returns the cached return
5230 * value of [load()]{@link LuCI.form.AbstractValue#load}. It may be
5231 * overwritten by user code to obtain the configuration value in a
5232 * different way.
5233 *
5234 * @param {string} section_id
5235 * The configuration section ID
5236 *
5237 * @throws {TypeError}
5238 * Throws a `TypeError` exception when no `section_id` was specified.
5239 *
5240 * @returns {*}
5241 * Returns the configuration value.
5242 */
5243 cfgvalue: function(section_id, set_value) {
5244 if (section_id == null)
5245 L.error('TypeError', 'Section ID required');
5246
5247 if (arguments.length == 2) {
5248 this.data = this.data || {};
5249 this.data[section_id] = set_value;
5250 }
5251
5252 return this.data ? this.data[section_id] : null;
5253 },
5254
5255 /**
5256 * Query the current form input value.
5257 *
5258 * The default implementation of this method returns the current input
5259 * value of the underlying [LuCI.ui]{@link LuCI.ui.AbstractElement} widget.
5260 * It may be overwritten by user code to handle input values differently.
5261 *
5262 * @param {string} section_id
5263 * The configuration section ID
5264 *
5265 * @throws {TypeError}
5266 * Throws a `TypeError` exception when no `section_id` was specified.
5267 *
5268 * @returns {*}
5269 * Returns the current input value.
5270 */
5271 formvalue: function(section_id) {
5272 var elem = this.getUIElement(section_id);
5273 return elem ? elem.getValue() : null;
5274 },
5275
5276 /**
5277 * Obtain a textual input representation.
5278 *
5279 * The default implementation of this method returns the HTML escaped
5280 * current input value of the underlying
5281 * [LuCI.ui]{@link LuCI.ui.AbstractElement} widget. User code or specific
5282 * option element implementations may overwrite this function to apply a
5283 * different logic, e.g. to return `Yes` or `No` depending on the checked
5284 * state of checkbox elements.
5285 *
5286 * @param {string} section_id
5287 * The configuration section ID
5288 *
5289 * @throws {TypeError}
5290 * Throws a `TypeError` exception when no `section_id` was specified.
5291 *
5292 * @returns {string}
5293 * Returns the text representation of the current input value.
5294 */
5295 textvalue: function(section_id) {
5296 var cval = this.cfgvalue(section_id);
5297
5298 if (cval == null)
5299 cval = this.default;
5300
5301 return (cval != null) ? '%h'.format(cval) : null;
5302 },
5303
5304 /**
5305 * Apply custom validation logic.
5306 *
5307 * This method is invoked whenever incremental validation is performed on
5308 * the user input, e.g. on keyup or blur events.
5309 *
5310 * The default implementation of this method does nothing and always
5311 * returns `true`. User code may overwrite this method to provide
5312 * additional validation logic which is not covered by data type
5313 * constraints.
5314 *
5315 * @abstract
5316 * @param {string} section_id
5317 * The configuration section ID
5318 *
5319 * @param {*} value
5320 * The value to validate
5321 *
5322 * @returns {*}
5323 * The method shall return `true` to accept the given value. Any other
5324 * return value is treated as failure, converted to a string and displayed
5325 * as error message to the user.
5326 */
5327 validate: function(section_id, value) {
5328 return true;
5329 },
5330
5331 /**
5332 * Test whether the input value is currently valid.
5333 *
5334 * @param {string} section_id
5335 * The configuration section ID
5336 *
5337 * @returns {boolean}
5338 * Returns `true` if the input value currently is valid, otherwise it
5339 * returns `false`.
5340 */
5341 isValid: function(section_id) {
5342 var elem = this.getUIElement(section_id);
5343 return elem ? elem.isValid() : true;
5344 },
5345
5346 /**
5347 * Test whether the option element is currently active.
5348 *
5349 * An element is active when it is not hidden due to unsatisfied dependency
5350 * constraints.
5351 *
5352 * @param {string} section_id
5353 * The configuration section ID
5354 *
5355 * @returns {boolean}
5356 * Returns `true` if the option element currently is active, otherwise it
5357 * returns `false`.
5358 */
5359 isActive: function(section_id) {
5360 var field = this.map.findElement('data-field', this.cbid(section_id));
5361 return (field != null &amp;&amp; !field.classList.contains('hidden'));
5362 },
5363
5364 /** @private */
5365 setActive: function(section_id, active) {
5366 var field = this.map.findElement('data-field', this.cbid(section_id));
5367
5368 if (field &amp;&amp; field.classList.contains('hidden') == active) {
5369 field.classList[active ? 'remove' : 'add']('hidden');
5370
5371 if (dom.matches(field.parentNode, '.td.cbi-value-field'))
5372 field.parentNode.classList[active ? 'remove' : 'add']('inactive');
5373
5374 return true;
5375 }
5376
5377 return false;
5378 },
5379
5380 /** @private */
5381 triggerValidation: function(section_id) {
5382 var elem = this.getUIElement(section_id);
5383 return elem ? elem.triggerValidation() : true;
5384 },
5385
5386 /**
5387 * Parse the option element input.
5388 *
5389 * The function is invoked when the `parse()` method has been invoked on
5390 * the parent form and triggers input value reading and validation.
5391 *
5392 * @param {string} section_id
5393 * The configuration section ID
5394 *
5395 * @returns {Promise&lt;void>}
5396 * Returns a promise resolving once the input value has been read and
5397 * validated or rejecting in case the input value does not meet the
5398 * validation constraints.
5399 */
5400 parse: function(section_id) {
5401 var active = this.isActive(section_id),
5402 cval = this.cfgvalue(section_id),
5403 fval = active ? this.formvalue(section_id) : null;
5404
5405 if (active &amp;&amp; !this.isValid(section_id)) {
5406 var title = this.stripTags(this.title).trim();
5407 return Promise.reject(new TypeError(_('Option "%s" contains an invalid input value.').format(title || this.option)));
5408 }
5409
5410 if (fval != '' &amp;&amp; fval != null) {
5411 if (this.forcewrite || !isEqual(cval, fval))
5412 return Promise.resolve(this.write(section_id, fval));
5413 }
5414 else {
5415 if (!active || this.rmempty || this.optional) {
5416 return Promise.resolve(this.remove(section_id));
5417 }
5418 else if (!isEqual(cval, fval)) {
5419 var title = this.stripTags(this.title).trim();
5420 return Promise.reject(new TypeError(_('Option "%s" must not be empty.').format(title || this.option)));
5421 }
5422 }
5423
5424 return Promise.resolve();
5425 },
5426
5427 /**
5428 * Write the current input value into the configuration.
5429 *
5430 * This function is invoked upon saving the parent form when the option
5431 * element is valid and when its input value has been changed compared to
5432 * the initial value returned by
5433 * [cfgvalue()]{@link LuCI.form.AbstractValue#cfgvalue}.
5434 *
5435 * The default implementation simply sets the given input value in the
5436 * UCI configuration (or the associated JavaScript object property in
5437 * case of `JSONMap` forms). It may be overwritten by user code to
5438 * implement alternative save logic, e.g. to transform the input value
5439 * before it is written.
5440 *
5441 * @param {string} section_id
5442 * The configuration section ID
5443 *
5444 * @param {string|string[]} formvalue
5445 * The input value to write.
5446 */
5447 write: function(section_id, formvalue) {
5448 return this.map.data.set(
5449 this.uciconfig || this.section.uciconfig || this.map.config,
5450 this.ucisection || section_id,
5451 this.ucioption || this.option,
5452 formvalue);
5453 },
5454
5455 /**
5456 * Remove the corresponding value from the configuration.
5457 *
5458 * This function is invoked upon saving the parent form when the option
5459 * element has been hidden due to unsatisfied dependencies or when the
5460 * user cleared the input value and the option is marked optional.
5461 *
5462 * The default implementation simply removes the associated option from the
5463 * UCI configuration (or the associated JavaScript object property in
5464 * case of `JSONMap` forms). It may be overwritten by user code to
5465 * implement alternative removal logic, e.g. to retain the original value.
5466 *
5467 * @param {string} section_id
5468 * The configuration section ID
5469 */
5470 remove: function(section_id) {
5471 return this.map.data.unset(
5472 this.uciconfig || this.section.uciconfig || this.map.config,
5473 this.ucisection || section_id,
5474 this.ucioption || this.option);
5475 }
5476 });
5477
5478 /**
5479 * @class TypedSection
5480 * @memberof LuCI.form
5481 * @augments LuCI.form.AbstractSection
5482 * @hideconstructor
5483 * @classdesc
5484 *
5485 * The `TypedSection` class maps all or - if `filter()` is overwritten - a
5486 * subset of the underlying UCI configuration sections of a given type.
5487 *
5488 * Layout wise, the configuration section instances mapped by the section
5489 * element (sometimes referred to as "section nodes") are stacked beneath
5490 * each other in a single column, with an optional section remove button next
5491 * to each section node and a section add button at the end, depending on the
5492 * value of the `addremove` property.
5493 *
5494 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
5495 * The configuration form this section is added to. It is automatically passed
5496 * by [section()]{@link LuCI.form.Map#section}.
5497 *
5498 * @param {string} section_type
5499 * The type of the UCI section to map.
5500 *
5501 * @param {string} [title]
5502 * The title caption of the form section element.
5503 *
5504 * @param {string} [description]
5505 * The description text of the form section element.
5506 */
5507 var CBITypedSection = CBIAbstractSection.extend(/** @lends LuCI.form.TypedSection.prototype */ {
5508 __name__: 'CBI.TypedSection',
5509
5510 /**
5511 * If set to `true`, the user may add or remove instances from the form
5512 * section widget, otherwise only preexisting sections may be edited.
5513 * The default is `false`.
5514 *
5515 * @name LuCI.form.TypedSection.prototype#addremove
5516 * @type boolean
5517 * @default false
5518 */
5519
5520 /**
5521 * If set to `true`, mapped section instances are treated as anonymous
5522 * UCI sections, which means that section instance elements will be
5523 * rendered without title element and that no name is required when adding
5524 * new sections. The default is `false`.
5525 *
5526 * @name LuCI.form.TypedSection.prototype#anonymous
5527 * @type boolean
5528 * @default false
5529 */
5530
5531 /**
5532 * When set to `true`, instead of rendering section instances one below
5533 * another, treat each instance as separate tab pane and render a tab menu
5534 * at the top of the form section element, allowing the user to switch
5535 * among instances. The default is `false`.
5536 *
5537 * @name LuCI.form.TypedSection.prototype#tabbed
5538 * @type boolean
5539 * @default false
5540 */
5541
5542 /**
5543 * Override the caption used for the section add button at the bottom of
5544 * the section form element. If set to a string, it will be used as-is,
5545 * if set to a function, the function will be invoked and its return value
5546 * is used as caption, after converting it to a string. If this property
5547 * is not set, the default is `Add`.
5548 *
5549 * @name LuCI.form.TypedSection.prototype#addbtntitle
5550 * @type string|function
5551 * @default null
5552 */
5553
5554 /**
5555 * Override the UCI configuration name to read the section IDs from. By
5556 * default, the configuration name is inherited from the parent `Map`.
5557 * By setting this property, a deviating configuration may be specified.
5558 * The default is `null`, means inheriting from the parent form.
5559 *
5560 * @name LuCI.form.TypedSection.prototype#uciconfig
5561 * @type string
5562 * @default null
5563 */
5564
5565 /** @override */
5566 cfgsections: function() {
5567 return this.map.data.sections(this.uciconfig || this.map.config, this.sectiontype)
5568 .map(function(s) { return s['.name'] })
5569 .filter(L.bind(this.filter, this));
5570 },
5571
5572 /** @private */
5573 handleAdd: function(ev, name) {
5574 var config_name = this.uciconfig || this.map.config;
5575
5576 this.map.data.add(config_name, this.sectiontype, name);
5577 return this.map.save(null, true);
5578 },
5579
5580 /** @private */
5581 handleRemove: function(section_id, ev) {
5582 var config_name = this.uciconfig || this.map.config;
5583
5584 this.map.data.remove(config_name, section_id);
5585 return this.map.save(null, true);
5586 },
5587
5588 /** @private */
5589 renderSectionAdd: function(extra_class) {
5590 if (!this.addremove)
5591 return E([]);
5592
5593 var createEl = E('div', { 'class': 'cbi-section-create' }),
5594 config_name = this.uciconfig || this.map.config,
5595 btn_title = this.titleFn('addbtntitle');
5596
5597 if (extra_class != null)
5598 createEl.classList.add(extra_class);
5599
5600 if (this.anonymous) {
5601 createEl.appendChild(E('button', {
5602 'class': 'cbi-button cbi-button-add',
5603 'title': btn_title || _('Add'),
5604 'click': ui.createHandlerFn(this, 'handleAdd'),
5605 'disabled': this.map.readonly || null
5606 }, [ btn_title || _('Add') ]));
5607 }
5608 else {
5609 var nameEl = E('input', {
5610 'type': 'text',
5611 'class': 'cbi-section-create-name',
5612 'disabled': this.map.readonly || null
5613 });
5614
5615 dom.append(createEl, [
5616 E('div', {}, nameEl),
5617 E('input', {
5618 'class': 'cbi-button cbi-button-add',
5619 'type': 'submit',
5620 'value': btn_title || _('Add'),
5621 'title': btn_title || _('Add'),
5622 'click': ui.createHandlerFn(this, function(ev) {
5623 if (nameEl.classList.contains('cbi-input-invalid'))
5624 return;
5625
5626 return this.handleAdd(ev, nameEl.value);
5627 }),
5628 'disabled': this.map.readonly || null
5629 })
5630 ]);
5631
5632 ui.addValidator(nameEl, 'uciname', true, 'blur', 'keyup');
5633 }
5634
5635 return createEl;
5636 },
5637
5638 /** @private */
5639 renderSectionPlaceholder: function() {
5640 return E([
5641 E('em', _('This section contains no values yet')),
5642 E('br'), E('br')
5643 ]);
5644 },
5645
5646 /** @private */
5647 renderContents: function(cfgsections, nodes) {
5648 var section_id = null,
5649 config_name = this.uciconfig || this.map.config,
5650 sectionEl = E('div', {
5651 'id': 'cbi-%s-%s'.format(config_name, this.sectiontype),
5652 'class': 'cbi-section',
5653 'data-tab': (this.map.tabbed &amp;&amp; !this.parentoption) ? this.sectiontype : null,
5654 'data-tab-title': (this.map.tabbed &amp;&amp; !this.parentoption) ? this.title || this.sectiontype : null
5655 });
5656
5657 if (this.title != null &amp;&amp; this.title != '')
5658 sectionEl.appendChild(E('legend', {}, this.title));
5659
5660 if (this.description != null &amp;&amp; this.description != '')
5661 sectionEl.appendChild(E('div', { 'class': 'cbi-section-descr' }, this.description));
5662
5663 for (var i = 0; i &lt; nodes.length; i++) {
5664 if (this.addremove) {
5665 sectionEl.appendChild(
5666 E('div', { 'class': 'cbi-section-remove right' },
5667 E('button', {
5668 'class': 'cbi-button',
5669 'name': 'cbi.rts.%s.%s'.format(config_name, cfgsections[i]),
5670 'data-section-id': cfgsections[i],
5671 'click': ui.createHandlerFn(this, 'handleRemove', cfgsections[i]),
5672 'disabled': this.map.readonly || null
5673 }, [ _('Delete') ])));
5674 }
5675
5676 if (!this.anonymous)
5677 sectionEl.appendChild(E('h3', cfgsections[i].toUpperCase()));
5678
5679 sectionEl.appendChild(E('div', {
5680 'id': 'cbi-%s-%s'.format(config_name, cfgsections[i]),
5681 'class': this.tabs
5682 ? 'cbi-section-node cbi-section-node-tabbed' : 'cbi-section-node',
5683 'data-section-id': cfgsections[i]
5684 }, nodes[i]));
5685 }
5686
5687 if (nodes.length == 0)
5688 sectionEl.appendChild(this.renderSectionPlaceholder());
5689
5690 sectionEl.appendChild(this.renderSectionAdd());
5691
5692 dom.bindClassInstance(sectionEl, this);
5693
5694 return sectionEl;
5695 },
5696
5697 /** @override */
5698 render: function() {
5699 var cfgsections = this.cfgsections(),
5700 renderTasks = [];
5701
5702 for (var i = 0; i &lt; cfgsections.length; i++)
5703 renderTasks.push(this.renderUCISection(cfgsections[i]));
5704
5705 return Promise.all(renderTasks).then(this.renderContents.bind(this, cfgsections));
5706 }
5707 });
5708
5709 /**
5710 * @class TableSection
5711 * @memberof LuCI.form
5712 * @augments LuCI.form.TypedSection
5713 * @hideconstructor
5714 * @classdesc
5715 *
5716 * The `TableSection` class maps all or - if `filter()` is overwritten - a
5717 * subset of the underlying UCI configuration sections of a given type.
5718 *
5719 * Layout wise, the configuration section instances mapped by the section
5720 * element (sometimes referred to as "section nodes") are rendered as rows
5721 * within an HTML table element, with an optional section remove button in the
5722 * last column and a section add button below the table, depending on the
5723 * value of the `addremove` property.
5724 *
5725 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
5726 * The configuration form this section is added to. It is automatically passed
5727 * by [section()]{@link LuCI.form.Map#section}.
5728 *
5729 * @param {string} section_type
5730 * The type of the UCI section to map.
5731 *
5732 * @param {string} [title]
5733 * The title caption of the form section element.
5734 *
5735 * @param {string} [description]
5736 * The description text of the form section element.
5737 */
5738 var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.prototype */ {
5739 __name__: 'CBI.TableSection',
5740
5741 /**
5742 * If set to `true`, the user may add or remove instances from the form
5743 * section widget, otherwise only preexisting sections may be edited.
5744 * The default is `false`.
5745 *
5746 * @name LuCI.form.TableSection.prototype#addremove
5747 * @type boolean
5748 * @default false
5749 */
5750
5751 /**
5752 * If set to `true`, mapped section instances are treated as anonymous
5753 * UCI sections, which means that section instance elements will be
5754 * rendered without title element and that no name is required when adding
5755 * new sections. The default is `false`.
5756 *
5757 * @name LuCI.form.TableSection.prototype#anonymous
5758 * @type boolean
5759 * @default false
5760 */
5761
5762 /**
5763 * Override the caption used for the section add button at the bottom of
5764 * the section form element. If set to a string, it will be used as-is,
5765 * if set to a function, the function will be invoked and its return value
5766 * is used as caption, after converting it to a string. If this property
5767 * is not set, the default is `Add`.
5768 *
5769 * @name LuCI.form.TableSection.prototype#addbtntitle
5770 * @type string|function
5771 * @default null
5772 */
5773
5774 /**
5775 * Override the per-section instance title caption shown in the first
5776 * column of the table unless `anonymous` is set to true. If set to a
5777 * string, it will be used as `String.format()` pattern with the name of
5778 * the underlying UCI section as first argument, if set to a function, the
5779 * function will be invoked with the section name as first argument and
5780 * its return value is used as caption, after converting it to a string.
5781 * If this property is not set, the default is the name of the underlying
5782 * UCI configuration section.
5783 *
5784 * @name LuCI.form.TableSection.prototype#sectiontitle
5785 * @type string|function
5786 * @default null
5787 */
5788
5789 /**
5790 * Override the per-section instance modal popup title caption shown when
5791 * clicking the `More…` button in a section specifying `max_cols`. If set
5792 * to a string, it will be used as `String.format()` pattern with the name
5793 * of the underlying UCI section as first argument, if set to a function,
5794 * the function will be invoked with the section name as first argument and
5795 * its return value is used as caption, after converting it to a string.
5796 * If this property is not set, the default is the name of the underlying
5797 * UCI configuration section.
5798 *
5799 * @name LuCI.form.TableSection.prototype#modaltitle
5800 * @type string|function
5801 * @default null
5802 */
5803
5804 /**
5805 * Override the UCI configuration name to read the section IDs from. By
5806 * default, the configuration name is inherited from the parent `Map`.
5807 * By setting this property, a deviating configuration may be specified.
5808 * The default is `null`, means inheriting from the parent form.
5809 *
5810 * @name LuCI.form.TableSection.prototype#uciconfig
5811 * @type string
5812 * @default null
5813 */
5814
5815 /**
5816 * Specify a maximum amount of columns to display. By default, one table
5817 * column is rendered for each child option of the form section element.
5818 * When this option is set to a positive number, then no more columns than
5819 * the given amount are rendered. When the number of child options exceeds
5820 * the specified amount, a `More…` button is rendered in the last column,
5821 * opening a modal dialog presenting all options elements in `NamedSection`
5822 * style when clicked.
5823 *
5824 * @name LuCI.form.TableSection.prototype#max_cols
5825 * @type number
5826 * @default null
5827 */
5828
5829 /**
5830 * If set to `true`, alternating `cbi-rowstyle-1` and `cbi-rowstyle-2` CSS
5831 * classes are added to the table row elements. Not all LuCI themes
5832 * implement these row style classes. The default is `false`.
5833 *
5834 * @name LuCI.form.TableSection.prototype#rowcolors
5835 * @type boolean
5836 * @default false
5837 */
5838
5839 /**
5840 * Enables a per-section instance row `Edit` button which triggers a certain
5841 * action when clicked. If set to a string, the string value is used
5842 * as `String.format()` pattern with the name of the underlying UCI section
5843 * as first format argument. The result is then interpreted as URL which
5844 * LuCI will navigate to when the user clicks the edit button.
5845 *
5846 * If set to a function, this function will be registered as click event
5847 * handler on the rendered edit button, receiving the section instance
5848 * name as first and the DOM click event as second argument.
5849 *
5850 * @name LuCI.form.TableSection.prototype#extedit
5851 * @type string|function
5852 * @default null
5853 */
5854
5855 /**
5856 * If set to `true`, a sort button is added to the last column, allowing
5857 * the user to reorder the section instances mapped by the section form
5858 * element.
5859 *
5860 * @name LuCI.form.TableSection.prototype#sortable
5861 * @type boolean
5862 * @default false
5863 */
5864
5865 /**
5866 * If set to `true`, the header row with the options descriptions will
5867 * not be displayed. By default, descriptions row is automatically displayed
5868 * when at least one option has a description.
5869 *
5870 * @name LuCI.form.TableSection.prototype#nodescriptions
5871 * @type boolean
5872 * @default false
5873 */
5874
5875 /**
5876 * The `TableSection` implementation does not support option tabbing, so
5877 * its implementation of `tab()` will always throw an exception when
5878 * invoked.
5879 *
5880 * @override
5881 * @throws Throws an exception when invoked.
5882 */
5883 tab: function() {
5884 throw 'Tabs are not supported by TableSection';
5885 },
5886
5887 /** @private */
5888 renderContents: function(cfgsections, nodes) {
5889 var section_id = null,
5890 config_name = this.uciconfig || this.map.config,
5891 max_cols = isNaN(this.max_cols) ? this.children.length : this.max_cols,
5892 has_more = max_cols &lt; this.children.length,
5893 sectionEl = E('div', {
5894 'id': 'cbi-%s-%s'.format(config_name, this.sectiontype),
5895 'class': 'cbi-section cbi-tblsection',
5896 'data-tab': (this.map.tabbed &amp;&amp; !this.parentoption) ? this.sectiontype : null,
5897 'data-tab-title': (this.map.tabbed &amp;&amp; !this.parentoption) ? this.title || this.sectiontype : null
5898 }),
5899 tableEl = E('div', {
5900 'class': 'table cbi-section-table'
5901 });
5902
5903 if (this.title != null &amp;&amp; this.title != '')
5904 sectionEl.appendChild(E('h3', {}, this.title));
5905
5906 if (this.description != null &amp;&amp; this.description != '')
5907 sectionEl.appendChild(E('div', { 'class': 'cbi-section-descr' }, this.description));
5908
5909 tableEl.appendChild(this.renderHeaderRows(max_cols));
5910
5911 for (var i = 0; i &lt; nodes.length; i++) {
5912 var sectionname = this.titleFn('sectiontitle', cfgsections[i]);
5913
5914 if (sectionname == null)
5915 sectionname = cfgsections[i];
5916
5917 var trEl = E('div', {
5918 'id': 'cbi-%s-%s'.format(config_name, cfgsections[i]),
5919 'class': 'tr cbi-section-table-row',
5920 'data-sid': cfgsections[i],
5921 'draggable': this.sortable ? true : null,
5922 'mousedown': this.sortable ? L.bind(this.handleDragInit, this) : null,
5923 'dragstart': this.sortable ? L.bind(this.handleDragStart, this) : null,
5924 'dragover': this.sortable ? L.bind(this.handleDragOver, this) : null,
5925 'dragenter': this.sortable ? L.bind(this.handleDragEnter, this) : null,
5926 'dragleave': this.sortable ? L.bind(this.handleDragLeave, this) : null,
5927 'dragend': this.sortable ? L.bind(this.handleDragEnd, this) : null,
5928 'drop': this.sortable ? L.bind(this.handleDrop, this) : null,
5929 'data-title': (sectionname &amp;&amp; (!this.anonymous || this.sectiontitle)) ? sectionname : null,
5930 'data-section-id': cfgsections[i]
5931 });
5932
5933 if (this.extedit || this.rowcolors)
5934 trEl.classList.add(!(tableEl.childNodes.length % 2)
5935 ? 'cbi-rowstyle-1' : 'cbi-rowstyle-2');
5936
5937 for (var j = 0; j &lt; max_cols &amp;&amp; nodes[i].firstChild; j++)
5938 trEl.appendChild(nodes[i].firstChild);
5939
5940 trEl.appendChild(this.renderRowActions(cfgsections[i], has_more ? _('More…') : null));
5941 tableEl.appendChild(trEl);
5942 }
5943
5944 if (nodes.length == 0)
5945 tableEl.appendChild(E('div', { 'class': 'tr cbi-section-table-row placeholder' },
5946 E('div', { 'class': 'td' },
5947 E('em', {}, _('This section contains no values yet')))));
5948
5949 sectionEl.appendChild(tableEl);
5950
5951 sectionEl.appendChild(this.renderSectionAdd('cbi-tblsection-create'));
5952
5953 dom.bindClassInstance(sectionEl, this);
5954
5955 return sectionEl;
5956 },
5957
5958 /** @private */
5959 renderHeaderRows: function(max_cols, has_action) {
5960 var has_titles = false,
5961 has_descriptions = false,
5962 max_cols = isNaN(this.max_cols) ? this.children.length : this.max_cols,
5963 has_more = max_cols &lt; this.children.length,
5964 anon_class = (!this.anonymous || this.sectiontitle) ? 'named' : 'anonymous',
5965 trEls = E([]);
5966
5967 for (var i = 0, opt; i &lt; max_cols &amp;&amp; (opt = this.children[i]) != null; i++) {
5968 if (opt.modalonly)
5969 continue;
5970
5971 has_titles = has_titles || !!opt.title;
5972 has_descriptions = has_descriptions || !!opt.description;
5973 }
5974
5975 if (has_titles) {
5976 var trEl = E('div', {
5977 'class': 'tr cbi-section-table-titles ' + anon_class,
5978 'data-title': (!this.anonymous || this.sectiontitle) ? _('Name') : null
5979 });
5980
5981 for (var i = 0, opt; i &lt; max_cols &amp;&amp; (opt = this.children[i]) != null; i++) {
5982 if (opt.modalonly)
5983 continue;
5984
5985 trEl.appendChild(E('div', {
5986 'class': 'th cbi-section-table-cell',
5987 'data-widget': opt.__name__
5988 }));
5989
5990 if (opt.width != null)
5991 trEl.lastElementChild.style.width =
5992 (typeof(opt.width) == 'number') ? opt.width+'px' : opt.width;
5993
5994 if (opt.titleref)
5995 trEl.lastElementChild.appendChild(E('a', {
5996 'href': opt.titleref,
5997 'class': 'cbi-title-ref',
5998 'title': this.titledesc || _('Go to relevant configuration page')
5999 }, opt.title));
6000 else
6001 dom.content(trEl.lastElementChild, opt.title);
6002 }
6003
6004 if (this.sortable || this.extedit || this.addremove || has_more || has_action)
6005 trEl.appendChild(E('div', {
6006 'class': 'th cbi-section-table-cell cbi-section-actions'
6007 }));
6008
6009 trEls.appendChild(trEl);
6010 }
6011
6012 if (has_descriptions &amp;&amp; !this.nodescriptions) {
6013 var trEl = E('div', {
6014 'class': 'tr cbi-section-table-descr ' + anon_class
6015 });
6016
6017 for (var i = 0, opt; i &lt; max_cols &amp;&amp; (opt = this.children[i]) != null; i++) {
6018 if (opt.modalonly)
6019 continue;
6020
6021 trEl.appendChild(E('div', {
6022 'class': 'th cbi-section-table-cell',
6023 'data-widget': opt.__name__
6024 }, opt.description));
6025
6026 if (opt.width != null)
6027 trEl.lastElementChild.style.width =
6028 (typeof(opt.width) == 'number') ? opt.width+'px' : opt.width;
6029 }
6030
6031 if (this.sortable || this.extedit || this.addremove || has_more || has_action)
6032 trEl.appendChild(E('div', {
6033 'class': 'th cbi-section-table-cell cbi-section-actions'
6034 }));
6035
6036 trEls.appendChild(trEl);
6037 }
6038
6039 return trEls;
6040 },
6041
6042 /** @private */
6043 renderRowActions: function(section_id, more_label) {
6044 var config_name = this.uciconfig || this.map.config;
6045
6046 if (!this.sortable &amp;&amp; !this.extedit &amp;&amp; !this.addremove &amp;&amp; !more_label)
6047 return E([]);
6048
6049 var tdEl = E('div', {
6050 'class': 'td cbi-section-table-cell nowrap cbi-section-actions'
6051 }, E('div'));
6052
6053 if (this.sortable) {
6054 dom.append(tdEl.lastElementChild, [
6055 E('div', {
6056 'title': _('Drag to reorder'),
6057 'class': 'btn cbi-button drag-handle center',
6058 'style': 'cursor:move',
6059 'disabled': this.map.readonly || null
6060 }, '☰')
6061 ]);
6062 }
6063
6064 if (this.extedit) {
6065 var evFn = null;
6066
6067 if (typeof(this.extedit) == 'function')
6068 evFn = L.bind(this.extedit, this);
6069 else if (typeof(this.extedit) == 'string')
6070 evFn = L.bind(function(sid, ev) {
6071 location.href = this.extedit.format(sid);
6072 }, this, section_id);
6073
6074 dom.append(tdEl.lastElementChild,
6075 E('button', {
6076 'title': _('Edit'),
6077 'class': 'cbi-button cbi-button-edit',
6078 'click': evFn
6079 }, [ _('Edit') ])
6080 );
6081 }
6082
6083 if (more_label) {
6084 dom.append(tdEl.lastElementChild,
6085 E('button', {
6086 'title': more_label,
6087 'class': 'cbi-button cbi-button-edit',
6088 'click': ui.createHandlerFn(this, 'renderMoreOptionsModal', section_id)
6089 }, [ more_label ])
6090 );
6091 }
6092
6093 if (this.addremove) {
6094 var btn_title = this.titleFn('removebtntitle', section_id);
6095
6096 dom.append(tdEl.lastElementChild,
6097 E('button', {
6098 'title': btn_title || _('Delete'),
6099 'class': 'cbi-button cbi-button-remove',
6100 'click': ui.createHandlerFn(this, 'handleRemove', section_id),
6101 'disabled': this.map.readonly || null
6102 }, [ btn_title || _('Delete') ])
6103 );
6104 }
6105
6106 return tdEl;
6107 },
6108
6109 /** @private */
6110 handleDragInit: function(ev) {
6111 scope.dragState = { node: ev.target };
6112 },
6113
6114 /** @private */
6115 handleDragStart: function(ev) {
6116 if (!scope.dragState || !scope.dragState.node.classList.contains('drag-handle')) {
6117 scope.dragState = null;
6118 ev.preventDefault();
6119 return false;
6120 }
6121
6122 scope.dragState.node = dom.parent(scope.dragState.node, '.tr');
6123 ev.dataTransfer.setData('text', 'drag');
6124 ev.target.style.opacity = 0.4;
6125 },
6126
6127 /** @private */
6128 handleDragOver: function(ev) {
6129 var n = scope.dragState.targetNode,
6130 r = scope.dragState.rect,
6131 t = r.top + r.height / 2;
6132
6133 if (ev.clientY &lt;= t) {
6134 n.classList.remove('drag-over-below');
6135 n.classList.add('drag-over-above');
6136 }
6137 else {
6138 n.classList.remove('drag-over-above');
6139 n.classList.add('drag-over-below');
6140 }
6141
6142 ev.dataTransfer.dropEffect = 'move';
6143 ev.preventDefault();
6144 return false;
6145 },
6146
6147 /** @private */
6148 handleDragEnter: function(ev) {
6149 scope.dragState.rect = ev.currentTarget.getBoundingClientRect();
6150 scope.dragState.targetNode = ev.currentTarget;
6151 },
6152
6153 /** @private */
6154 handleDragLeave: function(ev) {
6155 ev.currentTarget.classList.remove('drag-over-above');
6156 ev.currentTarget.classList.remove('drag-over-below');
6157 },
6158
6159 /** @private */
6160 handleDragEnd: function(ev) {
6161 var n = ev.target;
6162
6163 n.style.opacity = '';
6164 n.classList.add('flash');
6165 n.parentNode.querySelectorAll('.drag-over-above, .drag-over-below')
6166 .forEach(function(tr) {
6167 tr.classList.remove('drag-over-above');
6168 tr.classList.remove('drag-over-below');
6169 });
6170 },
6171
6172 /** @private */
6173 handleDrop: function(ev) {
6174 var s = scope.dragState;
6175
6176 if (s.node &amp;&amp; s.targetNode) {
6177 var config_name = this.uciconfig || this.map.config,
6178 ref_node = s.targetNode,
6179 after = false;
6180
6181 if (ref_node.classList.contains('drag-over-below')) {
6182 ref_node = ref_node.nextElementSibling;
6183 after = true;
6184 }
6185
6186 var sid1 = s.node.getAttribute('data-sid'),
6187 sid2 = s.targetNode.getAttribute('data-sid');
6188
6189 s.node.parentNode.insertBefore(s.node, ref_node);
6190 this.map.data.move(config_name, sid1, sid2, after);
6191 }
6192
6193 scope.dragState = null;
6194 ev.target.style.opacity = '';
6195 ev.stopPropagation();
6196 ev.preventDefault();
6197 return false;
6198 },
6199
6200 /** @private */
6201 handleModalCancel: function(modalMap, ev) {
6202 return Promise.resolve(ui.hideModal());
6203 },
6204
6205 /** @private */
6206 handleModalSave: function(modalMap, ev) {
6207 return modalMap.save(null, true)
6208 .then(L.bind(this.map.load, this.map))
6209 .then(L.bind(this.map.reset, this.map))
6210 .then(ui.hideModal)
6211 .catch(function() {});
6212 },
6213
6214 /**
6215 * Add further options to the per-section instanced modal popup.
6216 *
6217 * This function may be overwritten by user code to perform additional
6218 * setup steps before displaying the more options modal which is useful to
6219 * e.g. query additional data or to inject further option elements.
6220 *
6221 * The default implementation of this function does nothing.
6222 *
6223 * @abstract
6224 * @param {LuCI.form.NamedSection} modalSection
6225 * The `NamedSection` instance about to be rendered in the modal popup.
6226 *
6227 * @param {string} section_id
6228 * The ID of the underlying UCI section the modal popup belongs to.
6229 *
6230 * @param {Event} ev
6231 * The DOM event emitted by clicking the `More…` button.
6232 *
6233 * @returns {*|Promise&lt;*>}
6234 * Return values of this function are ignored but if a promise is returned,
6235 * it is run to completion before the rendering is continued, allowing
6236 * custom logic to perform asynchroneous work before the modal dialog
6237 * is shown.
6238 */
6239 addModalOptions: function(modalSection, section_id, ev) {
6240
6241 },
6242
6243 /** @private */
6244 renderMoreOptionsModal: function(section_id, ev) {
6245 var parent = this.map,
6246 title = parent.title,
6247 name = null,
6248 m = new CBIMap(this.map.config, null, null),
6249 s = m.section(CBINamedSection, section_id, this.sectiontype);
6250
6251 m.parent = parent;
6252 m.readonly = parent.readonly;
6253
6254 s.tabs = this.tabs;
6255 s.tab_names = this.tab_names;
6256
6257 if ((name = this.titleFn('modaltitle', section_id)) != null)
6258 title = name;
6259 else if ((name = this.titleFn('sectiontitle', section_id)) != null)
6260 title = '%s - %s'.format(parent.title, name);
6261 else if (!this.anonymous)
6262 title = '%s - %s'.format(parent.title, section_id);
6263
6264 for (var i = 0; i &lt; this.children.length; i++) {
6265 var o1 = this.children[i];
6266
6267 if (o1.modalonly === false)
6268 continue;
6269
6270 var o2 = s.option(o1.constructor, o1.option, o1.title, o1.description);
6271
6272 for (var k in o1) {
6273 if (!o1.hasOwnProperty(k))
6274 continue;
6275
6276 switch (k) {
6277 case 'map':
6278 case 'section':
6279 case 'option':
6280 case 'title':
6281 case 'description':
6282 continue;
6283
6284 default:
6285 o2[k] = o1[k];
6286 }
6287 }
6288 }
6289
6290 return Promise.resolve(this.addModalOptions(s, section_id, ev)).then(L.bind(m.render, m)).then(L.bind(function(nodes) {
6291 ui.showModal(title, [
6292 nodes,
6293 E('div', { 'class': 'right' }, [
6294 E('button', {
6295 'class': 'btn',
6296 'click': ui.createHandlerFn(this, 'handleModalCancel', m)
6297 }, [ _('Dismiss') ]), ' ',
6298 E('button', {
6299 'class': 'cbi-button cbi-button-positive important',
6300 'click': ui.createHandlerFn(this, 'handleModalSave', m),
6301 'disabled': m.readonly || null
6302 }, [ _('Save') ])
6303 ])
6304 ], 'cbi-modal');
6305 }, this)).catch(L.error);
6306 }
6307 });
6308
6309 /**
6310 * @class GridSection
6311 * @memberof LuCI.form
6312 * @augments LuCI.form.TableSection
6313 * @hideconstructor
6314 * @classdesc
6315 *
6316 * The `GridSection` class maps all or - if `filter()` is overwritten - a
6317 * subset of the underlying UCI configuration sections of a given type.
6318 *
6319 * A grid section functions similar to a {@link LuCI.form.TableSection} but
6320 * supports tabbing in the modal overlay. Option elements added with
6321 * [option()]{@link LuCI.form.GridSection#option} are shown in the table while
6322 * elements added with [taboption()]{@link LuCI.form.GridSection#taboption}
6323 * are displayed in the modal popup.
6324 *
6325 * Another important difference is that the table cells show a readonly text
6326 * preview of the corresponding option elements by default, unless the child
6327 * option element is explicitely made writable by setting the `editable`
6328 * property to `true`.
6329 *
6330 * Additionally, the grid section honours a `modalonly` property of child
6331 * option elements. Refer to the [AbstractValue]{@link LuCI.form.AbstractValue}
6332 * documentation for details.
6333 *
6334 * Layout wise, a grid section looks mostly identical to table sections.
6335 *
6336 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
6337 * The configuration form this section is added to. It is automatically passed
6338 * by [section()]{@link LuCI.form.Map#section}.
6339 *
6340 * @param {string} section_type
6341 * The type of the UCI section to map.
6342 *
6343 * @param {string} [title]
6344 * The title caption of the form section element.
6345 *
6346 * @param {string} [description]
6347 * The description text of the form section element.
6348 */
6349 var CBIGridSection = CBITableSection.extend(/** @lends LuCI.form.GridSection.prototype */ {
6350 /**
6351 * Add an option tab to the section.
6352 *
6353 * The modal option elements of a grid section may be divided into multiple
6354 * tabs to provide a better overview to the user.
6355 *
6356 * Before options can be moved into a tab pane, the corresponding tab
6357 * has to be defined first, which is done by calling this function.
6358 *
6359 * Note that tabs are only effective in modal popups, options added with
6360 * `option()` will not be assigned to a specific tab and are rendered in
6361 * the table view only.
6362 *
6363 * @param {string} name
6364 * The name of the tab to register. It may be freely chosen and just serves
6365 * as an identifier to differentiate tabs.
6366 *
6367 * @param {string} title
6368 * The human readable caption of the tab.
6369 *
6370 * @param {string} [description]
6371 * An additional description text for the corresponding tab pane. It is
6372 * displayed as text paragraph below the tab but before the tab pane
6373 * contents. If omitted, no description will be rendered.
6374 *
6375 * @throws {Error}
6376 * Throws an exeption if a tab with the same `name` already exists.
6377 */
6378 tab: function(name, title, description) {
6379 CBIAbstractSection.prototype.tab.call(this, name, title, description);
6380 },
6381
6382 /** @private */
6383 handleAdd: function(ev, name) {
6384 var config_name = this.uciconfig || this.map.config,
6385 section_id = this.map.data.add(config_name, this.sectiontype, name);
6386
6387 this.addedSection = section_id;
6388 return this.renderMoreOptionsModal(section_id);
6389 },
6390
6391 /** @private */
6392 handleModalSave: function(/* ... */) {
6393 return this.super('handleModalSave', arguments)
6394 .then(L.bind(function() { this.addedSection = null }, this));
6395 },
6396
6397 /** @private */
6398 handleModalCancel: function(/* ... */) {
6399 var config_name = this.uciconfig || this.map.config;
6400
6401 if (this.addedSection != null) {
6402 this.map.data.remove(config_name, this.addedSection);
6403 this.addedSection = null;
6404 }
6405
6406 return this.super('handleModalCancel', arguments);
6407 },
6408
6409 /** @private */
6410 renderUCISection: function(section_id) {
6411 return this.renderOptions(null, section_id);
6412 },
6413
6414 /** @private */
6415 renderChildren: function(tab_name, section_id, in_table) {
6416 var tasks = [], index = 0;
6417
6418 for (var i = 0, opt; (opt = this.children[i]) != null; i++) {
6419 if (opt.disable || opt.modalonly)
6420 continue;
6421
6422 if (opt.editable)
6423 tasks.push(opt.render(index++, section_id, in_table));
6424 else
6425 tasks.push(this.renderTextValue(section_id, opt));
6426 }
6427
6428 return Promise.all(tasks);
6429 },
6430
6431 /** @private */
6432 renderTextValue: function(section_id, opt) {
6433 var title = this.stripTags(opt.title).trim(),
6434 descr = this.stripTags(opt.description).trim(),
6435 value = opt.textvalue(section_id);
6436
6437 return E('div', {
6438 'class': 'td cbi-value-field',
6439 'data-title': (title != '') ? title : null,
6440 'data-description': (descr != '') ? descr : null,
6441 'data-name': opt.option,
6442 'data-widget': opt.typename || opt.__name__
6443 }, (value != null) ? value : E('em', _('none')));
6444 },
6445
6446 /** @private */
6447 renderHeaderRows: function(section_id) {
6448 return this.super('renderHeaderRows', [ NaN, true ]);
6449 },
6450
6451 /** @private */
6452 renderRowActions: function(section_id) {
6453 return this.super('renderRowActions', [ section_id, _('Edit') ]);
6454 },
6455
6456 /** @override */
6457 parse: function() {
6458 var section_ids = this.cfgsections(),
6459 tasks = [];
6460
6461 if (Array.isArray(this.children)) {
6462 for (var i = 0; i &lt; section_ids.length; i++) {
6463 for (var j = 0; j &lt; this.children.length; j++) {
6464 if (!this.children[j].editable || this.children[j].modalonly)
6465 continue;
6466
6467 tasks.push(this.children[j].parse(section_ids[i]));
6468 }
6469 }
6470 }
6471
6472 return Promise.all(tasks);
6473 }
6474 });
6475
6476 /**
6477 * @class NamedSection
6478 * @memberof LuCI.form
6479 * @augments LuCI.form.AbstractSection
6480 * @hideconstructor
6481 * @classdesc
6482 *
6483 * The `NamedSection` class maps exactly one UCI section instance which is
6484 * specified when constructing the class instance.
6485 *
6486 * Layout and functionality wise, a named section is essentially a
6487 * `TypedSection` which allows exactly one section node.
6488 *
6489 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
6490 * The configuration form this section is added to. It is automatically passed
6491 * by [section()]{@link LuCI.form.Map#section}.
6492 *
6493 * @param {string} section_id
6494 * The name (ID) of the UCI section to map.
6495 *
6496 * @param {string} section_type
6497 * The type of the UCI section to map.
6498 *
6499 * @param {string} [title]
6500 * The title caption of the form section element.
6501 *
6502 * @param {string} [description]
6503 * The description text of the form section element.
6504 */
6505 var CBINamedSection = CBIAbstractSection.extend(/** @lends LuCI.form.NamedSection.prototype */ {
6506 __name__: 'CBI.NamedSection',
6507 __init__: function(map, section_id /*, ... */) {
6508 this.super('__init__', this.varargs(arguments, 2, map));
6509
6510 this.section = section_id;
6511 },
6512
6513 /**
6514 * If set to `true`, the user may remove or recreate the sole mapped
6515 * configuration instance from the form section widget, otherwise only a
6516 * preexisting section may be edited. The default is `false`.
6517 *
6518 * @name LuCI.form.NamedSection.prototype#addremove
6519 * @type boolean
6520 * @default false
6521 */
6522
6523 /**
6524 * Override the UCI configuration name to read the section IDs from. By
6525 * default, the configuration name is inherited from the parent `Map`.
6526 * By setting this property, a deviating configuration may be specified.
6527 * The default is `null`, means inheriting from the parent form.
6528 *
6529 * @name LuCI.form.NamedSection.prototype#uciconfig
6530 * @type string
6531 * @default null
6532 */
6533
6534 /**
6535 * The `NamedSection` class overwrites the generic `cfgsections()`
6536 * implementation to return a one-element array containing the mapped
6537 * section ID as sole element. User code should not normally change this.
6538 *
6539 * @returns {string[]}
6540 * Returns a one-element array containing the mapped section ID.
6541 */
6542 cfgsections: function() {
6543 return [ this.section ];
6544 },
6545
6546 /** @private */
6547 handleAdd: function(ev) {
6548 var section_id = this.section,
6549 config_name = this.uciconfig || this.map.config;
6550
6551 this.map.data.add(config_name, this.sectiontype, section_id);
6552 return this.map.save(null, true);
6553 },
6554
6555 /** @private */
6556 handleRemove: function(ev) {
6557 var section_id = this.section,
6558 config_name = this.uciconfig || this.map.config;
6559
6560 this.map.data.remove(config_name, section_id);
6561 return this.map.save(null, true);
6562 },
6563
6564 /** @private */
6565 renderContents: function(data) {
6566 var ucidata = data[0], nodes = data[1],
6567 section_id = this.section,
6568 config_name = this.uciconfig || this.map.config,
6569 sectionEl = E('div', {
6570 'id': ucidata ? null : 'cbi-%s-%s'.format(config_name, section_id),
6571 'class': 'cbi-section',
6572 'data-tab': (this.map.tabbed &amp;&amp; !this.parentoption) ? this.sectiontype : null,
6573 'data-tab-title': (this.map.tabbed &amp;&amp; !this.parentoption) ? this.title || this.sectiontype : null
6574 });
6575
6576 if (typeof(this.title) === 'string' &amp;&amp; this.title !== '')
6577 sectionEl.appendChild(E('legend', {}, this.title));
6578
6579 if (typeof(this.description) === 'string' &amp;&amp; this.description !== '')
6580 sectionEl.appendChild(E('div', { 'class': 'cbi-section-descr' }, this.description));
6581
6582 if (ucidata) {
6583 if (this.addremove) {
6584 sectionEl.appendChild(
6585 E('div', { 'class': 'cbi-section-remove right' },
6586 E('button', {
6587 'class': 'cbi-button',
6588 'click': ui.createHandlerFn(this, 'handleRemove'),
6589 'disabled': this.map.readonly || null
6590 }, [ _('Delete') ])));
6591 }
6592
6593 sectionEl.appendChild(E('div', {
6594 'id': 'cbi-%s-%s'.format(config_name, section_id),
6595 'class': this.tabs
6596 ? 'cbi-section-node cbi-section-node-tabbed' : 'cbi-section-node',
6597 'data-section-id': section_id
6598 }, nodes));
6599 }
6600 else if (this.addremove) {
6601 sectionEl.appendChild(
6602 E('button', {
6603 'class': 'cbi-button cbi-button-add',
6604 'click': ui.createHandlerFn(this, 'handleAdd'),
6605 'disabled': this.map.readonly || null
6606 }, [ _('Add') ]));
6607 }
6608
6609 dom.bindClassInstance(sectionEl, this);
6610
6611 return sectionEl;
6612 },
6613
6614 /** @override */
6615 render: function() {
6616 var config_name = this.uciconfig || this.map.config,
6617 section_id = this.section;
6618
6619 return Promise.all([
6620 this.map.data.get(config_name, section_id),
6621 this.renderUCISection(section_id)
6622 ]).then(this.renderContents.bind(this));
6623 }
6624 });
6625
6626 /**
6627 * @class Value
6628 * @memberof LuCI.form
6629 * @augments LuCI.form.AbstractValue
6630 * @hideconstructor
6631 * @classdesc
6632 *
6633 * The `Value` class represents a simple one-line form input using the
6634 * {@link LuCI.ui.Textfield} or - in case choices are added - the
6635 * {@link LuCI.ui.Combobox} class as underlying widget.
6636 *
6637 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
6638 * The configuration form this section is added to. It is automatically passed
6639 * by [option()]{@link LuCI.form.AbstractSection#option} or
6640 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6641 * option to the section.
6642 *
6643 * @param {LuCI.form.AbstractSection} section
6644 * The configuration section this option is added to. It is automatically passed
6645 * by [option()]{@link LuCI.form.AbstractSection#option} or
6646 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6647 * option to the section.
6648 *
6649 * @param {string} option
6650 * The name of the UCI option to map.
6651 *
6652 * @param {string} [title]
6653 * The title caption of the option element.
6654 *
6655 * @param {string} [description]
6656 * The description text of the option element.
6657 */
6658 var CBIValue = CBIAbstractValue.extend(/** @lends LuCI.form.Value.prototype */ {
6659 __name__: 'CBI.Value',
6660
6661 /**
6662 * If set to `true`, the field is rendered as password input, otherwise
6663 * as plain text input.
6664 *
6665 * @name LuCI.form.Value.prototype#password
6666 * @type boolean
6667 * @default false
6668 */
6669
6670 /**
6671 * Set a placeholder string to use when the input field is empty.
6672 *
6673 * @name LuCI.form.Value.prototype#placeholder
6674 * @type string
6675 * @default null
6676 */
6677
6678 /**
6679 * Add a predefined choice to the form option. By adding one or more
6680 * choices, the plain text input field is turned into a combobox widget
6681 * which prompts the user to select a predefined choice, or to enter a
6682 * custom value.
6683 *
6684 * @param {string} key
6685 * The choice value to add.
6686 *
6687 * @param {Node|string} value
6688 * The caption for the choice value. May be a DOM node, a document fragment
6689 * or a plain text string. If omitted, the `key` value is used as caption.
6690 */
6691 value: function(key, val) {
6692 this.keylist = this.keylist || [];
6693 this.keylist.push(String(key));
6694
6695 this.vallist = this.vallist || [];
6696 this.vallist.push(dom.elem(val) ? val : String(val != null ? val : key));
6697 },
6698
6699 /** @override */
6700 render: function(option_index, section_id, in_table) {
6701 return Promise.resolve(this.cfgvalue(section_id))
6702 .then(this.renderWidget.bind(this, section_id, option_index))
6703 .then(this.renderFrame.bind(this, section_id, in_table, option_index));
6704 },
6705
6706 /** @private */
6707 handleValueChange: function(section_id, state, ev) {
6708 if (typeof(this.onchange) != 'function')
6709 return;
6710
6711 var value = this.formvalue(section_id);
6712
6713 if (isEqual(value, state.previousValue))
6714 return;
6715
6716 state.previousValue = value;
6717 this.onchange.call(this, ev, section_id, value);
6718 },
6719
6720 /** @private */
6721 renderFrame: function(section_id, in_table, option_index, nodes) {
6722 var config_name = this.uciconfig || this.section.uciconfig || this.map.config,
6723 depend_list = this.transformDepList(section_id),
6724 optionEl;
6725
6726 if (in_table) {
6727 var title = this.stripTags(this.title).trim();
6728 optionEl = E('div', {
6729 'class': 'td cbi-value-field',
6730 'data-title': (title != '') ? title : null,
6731 'data-description': this.stripTags(this.description).trim(),
6732 'data-name': this.option,
6733 'data-widget': this.typename || (this.template ? this.template.replace(/^.+\//, '') : null) || this.__name__
6734 }, E('div', {
6735 'id': 'cbi-%s-%s-%s'.format(config_name, section_id, this.option),
6736 'data-index': option_index,
6737 'data-depends': depend_list,
6738 'data-field': this.cbid(section_id)
6739 }));
6740 }
6741 else {
6742 optionEl = E('div', {
6743 'class': 'cbi-value',
6744 'id': 'cbi-%s-%s-%s'.format(config_name, section_id, this.option),
6745 'data-index': option_index,
6746 'data-depends': depend_list,
6747 'data-field': this.cbid(section_id),
6748 'data-name': this.option,
6749 'data-widget': this.typename || (this.template ? this.template.replace(/^.+\//, '') : null) || this.__name__
6750 });
6751
6752 if (this.last_child)
6753 optionEl.classList.add('cbi-value-last');
6754
6755 if (typeof(this.title) === 'string' &amp;&amp; this.title !== '') {
6756 optionEl.appendChild(E('label', {
6757 'class': 'cbi-value-title',
6758 'for': 'widget.cbid.%s.%s.%s'.format(config_name, section_id, this.option),
6759 'click': function(ev) {
6760 var node = ev.currentTarget,
6761 elem = node.nextElementSibling.querySelector('#' + node.getAttribute('for')) || node.nextElementSibling.querySelector('[data-widget-id="' + node.getAttribute('for') + '"]');
6762
6763 if (elem) {
6764 elem.click();
6765 elem.focus();
6766 }
6767 }
6768 },
6769 this.titleref ? E('a', {
6770 'class': 'cbi-title-ref',
6771 'href': this.titleref,
6772 'title': this.titledesc || _('Go to relevant configuration page')
6773 }, this.title) : this.title));
6774
6775 optionEl.appendChild(E('div', { 'class': 'cbi-value-field' }));
6776 }
6777 }
6778
6779 if (nodes)
6780 (optionEl.lastChild || optionEl).appendChild(nodes);
6781
6782 if (!in_table &amp;&amp; typeof(this.description) === 'string' &amp;&amp; this.description !== '')
6783 dom.append(optionEl.lastChild || optionEl,
6784 E('div', { 'class': 'cbi-value-description' }, this.description));
6785
6786 if (depend_list &amp;&amp; depend_list.length)
6787 optionEl.classList.add('hidden');
6788
6789 optionEl.addEventListener('widget-change',
6790 L.bind(this.handleValueChange, this, section_id, {}));
6791
6792 optionEl.addEventListener('widget-change',
6793 L.bind(this.map.checkDepends, this.map));
6794
6795 dom.bindClassInstance(optionEl, this);
6796
6797 return optionEl;
6798 },
6799
6800 /** @private */
6801 renderWidget: function(section_id, option_index, cfgvalue) {
6802 var value = (cfgvalue != null) ? cfgvalue : this.default,
6803 choices = this.transformChoices(),
6804 widget;
6805
6806 if (choices) {
6807 var placeholder = (this.optional || this.rmempty)
6808 ? E('em', _('unspecified')) : _('-- Please choose --');
6809
6810 widget = new ui.Combobox(Array.isArray(value) ? value.join(' ') : value, choices, {
6811 id: this.cbid(section_id),
6812 sort: this.keylist,
6813 optional: this.optional || this.rmempty,
6814 datatype: this.datatype,
6815 select_placeholder: this.placeholder || placeholder,
6816 validate: L.bind(this.validate, this, section_id),
6817 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
6818 });
6819 }
6820 else {
6821 widget = new ui.Textfield(Array.isArray(value) ? value.join(' ') : value, {
6822 id: this.cbid(section_id),
6823 password: this.password,
6824 optional: this.optional || this.rmempty,
6825 datatype: this.datatype,
6826 placeholder: this.placeholder,
6827 validate: L.bind(this.validate, this, section_id),
6828 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
6829 });
6830 }
6831
6832 return widget.render();
6833 }
6834 });
6835
6836 /**
6837 * @class DynamicList
6838 * @memberof LuCI.form
6839 * @augments LuCI.form.Value
6840 * @hideconstructor
6841 * @classdesc
6842 *
6843 * The `DynamicList` class represents a multi value widget allowing the user
6844 * to enter multiple unique values, optionally selected from a set of
6845 * predefined choices. It builds upon the {@link LuCI.ui.DynamicList} widget.
6846 *
6847 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
6848 * The configuration form this section is added to. It is automatically passed
6849 * by [option()]{@link LuCI.form.AbstractSection#option} or
6850 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6851 * option to the section.
6852 *
6853 * @param {LuCI.form.AbstractSection} section
6854 * The configuration section this option is added to. It is automatically passed
6855 * by [option()]{@link LuCI.form.AbstractSection#option} or
6856 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6857 * option to the section.
6858 *
6859 * @param {string} option
6860 * The name of the UCI option to map.
6861 *
6862 * @param {string} [title]
6863 * The title caption of the option element.
6864 *
6865 * @param {string} [description]
6866 * The description text of the option element.
6867 */
6868 var CBIDynamicList = CBIValue.extend(/** @lends LuCI.form.DynamicList.prototype */ {
6869 __name__: 'CBI.DynamicList',
6870
6871 /** @private */
6872 renderWidget: function(section_id, option_index, cfgvalue) {
6873 var value = (cfgvalue != null) ? cfgvalue : this.default,
6874 choices = this.transformChoices(),
6875 items = L.toArray(value);
6876
6877 var widget = new ui.DynamicList(items, choices, {
6878 id: this.cbid(section_id),
6879 sort: this.keylist,
6880 optional: this.optional || this.rmempty,
6881 datatype: this.datatype,
6882 placeholder: this.placeholder,
6883 validate: L.bind(this.validate, this, section_id),
6884 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
6885 });
6886
6887 return widget.render();
6888 },
6889 });
6890
6891 /**
6892 * @class ListValue
6893 * @memberof LuCI.form
6894 * @augments LuCI.form.Value
6895 * @hideconstructor
6896 * @classdesc
6897 *
6898 * The `ListValue` class implements a simple static HTML select element
6899 * allowing the user to chose a single value from a set of predefined choices.
6900 * It builds upon the {@link LuCI.ui.Select} widget.
6901 *
6902 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
6903 * The configuration form this section is added to. It is automatically passed
6904 * by [option()]{@link LuCI.form.AbstractSection#option} or
6905 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6906 * option to the section.
6907 *
6908 * @param {LuCI.form.AbstractSection} section
6909 * The configuration section this option is added to. It is automatically passed
6910 * by [option()]{@link LuCI.form.AbstractSection#option} or
6911 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6912 * option to the section.
6913 *
6914 * @param {string} option
6915 * The name of the UCI option to map.
6916 *
6917 * @param {string} [title]
6918 * The title caption of the option element.
6919 *
6920 * @param {string} [description]
6921 * The description text of the option element.
6922 */
6923 var CBIListValue = CBIValue.extend(/** @lends LuCI.form.ListValue.prototype */ {
6924 __name__: 'CBI.ListValue',
6925
6926 __init__: function() {
6927 this.super('__init__', arguments);
6928 this.widget = 'select';
6929 this.orientation = 'horizontal';
6930 this.deplist = [];
6931 },
6932
6933 /**
6934 * Set the size attribute of the underlying HTML select element.
6935 *
6936 * @name LuCI.form.ListValue.prototype#size
6937 * @type number
6938 * @default null
6939 */
6940
6941 /**
6942 * Set the type of the underlying form controls.
6943 *
6944 * May be one of `select` or `radio`. If set to `select`, an HTML
6945 * select element is rendered, otherwise a collection of `radio`
6946 * elements is used.
6947 *
6948 * @name LuCI.form.ListValue.prototype#widget
6949 * @type string
6950 * @default select
6951 */
6952
6953 /**
6954 * Set the orientation of the underlying radio or checkbox elements.
6955 *
6956 * May be one of `horizontal` or `vertical`. Only applies to non-select
6957 * widget types.
6958 *
6959 * @name LuCI.form.ListValue.prototype#orientation
6960 * @type string
6961 * @default horizontal
6962 */
6963
6964 /** @private */
6965 renderWidget: function(section_id, option_index, cfgvalue) {
6966 var choices = this.transformChoices();
6967 var widget = new ui.Select((cfgvalue != null) ? cfgvalue : this.default, choices, {
6968 id: this.cbid(section_id),
6969 size: this.size,
6970 sort: this.keylist,
6971 widget: this.widget,
6972 optional: this.optional,
6973 orientation: this.orientation,
6974 placeholder: this.placeholder,
6975 validate: L.bind(this.validate, this, section_id),
6976 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
6977 });
6978
6979 return widget.render();
6980 },
6981 });
6982
6983 /**
6984 * @class FlagValue
6985 * @memberof LuCI.form
6986 * @augments LuCI.form.Value
6987 * @hideconstructor
6988 * @classdesc
6989 *
6990 * The `FlagValue` element builds upon the {@link LuCI.ui.Checkbox} widget to
6991 * implement a simple checkbox element.
6992 *
6993 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
6994 * The configuration form this section is added to. It is automatically passed
6995 * by [option()]{@link LuCI.form.AbstractSection#option} or
6996 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
6997 * option to the section.
6998 *
6999 * @param {LuCI.form.AbstractSection} section
7000 * The configuration section this option is added to. It is automatically passed
7001 * by [option()]{@link LuCI.form.AbstractSection#option} or
7002 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7003 * option to the section.
7004 *
7005 * @param {string} option
7006 * The name of the UCI option to map.
7007 *
7008 * @param {string} [title]
7009 * The title caption of the option element.
7010 *
7011 * @param {string} [description]
7012 * The description text of the option element.
7013 */
7014 var CBIFlagValue = CBIValue.extend(/** @lends LuCI.form.FlagValue.prototype */ {
7015 __name__: 'CBI.FlagValue',
7016
7017 __init__: function() {
7018 this.super('__init__', arguments);
7019
7020 this.enabled = '1';
7021 this.disabled = '0';
7022 this.default = this.disabled;
7023 },
7024
7025 /**
7026 * Sets the input value to use for the checkbox checked state.
7027 *
7028 * @name LuCI.form.FlagValue.prototype#enabled
7029 * @type number
7030 * @default 1
7031 */
7032
7033 /**
7034 * Sets the input value to use for the checkbox unchecked state.
7035 *
7036 * @name LuCI.form.FlagValue.prototype#disabled
7037 * @type number
7038 * @default 0
7039 */
7040
7041 /** @private */
7042 renderWidget: function(section_id, option_index, cfgvalue) {
7043 var widget = new ui.Checkbox((cfgvalue != null) ? cfgvalue : this.default, {
7044 id: this.cbid(section_id),
7045 value_enabled: this.enabled,
7046 value_disabled: this.disabled,
7047 validate: L.bind(this.validate, this, section_id),
7048 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
7049 });
7050
7051 return widget.render();
7052 },
7053
7054 /**
7055 * Query the checked state of the underlying checkbox widget and return
7056 * either the `enabled` or the `disabled` property value, depending on
7057 * the checked state.
7058 *
7059 * @override
7060 */
7061 formvalue: function(section_id) {
7062 var elem = this.getUIElement(section_id),
7063 checked = elem ? elem.isChecked() : false;
7064 return checked ? this.enabled : this.disabled;
7065 },
7066
7067 /**
7068 * Query the checked state of the underlying checkbox widget and return
7069 * either a localized `Yes` or `No` string, depending on the checked state.
7070 *
7071 * @override
7072 */
7073 textvalue: function(section_id) {
7074 var cval = this.cfgvalue(section_id);
7075
7076 if (cval == null)
7077 cval = this.default;
7078
7079 return (cval == this.enabled) ? _('Yes') : _('No');
7080 },
7081
7082 /** @override */
7083 parse: function(section_id) {
7084 if (this.isActive(section_id)) {
7085 var fval = this.formvalue(section_id);
7086
7087 if (!this.isValid(section_id)) {
7088 var title = this.stripTags(this.title).trim();
7089 return Promise.reject(new TypeError(_('Option "%s" contains an invalid input value.').format(title || this.option)));
7090 }
7091
7092 if (fval == this.default &amp;&amp; (this.optional || this.rmempty))
7093 return Promise.resolve(this.remove(section_id));
7094 else
7095 return Promise.resolve(this.write(section_id, fval));
7096 }
7097 else {
7098 return Promise.resolve(this.remove(section_id));
7099 }
7100 },
7101 });
7102
7103 /**
7104 * @class MultiValue
7105 * @memberof LuCI.form
7106 * @augments LuCI.form.DynamicList
7107 * @hideconstructor
7108 * @classdesc
7109 *
7110 * The `MultiValue` class is a modified variant of the `DynamicList` element
7111 * which leverages the {@link LuCI.ui.Dropdown} widget to implement a multi
7112 * select dropdown element.
7113 *
7114 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7115 * The configuration form this section is added to. It is automatically passed
7116 * by [option()]{@link LuCI.form.AbstractSection#option} or
7117 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7118 * option to the section.
7119 *
7120 * @param {LuCI.form.AbstractSection} section
7121 * The configuration section this option is added to. It is automatically passed
7122 * by [option()]{@link LuCI.form.AbstractSection#option} or
7123 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7124 * option to the section.
7125 *
7126 * @param {string} option
7127 * The name of the UCI option to map.
7128 *
7129 * @param {string} [title]
7130 * The title caption of the option element.
7131 *
7132 * @param {string} [description]
7133 * The description text of the option element.
7134 */
7135 var CBIMultiValue = CBIDynamicList.extend(/** @lends LuCI.form.MultiValue.prototype */ {
7136 __name__: 'CBI.MultiValue',
7137
7138 __init__: function() {
7139 this.super('__init__', arguments);
7140 this.placeholder = _('-- Please choose --');
7141 },
7142
7143 /**
7144 * Allows to specify the [display_items]{@link LuCI.ui.Dropdown.InitOptions}
7145 * property of the underlying dropdown widget. If omitted, the value of
7146 * the `size` property is used or `3` when `size` is unspecified as well.
7147 *
7148 * @name LuCI.form.MultiValue.prototype#display_size
7149 * @type number
7150 * @default null
7151 */
7152
7153 /**
7154 * Allows to specify the [dropdown_items]{@link LuCI.ui.Dropdown.InitOptions}
7155 * property of the underlying dropdown widget. If omitted, the value of
7156 * the `size` property is used or `-1` when `size` is unspecified as well.
7157 *
7158 * @name LuCI.form.MultiValue.prototype#dropdown_size
7159 * @type number
7160 * @default null
7161 */
7162
7163 /** @private */
7164 renderWidget: function(section_id, option_index, cfgvalue) {
7165 var value = (cfgvalue != null) ? cfgvalue : this.default,
7166 choices = this.transformChoices();
7167
7168 var widget = new ui.Dropdown(L.toArray(value), choices, {
7169 id: this.cbid(section_id),
7170 sort: this.keylist,
7171 multiple: true,
7172 optional: this.optional || this.rmempty,
7173 select_placeholder: this.placeholder,
7174 display_items: this.display_size || this.size || 3,
7175 dropdown_items: this.dropdown_size || this.size || -1,
7176 validate: L.bind(this.validate, this, section_id),
7177 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
7178 });
7179
7180 return widget.render();
7181 },
7182 });
7183
7184 /**
7185 * @class TextValue
7186 * @memberof LuCI.form
7187 * @augments LuCI.form.Value
7188 * @hideconstructor
7189 * @classdesc
7190 *
7191 * The `TextValue` class implements a multi-line textarea input using
7192 * {@link LuCI.ui.Textarea}.
7193 *
7194 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7195 * The configuration form this section is added to. It is automatically passed
7196 * by [option()]{@link LuCI.form.AbstractSection#option} or
7197 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7198 * option to the section.
7199 *
7200 * @param {LuCI.form.AbstractSection} section
7201 * The configuration section this option is added to. It is automatically passed
7202 * by [option()]{@link LuCI.form.AbstractSection#option} or
7203 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7204 * option to the section.
7205 *
7206 * @param {string} option
7207 * The name of the UCI option to map.
7208 *
7209 * @param {string} [title]
7210 * The title caption of the option element.
7211 *
7212 * @param {string} [description]
7213 * The description text of the option element.
7214 */
7215 var CBITextValue = CBIValue.extend(/** @lends LuCI.form.TextValue.prototype */ {
7216 __name__: 'CBI.TextValue',
7217
7218 /** @ignore */
7219 value: null,
7220
7221 /**
7222 * Enforces the use of a monospace font for the textarea contents when set
7223 * to `true`.
7224 *
7225 * @name LuCI.form.TextValue.prototype#monospace
7226 * @type boolean
7227 * @default false
7228 */
7229
7230 /**
7231 * Allows to specify the [cols]{@link LuCI.ui.Textarea.InitOptions}
7232 * property of the underlying textarea widget.
7233 *
7234 * @name LuCI.form.TextValue.prototype#cols
7235 * @type number
7236 * @default null
7237 */
7238
7239 /**
7240 * Allows to specify the [rows]{@link LuCI.ui.Textarea.InitOptions}
7241 * property of the underlying textarea widget.
7242 *
7243 * @name LuCI.form.TextValue.prototype#rows
7244 * @type number
7245 * @default null
7246 */
7247
7248 /**
7249 * Allows to specify the [wrap]{@link LuCI.ui.Textarea.InitOptions}
7250 * property of the underlying textarea widget.
7251 *
7252 * @name LuCI.form.TextValue.prototype#wrap
7253 * @type number
7254 * @default null
7255 */
7256
7257 /** @private */
7258 renderWidget: function(section_id, option_index, cfgvalue) {
7259 var value = (cfgvalue != null) ? cfgvalue : this.default;
7260
7261 var widget = new ui.Textarea(value, {
7262 id: this.cbid(section_id),
7263 optional: this.optional || this.rmempty,
7264 placeholder: this.placeholder,
7265 monospace: this.monospace,
7266 cols: this.cols,
7267 rows: this.rows,
7268 wrap: this.wrap,
7269 validate: L.bind(this.validate, this, section_id),
7270 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
7271 });
7272
7273 return widget.render();
7274 }
7275 });
7276
7277 /**
7278 * @class DummyValue
7279 * @memberof LuCI.form
7280 * @augments LuCI.form.Value
7281 * @hideconstructor
7282 * @classdesc
7283 *
7284 * The `DummyValue` element wraps an {@link LuCI.ui.Hiddenfield} widget and
7285 * renders the underlying UCI option or default value as readonly text.
7286 *
7287 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7288 * The configuration form this section is added to. It is automatically passed
7289 * by [option()]{@link LuCI.form.AbstractSection#option} or
7290 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7291 * option to the section.
7292 *
7293 * @param {LuCI.form.AbstractSection} section
7294 * The configuration section this option is added to. It is automatically passed
7295 * by [option()]{@link LuCI.form.AbstractSection#option} or
7296 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7297 * option to the section.
7298 *
7299 * @param {string} option
7300 * The name of the UCI option to map.
7301 *
7302 * @param {string} [title]
7303 * The title caption of the option element.
7304 *
7305 * @param {string} [description]
7306 * The description text of the option element.
7307 */
7308 var CBIDummyValue = CBIValue.extend(/** @lends LuCI.form.DummyValue.prototype */ {
7309 __name__: 'CBI.DummyValue',
7310
7311 /**
7312 * Set an URL which is opened when clicking on the dummy value text.
7313 *
7314 * By setting this property, the dummy value text is wrapped in an `&lt;a>`
7315 * element with the property value used as `href` attribute.
7316 *
7317 * @name LuCI.form.DummyValue.prototype#href
7318 * @type string
7319 * @default null
7320 */
7321
7322 /**
7323 * Treat the UCI option value (or the `default` property value) as HTML.
7324 *
7325 * By default, the value text is HTML escaped before being rendered as
7326 * text. In some cases it may be needed to actually interpret and render
7327 * HTML contents as-is. When set to `true`, HTML escaping is disabled.
7328 *
7329 * @name LuCI.form.DummyValue.prototype#rawhtml
7330 * @type boolean
7331 * @default null
7332 */
7333
7334 /** @private */
7335 renderWidget: function(section_id, option_index, cfgvalue) {
7336 var value = (cfgvalue != null) ? cfgvalue : this.default,
7337 hiddenEl = new ui.Hiddenfield(value, { id: this.cbid(section_id) }),
7338 outputEl = E('div');
7339
7340 if (this.href &amp;&amp; !((this.readonly != null) ? this.readonly : this.map.readonly))
7341 outputEl.appendChild(E('a', { 'href': this.href }));
7342
7343 dom.append(outputEl.lastChild || outputEl,
7344 this.rawhtml ? value : [ value ]);
7345
7346 return E([
7347 outputEl,
7348 hiddenEl.render()
7349 ]);
7350 },
7351
7352 /** @override */
7353 remove: function() {},
7354
7355 /** @override */
7356 write: function() {}
7357 });
7358
7359 /**
7360 * @class ButtonValue
7361 * @memberof LuCI.form
7362 * @augments LuCI.form.Value
7363 * @hideconstructor
7364 * @classdesc
7365 *
7366 * The `DummyValue` element wraps an {@link LuCI.ui.Hiddenfield} widget and
7367 * renders the underlying UCI option or default value as readonly text.
7368 *
7369 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7370 * The configuration form this section is added to. It is automatically passed
7371 * by [option()]{@link LuCI.form.AbstractSection#option} or
7372 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7373 * option to the section.
7374 *
7375 * @param {LuCI.form.AbstractSection} section
7376 * The configuration section this option is added to. It is automatically passed
7377 * by [option()]{@link LuCI.form.AbstractSection#option} or
7378 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7379 * option to the section.
7380 *
7381 * @param {string} option
7382 * The name of the UCI option to map.
7383 *
7384 * @param {string} [title]
7385 * The title caption of the option element.
7386 *
7387 * @param {string} [description]
7388 * The description text of the option element.
7389 */
7390 var CBIButtonValue = CBIValue.extend(/** @lends LuCI.form.ButtonValue.prototype */ {
7391 __name__: 'CBI.ButtonValue',
7392
7393 /**
7394 * Override the rendered button caption.
7395 *
7396 * By default, the option title - which is passed as fourth argument to the
7397 * constructor - is used as caption for the button element. When setting
7398 * this property to a string, it is used as `String.format()` pattern with
7399 * the underlying UCI section name passed as first format argument. When
7400 * set to a function, it is invoked passing the section ID as sole argument
7401 * and the resulting return value is converted to a string before being
7402 * used as button caption.
7403 *
7404 * The default is `null`, means the option title is used as caption.
7405 *
7406 * @name LuCI.form.ButtonValue.prototype#inputtitle
7407 * @type string|function
7408 * @default null
7409 */
7410
7411 /**
7412 * Override the button style class.
7413 *
7414 * By setting this property, a specific `cbi-button-*` CSS class can be
7415 * selected to influence the style of the resulting button.
7416 *
7417 * Suitable values which are implemented by most themes are `positive`,
7418 * `negative` and `primary`.
7419 *
7420 * The default is `null`, means a neutral button styling is used.
7421 *
7422 * @name LuCI.form.ButtonValue.prototype#inputstyle
7423 * @type string
7424 * @default null
7425 */
7426
7427 /**
7428 * Override the button click action.
7429 *
7430 * By default, the underlying UCI option (or default property) value is
7431 * copied into a hidden field tied to the button element and the save
7432 * action is triggered on the parent form element.
7433 *
7434 * When this property is set to a function, it is invoked instead of
7435 * performing the default actions. The handler function will receive the
7436 * DOM click element as first and the underlying configuration section ID
7437 * as second argument.
7438 *
7439 * @name LuCI.form.ButtonValue.prototype#onclick
7440 * @type function
7441 * @default null
7442 */
7443
7444 /** @private */
7445 renderWidget: function(section_id, option_index, cfgvalue) {
7446 var value = (cfgvalue != null) ? cfgvalue : this.default,
7447 hiddenEl = new ui.Hiddenfield(value, { id: this.cbid(section_id) }),
7448 outputEl = E('div'),
7449 btn_title = this.titleFn('inputtitle', section_id) || this.titleFn('title', section_id);
7450
7451 if (value !== false)
7452 dom.content(outputEl, [
7453 E('button', {
7454 'class': 'cbi-button cbi-button-%s'.format(this.inputstyle || 'button'),
7455 'click': ui.createHandlerFn(this, function(section_id, ev) {
7456 if (this.onclick)
7457 return this.onclick(ev, section_id);
7458
7459 ev.currentTarget.parentNode.nextElementSibling.value = value;
7460 return this.map.save();
7461 }, section_id),
7462 'disabled': ((this.readonly != null) ? this.readonly : this.map.readonly) || null
7463 }, [ btn_title ])
7464 ]);
7465 else
7466 dom.content(outputEl, ' - ');
7467
7468 return E([
7469 outputEl,
7470 hiddenEl.render()
7471 ]);
7472 }
7473 });
7474
7475 /**
7476 * @class HiddenValue
7477 * @memberof LuCI.form
7478 * @augments LuCI.form.Value
7479 * @hideconstructor
7480 * @classdesc
7481 *
7482 * The `HiddenValue` element wraps an {@link LuCI.ui.Hiddenfield} widget.
7483 *
7484 * Hidden value widgets used to be necessary in legacy code which actually
7485 * submitted the underlying HTML form the server. With client side handling of
7486 * forms, there are more efficient ways to store hidden state data.
7487 *
7488 * Since this widget has no visible content, the title and description values
7489 * of this form element should be set to `null` as well to avoid a broken or
7490 * distorted form layout when rendering the option element.
7491 *
7492 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7493 * The configuration form this section is added to. It is automatically passed
7494 * by [option()]{@link LuCI.form.AbstractSection#option} or
7495 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7496 * option to the section.
7497 *
7498 * @param {LuCI.form.AbstractSection} section
7499 * The configuration section this option is added to. It is automatically passed
7500 * by [option()]{@link LuCI.form.AbstractSection#option} or
7501 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7502 * option to the section.
7503 *
7504 * @param {string} option
7505 * The name of the UCI option to map.
7506 *
7507 * @param {string} [title]
7508 * The title caption of the option element.
7509 *
7510 * @param {string} [description]
7511 * The description text of the option element.
7512 */
7513 var CBIHiddenValue = CBIValue.extend(/** @lends LuCI.form.HiddenValue.prototype */ {
7514 __name__: 'CBI.HiddenValue',
7515
7516 /** @private */
7517 renderWidget: function(section_id, option_index, cfgvalue) {
7518 var widget = new ui.Hiddenfield((cfgvalue != null) ? cfgvalue : this.default, {
7519 id: this.cbid(section_id)
7520 });
7521
7522 return widget.render();
7523 }
7524 });
7525
7526 /**
7527 * @class FileUpload
7528 * @memberof LuCI.form
7529 * @augments LuCI.form.Value
7530 * @hideconstructor
7531 * @classdesc
7532 *
7533 * The `FileUpload` element wraps an {@link LuCI.ui.FileUpload} widget and
7534 * offers the ability to browse, upload and select remote files.
7535 *
7536 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7537 * The configuration form this section is added to. It is automatically passed
7538 * by [option()]{@link LuCI.form.AbstractSection#option} or
7539 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7540 * option to the section.
7541 *
7542 * @param {LuCI.form.AbstractSection} section
7543 * The configuration section this option is added to. It is automatically passed
7544 * by [option()]{@link LuCI.form.AbstractSection#option} or
7545 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7546 * option to the section.
7547 *
7548 * @param {string} option
7549 * The name of the UCI option to map.
7550 *
7551 * @param {string} [title]
7552 * The title caption of the option element.
7553 *
7554 * @param {string} [description]
7555 * The description text of the option element.
7556 */
7557 var CBIFileUpload = CBIValue.extend(/** @lends LuCI.form.FileUpload.prototype */ {
7558 __name__: 'CBI.FileSelect',
7559
7560 __init__: function(/* ... */) {
7561 this.super('__init__', arguments);
7562
7563 this.show_hidden = false;
7564 this.enable_upload = true;
7565 this.enable_remove = true;
7566 this.root_directory = '/etc/luci-uploads';
7567 },
7568
7569 /**
7570 * Toggle display of hidden files.
7571 *
7572 * Display hidden files when rendering the remote directory listing.
7573 * Note that this is merely a cosmetic feature, hidden files are always
7574 * included in received remote file listings.
7575 *
7576 * The default is `false`, means hidden files are not displayed.
7577 *
7578 * @name LuCI.form.FileUpload.prototype#show_hidden
7579 * @type boolean
7580 * @default false
7581 */
7582
7583 /**
7584 * Toggle file upload functionality.
7585 *
7586 * When set to `true`, the underlying widget provides a button which lets
7587 * the user select and upload local files to the remote system.
7588 * Note that this is merely a cosmetic feature, remote upload access is
7589 * controlled by the session ACL rules.
7590 *
7591 * The default is `true`, means file upload functionality is displayed.
7592 *
7593 * @name LuCI.form.FileUpload.prototype#enable_upload
7594 * @type boolean
7595 * @default true
7596 */
7597
7598 /**
7599 * Toggle remote file delete functionality.
7600 *
7601 * When set to `true`, the underlying widget provides a buttons which let
7602 * the user delete files from remote directories. Note that this is merely
7603 * a cosmetic feature, remote delete permissions are controlled by the
7604 * session ACL rules.
7605 *
7606 * The default is `true`, means file removal buttons are displayed.
7607 *
7608 * @name LuCI.form.FileUpload.prototype#enable_remove
7609 * @type boolean
7610 * @default true
7611 */
7612
7613 /**
7614 * Specify the root directory for file browsing.
7615 *
7616 * This property defines the topmost directory the file browser widget may
7617 * navigate to, the UI will not allow browsing directories outside this
7618 * prefix. Note that this is merely a cosmetic feature, remote file access
7619 * and directory listing permissions are controlled by the session ACL
7620 * rules.
7621 *
7622 * The default is `/etc/luci-uploads`.
7623 *
7624 * @name LuCI.form.FileUpload.prototype#root_directory
7625 * @type string
7626 * @default /etc/luci-uploads
7627 */
7628
7629 /** @private */
7630 renderWidget: function(section_id, option_index, cfgvalue) {
7631 var browserEl = new ui.FileUpload((cfgvalue != null) ? cfgvalue : this.default, {
7632 id: this.cbid(section_id),
7633 name: this.cbid(section_id),
7634 show_hidden: this.show_hidden,
7635 enable_upload: this.enable_upload,
7636 enable_remove: this.enable_remove,
7637 root_directory: this.root_directory,
7638 disabled: (this.readonly != null) ? this.readonly : this.map.readonly
7639 });
7640
7641 return browserEl.render();
7642 }
7643 });
7644
7645 /**
7646 * @class SectionValue
7647 * @memberof LuCI.form
7648 * @augments LuCI.form.Value
7649 * @hideconstructor
7650 * @classdesc
7651 *
7652 * The `SectionValue` widget embeds a form section element within an option
7653 * element container, allowing to nest form sections into other sections.
7654 *
7655 * @param {LuCI.form.Map|LuCI.form.JSONMap} form
7656 * The configuration form this section is added to. It is automatically passed
7657 * by [option()]{@link LuCI.form.AbstractSection#option} or
7658 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7659 * option to the section.
7660 *
7661 * @param {LuCI.form.AbstractSection} section
7662 * The configuration section this option is added to. It is automatically passed
7663 * by [option()]{@link LuCI.form.AbstractSection#option} or
7664 * [taboption()]{@link LuCI.form.AbstractSection#taboption} when adding the
7665 * option to the section.
7666 *
7667 * @param {string} option
7668 * The internal name of the option element holding the section. Since a section
7669 * container element does not read or write any configuration itself, the name
7670 * is only used internally and does not need to relate to any underlying UCI
7671 * option name.
7672 *
7673 * @param {LuCI.form.AbstractSection} subsection_class
7674 * The class to use for instantiating the nested section element. Note that
7675 * the class value itself is expected here, not a class instance obtained by
7676 * calling `new`. The given class argument must be a subclass of the
7677 * `AbstractSection` class.
7678 *
7679 * @param {...*} [class_args]
7680 * All further arguments are passed as-is to the subclass constructor. Refer
7681 * to the corresponding class constructor documentations for details.
7682 */
7683 var CBISectionValue = CBIValue.extend(/** @lends LuCI.form.SectionValue.prototype */ {
7684 __name__: 'CBI.ContainerValue',
7685 __init__: function(map, section, option, cbiClass /*, ... */) {
7686 this.super('__init__', [map, section, option]);
7687
7688 if (!CBIAbstractSection.isSubclass(cbiClass))
7689 throw 'Sub section must be a descendent of CBIAbstractSection';
7690
7691 this.subsection = cbiClass.instantiate(this.varargs(arguments, 4, this.map));
7692 this.subsection.parentoption = this;
7693 },
7694
7695 /**
7696 * Access the embedded section instance.
7697 *
7698 * This property holds a reference to the instantiated nested section.
7699 *
7700 * @name LuCI.form.SectionValue.prototype#subsection
7701 * @type LuCI.form.AbstractSection
7702 * @readonly
7703 */
7704
7705 /** @override */
7706 load: function(section_id) {
7707 return this.subsection.load(section_id);
7708 },
7709
7710 /** @override */
7711 parse: function(section_id) {
7712 return this.subsection.parse(section_id);
7713 },
7714
7715 /** @private */
7716 renderWidget: function(section_id, option_index, cfgvalue) {
7717 return this.subsection.render(section_id);
7718 },
7719
7720 /** @private */
7721 checkDepends: function(section_id) {
7722 this.subsection.checkDepends(section_id);
7723 return CBIValue.prototype.checkDepends.apply(this, [ section_id ]);
7724 },
7725
7726 /**
7727 * Since the section container is not rendering an own widget,
7728 * its `value()` implementation is a no-op.
7729 *
7730 * @override
7731 */
7732 value: function() {},
7733
7734 /**
7735 * Since the section container is not tied to any UCI configuration,
7736 * its `write()` implementation is a no-op.
7737 *
7738 * @override
7739 */
7740 write: function() {},
7741
7742 /**
7743 * Since the section container is not tied to any UCI configuration,
7744 * its `remove()` implementation is a no-op.
7745 *
7746 * @override
7747 */
7748 remove: function() {},
7749
7750 /**
7751 * Since the section container is not tied to any UCI configuration,
7752 * its `cfgvalue()` implementation will always return `null`.
7753 *
7754 * @override
7755 * @returns {null}
7756 */
7757 cfgvalue: function() { return null },
7758
7759 /**
7760 * Since the section container is not tied to any UCI configuration,
7761 * its `formvalue()` implementation will always return `null`.
7762 *
7763 * @override
7764 * @returns {null}
7765 */
7766 formvalue: function() { return null }
7767 });
7768
7769 /**
7770 * @class form
7771 * @memberof LuCI
7772 * @hideconstructor
7773 * @classdesc
7774 *
7775 * The LuCI form class provides high level abstractions for creating creating
7776 * UCI- or JSON backed configurations forms.
7777 *
7778 * To import the class in views, use `'require form'`, to import it in
7779 * external JavaScript, use `L.require("form").then(...)`.
7780 *
7781 * A typical form is created by first constructing a
7782 * {@link LuCI.form.Map} or {@link LuCI.form.JSONMap} instance using `new` and
7783 * by subsequently adding sections and options to it. Finally
7784 * [render()]{@link LuCI.form.Map#render} is invoked on the instance to
7785 * assemble the HTML markup and insert it into the DOM.
7786 *
7787 * Example:
7788 *
7789 * &lt;pre>
7790 * 'use strict';
7791 * 'require form';
7792 *
7793 * var m, s, o;
7794 *
7795 * m = new form.Map('example', 'Example form',
7796 * 'This is an example form mapping the contents of /etc/config/example');
7797 *
7798 * s = m.section(form.NamedSection, 'first_section', 'example', 'The first section',
7799 * 'This sections maps "config example first_section" of /etc/config/example');
7800 *
7801 * o = s.option(form.Flag, 'some_bool', 'A checkbox option');
7802 *
7803 * o = s.option(form.ListValue, 'some_choice', 'A select element');
7804 * o.value('choice1', 'The first choice');
7805 * o.value('choice2', 'The second choice');
7806 *
7807 * m.render().then(function(node) {
7808 * document.body.appendChild(node);
7809 * });
7810 * &lt;/pre>
7811 */
7812 return baseclass.extend(/** @lends LuCI.form.prototype */ {
7813 Map: CBIMap,
7814 JSONMap: CBIJSONMap,
7815 AbstractSection: CBIAbstractSection,
7816 AbstractValue: CBIAbstractValue,
7817
7818 TypedSection: CBITypedSection,
7819 TableSection: CBITableSection,
7820 GridSection: CBIGridSection,
7821 NamedSection: CBINamedSection,
7822
7823 Value: CBIValue,
7824 DynamicList: CBIDynamicList,
7825 ListValue: CBIListValue,
7826 Flag: CBIFlagValue,
7827 MultiValue: CBIMultiValue,
7828 TextValue: CBITextValue,
7829 DummyValue: CBIDummyValue,
7830 Button: CBIButtonValue,
7831 HiddenValue: CBIHiddenValue,
7832 FileUpload: CBIFileUpload,
7833 SectionValue: CBISectionValue
7834 });
7835 </code></pre>
7836 </article>
7837 </section>
7838
7839
7840
7841
7842
7843
7844
7845
7846 <footer>
7847 Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Thu Aug 06 2020 17:58:02 GMT+0200 (Central European Summer Time)
7848 </footer>
7849 </div>
7850 </div>
7851 <script>prettyPrint();</script>
7852 <script src="scripts/jaguar.js"></script>
7853 </body>
7854 </html>