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