Add XHR CBI helper
[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 Jo-Philipp Wich <xm@leipzig.freifunk.net>
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
18 function cbi_d_add(field, dep, next) {
19 var obj = document.getElementById(field);
20 if (obj) {
21 var entry
22 for (var i=0; i<cbi_d.length; i++) {
23 if (cbi_d[i].id == field) {
24 entry = cbi_d[i];
25 break;
26 }
27 }
28 if (!entry) {
29 entry = {
30 "node": obj,
31 "id": field,
32 "parent": obj.parentNode.id,
33 "next": next,
34 "deps": []
35 };
36 cbi_d.unshift(entry);
37 }
38 entry.deps.push(dep)
39 }
40 }
41
42 function cbi_d_checkvalue(target, ref) {
43 var t = document.getElementById(target);
44 var value;
45
46 if (!t || !t.value) {
47 value = "";
48 } else {
49 value = t.value;
50
51 if (t.type == "checkbox") {
52 value = t.checked ? value : "";
53 }
54 }
55
56 return (value == ref)
57 }
58
59 function cbi_d_check(deps) {
60 for (var i=0; i<deps.length; i++) {
61 var istat = true
62 for (var j in deps[i]) {
63 istat = (istat && cbi_d_checkvalue(j, deps[i][j]))
64 }
65 if (istat) {
66 return true
67 }
68 }
69 }
70
71 function cbi_d_update() {
72 var state = false;
73 for (var i=0; i<cbi_d.length; i++) {
74 var entry = cbi_d[i];
75 var next = document.getElementById(entry.next)
76 var node = document.getElementById(entry.id)
77 var parent = document.getElementById(entry.parent)
78
79 if (node && node.parentNode && !cbi_d_check(entry.deps)) {
80 node.parentNode.removeChild(node);
81 state = (state || !node.parentNode)
82 } else if ((!node || !node.parentNode) && cbi_d_check(entry.deps)) {
83 if (!next) {
84 parent.appendChild(entry.node);
85 } else {
86 next.parentNode.insertBefore(entry.node, next);
87 }
88 state = (state || (node && node.parentNode))
89 }
90 }
91 if (state) {
92 cbi_d_update();
93 }
94 }
95
96 function cbi_bind(obj, type, callback, mode) {
97 if (typeof mode == "undefined") {
98 mode = false;
99 }
100 if (!obj.addEventListener) {
101 ieCallback = function(){
102 var e = window.event;
103 if (!e.target && e.srcElement) {
104 e.target = e.srcElement;
105 };
106 e.target['_eCB' + type + callback] = callback;
107 e.target['_eCB' + type + callback](e);
108 e.target['_eCB' + type + callback] = null;
109 };
110 obj.attachEvent('on' + type, ieCallback);
111 } else {
112 obj.addEventListener(type, callback, mode);
113 }
114 return obj;
115 }
116
117 function cbi_combobox(id, values, def, man) {
118 var selid = "cbi.combobox." + id;
119 if (document.getElementById(selid)) {
120 return
121 }
122
123 var obj = document.getElementById(id)
124 var sel = document.createElement("select");
125 sel.id = selid;
126 sel.className = 'cbi-input-select';
127 if (obj.nextSibling) {
128 obj.parentNode.insertBefore(sel, obj.nextSibling);
129 } else {
130 obj.parentNode.appendChild(sel);
131 }
132
133 if (!values[obj.value]) {
134 if (obj.value == "") {
135 var optdef = document.createElement("option");
136 optdef.value = "";
137 optdef.appendChild(document.createTextNode(def));
138 sel.appendChild(optdef);
139 } else {
140 var opt = document.createElement("option");
141 opt.value = obj.value;
142 opt.selected = "selected";
143 opt.appendChild(document.createTextNode(obj.value));
144 sel.appendChild(opt);
145 }
146 }
147
148 for (var i in values) {
149 var opt = document.createElement("option");
150 opt.value = i;
151
152 if (obj.value == i) {
153 opt.selected = "selected";
154 }
155
156 opt.appendChild(document.createTextNode(values[i]));
157 sel.appendChild(opt);
158 }
159
160 var optman = document.createElement("option");
161 optman.value = "";
162 optman.appendChild(document.createTextNode(man));
163 sel.appendChild(optman);
164
165 obj.style.display = "none";
166
167 cbi_bind(sel, "change", function() {
168 if (sel.selectedIndex == sel.options.length - 1) {
169 obj.style.display = "inline";
170 sel.parentNode.removeChild(sel);
171 obj.focus();
172 } else {
173 obj.value = sel.options[sel.selectedIndex].value;
174 }
175 })
176 }
177
178 function cbi_combobox_init(id, values, def, man) {
179 var obj = document.getElementById(id);
180 cbi_bind(obj, "blur", function() {
181 cbi_combobox(id, values, def, man)
182 });
183 cbi_combobox(id, values, def, man);
184 }
185
186 function cbi_filebrowser(id, url, defpath) {
187 var field = document.getElementById(id);
188 var browser = window.open(
189 url + ( field.value || defpath || '' ) + '?field=' + id,
190 "luci_filebrowser", "width=300,height=400,left=100,top=200,scrollbars=yes"
191 );
192
193 browser.focus();
194 }
195
196 //Hijacks the CBI form to send via XHR (requires Prototype)
197 function cbi_hijack_forms(layer, win, fail, load) {
198 layer.select('form').each(function(form) {
199 form.observe('submit', function(event) {
200 // Prevent the form from also submitting the regular way
201 event.stop();
202
203 var form = event.element();
204
205 if (load) {
206 load();
207 }
208
209 // Submit via XHR
210 form.request({
211 onSuccess: win,
212 onFailure: fail
213 });
214 });
215 });
216 }