Use .empty() instead off removing childs
[adhocweb.git] / js / main.js
1 var BOSH_SERVICE = 'http://localhost:5280/http-bind/';
2 var show_log = false;
3
4 Strophe.addNamespace("ADHOC", "http://jabber.org/protocol/commands");
5
6 var localJID = null;
7 var connection   = null;
8 var sessionid = null;
9 var cmdNode = null;
10
11 function log(msg) {
12     var entry = $('<div></div>').append(document.createTextNode(msg));
13     $('#log').append(entry);
14 }
15
16 function rawInput(data) {
17     log('RECV: ' + data);
18 }
19
20 function rawOutput(data) {
21     log('SENT: ' + data);
22 }
23
24 function onConnect(status) {
25     if (status == Strophe.Status.CONNECTING) {
26         log('Strophe is connecting.');
27     } else if (status == Strophe.Status.CONNFAIL) {
28         log('Strophe failed to connect.');
29         showConnect();
30     } else if (status == Strophe.Status.DISCONNECTING) {
31         log('Strophe is disconnecting.');
32     } else if (status == Strophe.Status.DISCONNECTED) {
33         log('Strophe is disconnected.');
34         showConnect();
35     } else if (status == Strophe.Status.AUTHFAIL) {
36         log('Authentication failed');
37         if (connection) {
38             connection.disconnect();
39         }
40     } else if (status == Strophe.Status.CONNECTED) {
41         log('Strophe is connected.');
42         checkFeatures();
43     }
44 }
45
46 function addNote(elem, text, type) {
47     if (!type) {
48        type = "info";
49     }
50     $(elem).append("<p class='" + type + "Note'>" + text + "</p>");
51 }
52
53 function addForm(elem, x) {
54     var form = $("<form/>");
55     form.submit(function(){return false;});
56     var fieldset = $("<fieldset/>");
57     form.append(fieldset);
58     if ($(x).find("title").length > 0)
59         $("<legend/>").text($(x).find("title").text()).appendTo(fieldset);
60     if ($(x).find("instructions").length > 0)
61         $("<p/>").text($(x).find("instructions").text()).appendTo(fieldset);
62     $(x).find("field").each(function(){
63         var item = null;
64         var type = $(this).attr("type");
65         if($(this).attr("label")) {
66             $("<label/>").text($(this).attr("label")).attr("for", $(this).attr("var")).appendTo(fieldset);
67         }
68         switch(type) {
69         case "hidden":
70             item = $("<input type='hidden'/>");
71             break;
72         case "boolean":
73             item = $("<input type='checkbox'/>");
74             break;
75         case "text-multi":
76             item = $("<textarea/>");
77             break;
78         case "text-single":
79             item = $("<input type='text'/>");
80             break;
81         case "fixed":
82             item = $("<input type='text'/>").attr("readonly",true);
83             break;
84         case "jid-multi":
85             item = $("<textarea/>");
86             break;
87         case "jid-single":
88             item = $("<input type='text'/>");
89             break;
90         case "list-multi":
91             item = $("<select multiple='multiple'/>");
92             $(this).find("option").each(function(){
93                     $("<option/>").val($(this).find("value").text()).text($(this).attr("label")).appendTo(item);
94                     });
95             break;
96         case "list-single":
97             item = $("<select/>");
98             $(this).find("option").each(function(){
99                     $("<option/>").val($(this).find("value").text()).text($(this).attr("label")).appendTo(item);
100                     });
101             break;
102         case "text-private":
103             item = $("<input type='password'/>");
104             break;
105         default:
106             item = $("<input/>");
107         }
108         item.addClass("df-item");
109         if ($(this).find("value").length > 0) {
110             var value = null;
111             if ((type == "text-multi") || (type == "jid-multi")) {
112                 value = "";
113                 $(this).find("value").each(function() {
114                     value = value + $(this).text() + "\n";
115                 });
116                 item.val(value);
117             } else if (type == "list-multi") {
118                 value = new Array();
119                 $(this).find("value").each(function() {
120                     value[value.length] = $(this).text();
121                 });
122             } else {
123                 item.val($(this).find("value").text());
124             }
125         }
126         if ($(this).attr("var")) {
127             item.attr("name", $(this).attr("var"));
128             item.attr("id", $(this).attr("var"));
129         }
130         fieldset.append(item);
131         fieldset.append("<br/>");
132     });
133     $(elem).append(form);
134 }
135
136 function serializeToDataform(form, st) {
137     st.c("x", {"xmlns":"jabber:x:data", "type": "submit"});
138     $(form).find(".df-item").each(function(){
139         st.c("field", {"var": $(this).attr("name")});
140         if (this.nodeName.toLowerCase() == "select" && this.multiple) {
141             for (var i = 0; i < this.options.length; i++)
142                 if (options[i].selected)
143                     st.c("value").t(options[i]).up();
144         } else if (this.nodeName.toLowerCase() == "textarea") {
145             var sp_value = this.value.split(/\r?\n|\r/g);
146             for(var i = 0; i < sp_value.length; i++)
147                 st.c("value").t(sp_value[i]).up();
148         } else if (this.nodeName.toLowerCase() == "input" && this.type == "checkbox") {
149             if (this.checked) {
150                 st.c("value").t("1");
151             } else {
152                 st.c("value").t("0");
153             }
154         } else {
155             // if this has value then
156             st.c("value").t($(this).val()).up();
157         }
158         st.up();
159     });
160     st.up();
161 }
162
163 function displayResult(result) {
164     var status = $(result).find("command").attr("status");
165
166     $("#output").empty();
167     $(result).find("command > *").each(function(index, e) {
168         if ($(e).is("note")) {
169             addNote("#output", $(e).text(), $(e).attr("type"));
170         } else if ($(e).is("x[xmlns=jabber:x:data]")) {
171             addForm("#output", e);
172         }
173     });
174     if (status == "executing") {
175         $("#output").append("<input type='button' disabled='true' id='prevButton' value='Prev'/>"+
176                             "<input type='button' disabled='true' id='nextButton' value='Next'/>"+
177                             "<input type='button' disabled='true' id='completeButton' value='Complete'/>"+
178                             "<input type='button' id='executeButton' value='Execute'/>"+
179                             "<input type='button' id='cancelButton' value='Cancel'/>");
180         for (kind in ['prev', 'next', 'complete']) {
181             if ($(result).find('actions ' + kind).length > 0)
182                 $('#' + kind + 'Button').attr("disabled", "false");
183         }
184         $('#executeButton').bind("click", function() {
185             var execIQ = $iq({ type: "set", to: connection.domain, id: connection.getUniqueId() })
186                 .c("command", { xmlns: Strophe.NS.ADHOC, node: cmdNode, sessionid: sessionid, action: "execute" });
187             serializeToDataform($('form'), execIQ);
188             connection.sendIQ(execIQ, displayResult);
189         });
190
191         $('#cancelButton').bind("click", function() {
192             var cancelIQ = $iq({ type: "set", to: connection.domain, id: connection.getUniqueId() })
193                 .c("command", { xmlns: Strophe.NS.ADHOC, node: cmdNode, sessionid: sessionid, action: "cancel" });
194             cmdNode = null
195             sessionid = null;
196             connection.sendIQ(cancelIQ, displayResult);
197         });
198     } else {
199         input = $("<input type='button' value='Start over'/>").bind("click", function() {
200             $('#output').empty();
201             sessionid = null;
202             cmdNode = null;
203             getCommandNodes();
204         });
205         $("#output").append(input);
206     }
207 }
208
209 function runCommand() {
210     cmdNode = $(this).attr("id"); // Save node of executed command (in global var)
211     var execIQ = $iq({ type: "set", to: connection.domain, id: connection.getUniqueId() })
212         .c("command", { xmlns: Strophe.NS.ADHOC, node: cmdNode, action: "execute" });
213     connection.sendIQ(execIQ, function(result) {
214         sessionid = $(result).find("command").attr("sessionid");
215         displayResult(result);
216     });
217 }
218
219 function getCommandNodes() {
220     var nodesIQ = $iq({ type: "get", to: connection.domain, id: "nodes1" }).c("query", {xmlns: Strophe.NS.DISCO_ITEMS, node: Strophe.NS.ADHOC});
221     connection.sendIQ(nodesIQ, function(result) {
222         $('#output').append("<ul id='items'></ul>");
223         $(result).find("item").each(function(index, e) {
224             item = $("<li id='" + $(e).attr("node") + "'>" + $(e).attr("name") + "</li>").bind("click", runCommand);
225             $("#items").append(item);
226         });
227     });
228 }
229
230 function checkFeatures() {
231     featureIQ = $iq({ type: "get", to: connection.domain, id: "features1" }).c("query", {xmlns: Strophe.NS.DISCO_INFO});
232     connection.sendIQ(featureIQ, function(result) {
233         if ($(result).find("feature[var='" + Strophe.NS.ADHOC + "']").length > 0) {
234             $('#output').append("<p>This entitiy does support AdHoc commands</p>");
235         } else {
236             $('#output').append("<p>This entitiy does NOT support AdHoc commands</p>");
237         }
238     });
239     getCommandNodes();
240 }
241
242 function showConnect() {
243     var jid = $('#jid');
244     var pass = $('#pass');
245     var button = $('#connect').get(0);        
246
247     button.value = 'connect';
248     pass.show();
249     jid.show();
250     $('label').show();
251     $('#output').empty();
252     return false;
253 }
254
255 function showDisconnect() {
256     var jid = $('#jid');
257     var pass = $('#pass');
258     var button = $('#connect').get(0);        
259
260     button.value = 'disconnect';
261     pass.hide();
262     jid.hide();
263     $('label').hide();
264     return false;
265 }
266
267 $(document).ready(function () {
268     connection = new Strophe.Connection(BOSH_SERVICE);
269     if (show_log) {
270         $('#log_container').show();
271         connection.rawInput = rawInput;
272         connection.rawOutput = rawOutput;
273     }
274
275     $("#log_toggle").click(function () {
276         $("#log").toggle();
277       });
278
279     $('#cred').bind('submit', function () {
280         var button = $('#connect').get(0);
281         var jid = $('#jid');
282         var pass = $('#pass');        
283         localJID = jid.get(0).value;
284
285         if (button.value == 'connect') {
286             showDisconnect();
287             $('#log').empty();
288             connection.connect(localJID,
289                pass.get(0).value,
290                onConnect);
291         } else {
292             connection.disconnect();
293         }
294         return false;
295     });
296 });
297
298 onunload = function() {
299     if (connection) {
300         connection.disconnect();
301     }
302 }
303