247228d225b47d6a3f15a88e3ecefae176153be7
[project/luci.git] / libs / cbi / htdocs / luci-static / resources / cbi.js
1 /*
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008-2009 Jo-Philipp Wich <xm@subsignal.org>
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id$
14 */
15
16 var cbi_d = [];
17 var cbi_t = [];
18 var cbi_c = [];
19
20 function cbi_d_add(field, dep, next) {
21 var obj = document.getElementById(field);
22 if (obj) {
23 var entry
24 for (var i=0; i<cbi_d.length; i++) {
25 if (cbi_d[i].id == field) {
26 entry = cbi_d[i];
27 break;
28 }
29 }
30 if (!entry) {
31 entry = {
32 "node": obj,
33 "id": field,
34 "parent": obj.parentNode.id,
35 "next": next,
36 "deps": []
37 };
38 cbi_d.unshift(entry);
39 }
40 entry.deps.push(dep)
41 }
42 }
43
44 function cbi_d_checkvalue(target, ref) {
45 var t = document.getElementById(target);
46 var value;
47
48 if (!t) {
49 var tl = document.getElementsByName(target);
50
51 if( tl.length > 0 && tl[0].type == 'radio' )
52 for( var i = 0; i < tl.length; i++ )
53 if( tl[i].checked ) {
54 value = tl[i].value;
55 break;
56 }
57
58 value = value ? value : "";
59 } else if (!t.value) {
60 value = "";
61 } else {
62 value = t.value;
63
64 if (t.type == "checkbox") {
65 value = t.checked ? value : "";
66 }
67 }
68
69 return (value == ref)
70 }
71
72 function cbi_d_check(deps) {
73 var reverse;
74 var def = false;
75 for (var i=0; i<deps.length; i++) {
76 var istat = true;
77 reverse = false;
78 for (var j in deps[i]) {
79 if (j == "!reverse") {
80 reverse = true;
81 } else if (j == "!default") {
82 def = true;
83 istat = false;
84 } else {
85 istat = (istat && cbi_d_checkvalue(j, deps[i][j]))
86 }
87 }
88 if (istat) {
89 return !reverse;
90 }
91 }
92 return def;
93 }
94
95 function cbi_d_update() {
96 var state = false;
97 for (var i=0; i<cbi_d.length; i++) {
98 var entry = cbi_d[i];
99 var next = document.getElementById(entry.next)
100 var node = document.getElementById(entry.id)
101 var parent = document.getElementById(entry.parent)
102
103 if (node && node.parentNode && !cbi_d_check(entry.deps)) {
104 node.parentNode.removeChild(node);
105 state = true;
106 if( entry.parent )
107 cbi_c[entry.parent]--;
108 } else if ((!node || !node.parentNode) && cbi_d_check(entry.deps)) {
109 if (!next) {
110 parent.appendChild(entry.node);
111 } else {
112 next.parentNode.insertBefore(entry.node, next);
113 }
114 state = true;
115 if( entry.parent )
116 cbi_c[entry.parent]++;
117 }
118 }
119
120 if (entry.parent) {
121 cbi_t_update();
122 }
123
124 if (state) {
125 cbi_d_update();
126 }
127 }
128
129 function cbi_bind(obj, type, callback, mode) {
130 if (typeof mode == "undefined") {
131 mode = false;
132 }
133 if (!obj.addEventListener) {
134 ieCallback = function(){
135 var e = window.event;
136 if (!e.target && e.srcElement) {
137 e.target = e.srcElement;
138 };
139 e.target['_eCB' + type + callback] = callback;
140 e.target['_eCB' + type + callback](e);
141 e.target['_eCB' + type + callback] = null;
142 };
143 obj.attachEvent('on' + type, ieCallback);
144 } else {
145 obj.addEventListener(type, callback, mode);
146 }
147 return obj;
148 }
149
150 function cbi_combobox(id, values, def, man) {
151 var selid = "cbi.combobox." + id;
152 if (document.getElementById(selid)) {
153 return
154 }
155
156 var obj = document.getElementById(id)
157 var sel = document.createElement("select");
158 sel.id = selid;
159 sel.className = 'cbi-input-select';
160 if (obj.nextSibling) {
161 obj.parentNode.insertBefore(sel, obj.nextSibling);
162 } else {
163 obj.parentNode.appendChild(sel);
164 }
165
166 if (!values[obj.value]) {
167 if (obj.value == "") {
168 var optdef = document.createElement("option");
169 optdef.value = "";
170 optdef.appendChild(document.createTextNode(def));
171 sel.appendChild(optdef);
172 } else {
173 var opt = document.createElement("option");
174 opt.value = obj.value;
175 opt.selected = "selected";
176 opt.appendChild(document.createTextNode(obj.value));
177 sel.appendChild(opt);
178 }
179 }
180
181 for (var i in values) {
182 var opt = document.createElement("option");
183 opt.value = i;
184
185 if (obj.value == i) {
186 opt.selected = "selected";
187 }
188
189 opt.appendChild(document.createTextNode(values[i]));
190 sel.appendChild(opt);
191 }
192
193 var optman = document.createElement("option");
194 optman.value = "";
195 optman.appendChild(document.createTextNode(man));
196 sel.appendChild(optman);
197
198 obj.style.display = "none";
199
200 cbi_bind(sel, "change", function() {
201 if (sel.selectedIndex == sel.options.length - 1) {
202 obj.style.display = "inline";
203 sel.parentNode.removeChild(sel);
204 obj.focus();
205 } else {
206 obj.value = sel.options[sel.selectedIndex].value;
207 }
208
209 try {
210 cbi_d_update();
211 } catch (e) {
212 //Do nothing
213 }
214 })
215 }
216
217 function cbi_combobox_init(id, values, def, man) {
218 var obj = document.getElementById(id);
219 cbi_bind(obj, "blur", function() {
220 cbi_combobox(id, values, def, man)
221 });
222 cbi_combobox(id, values, def, man);
223 }
224
225 function cbi_filebrowser(id, url, defpath) {
226 var field = document.getElementById(id);
227 var browser = window.open(
228 url + ( field.value || defpath || '' ) + '?field=' + id,
229 "luci_filebrowser", "width=300,height=400,left=100,top=200,scrollbars=yes"
230 );
231
232 browser.focus();
233 }
234
235 //Hijacks the CBI form to send via XHR (requires Prototype)
236 function cbi_hijack_forms(layer, win, fail, load) {
237 var forms = layer.getElementsByTagName('form');
238 for (var i=0; i<forms.length; i++) {
239 $(forms[i]).observe('submit', function(event) {
240 // Prevent the form from also submitting the regular way
241 event.stop();
242
243 // Submit via XHR
244 event.element().request({
245 onSuccess: win,
246 onFailure: fail
247 });
248
249 if (load) {
250 load();
251 }
252 });
253 }
254 }
255
256
257 function cbi_t_add(section, tab) {
258 var t = document.getElementById('tab.' + section + '.' + tab);
259 var c = document.getElementById('container.' + section + '.' + tab);
260
261 if( t && c ) {
262 cbi_t[section] = (cbi_t[section] || [ ]);
263 cbi_t[section][tab] = { 'tab': t, 'container': c, 'cid': c.id };
264 }
265 }
266
267 function cbi_t_switch(section, tab) {
268 if( cbi_t[section] && cbi_t[section][tab] ) {
269 var o = cbi_t[section][tab];
270 var h = document.getElementById('tab.' + section);
271 for( var tid in cbi_t[section] ) {
272 var o2 = cbi_t[section][tid];
273 if( o.tab.id != o2.tab.id ) {
274 o2.tab.className = o2.tab.className.replace(/(^| )cbi-tab( |$)/, " cbi-tab-disabled ");
275 o2.container.style.display = 'none';
276 }
277 else {
278 if(h) h.value = tab;
279 o2.tab.className = o2.tab.className.replace(/(^| )cbi-tab-disabled( |$)/, " cbi-tab ");
280 o2.container.style.display = 'block';
281 }
282 }
283 }
284 return false
285 }
286
287 function cbi_t_update() {
288 for( var sid in cbi_t )
289 for( var tid in cbi_t[sid] )
290 if( cbi_c[cbi_t[sid][tid].cid] == 0 ) {
291 cbi_t[sid][tid].tab.style.display = 'none';
292 }
293 else if( cbi_t[sid][tid].tab && cbi_t[sid][tid].tab.style.display == 'none' ) {
294 cbi_t[sid][tid].tab.style.display = '';
295
296 var t = cbi_t[sid][tid].tab;
297 window.setTimeout(function() { t.className = t.className.replace(/ cbi-tab-highlighted/g, '') }, 750);
298 cbi_t[sid][tid].tab.className += ' cbi-tab-highlighted';
299 }
300 }
301