]>
Commit | Line | Data |
---|---|---|
15046f00 JM |
1 | /* |
2 | * noVNC: HTML5 VNC client | |
d0c29bb6 | 3 | * Copyright (C) 2011 Joel Martin |
5f409eee | 4 | * Licensed under LGPL-3 (see LICENSE.txt) |
15046f00 JM |
5 | * |
6 | * See README.md for usage and integration instructions. | |
7 | */ | |
43cf7bd8 | 8 | |
15046f00 | 9 | "use strict"; |
43cf7bd8 | 10 | /*jslint white: false, browser: true */ |
d890e864 | 11 | /*global window, $D, Util, WebUtil, RFB, Display */ |
15046f00 | 12 | |
f7ec5b2c | 13 | var UI = { |
91308399 | 14 | |
da6dd893 | 15 | settingsOpen : false, |
53fc7392 CG |
16 | ConnSettingsOpen : true, |
17 | clipboardOpen: false, | |
da6dd893 | 18 | |
f7ec5b2c | 19 | // Render default UI and initialize settings menu |
53fc7392 | 20 | load: function() { |
f7ec5b2c | 21 | var html = '', i, sheet, sheets, llevels; |
91308399 | 22 | |
53fc7392 | 23 | // Stylesheet selection dropdown |
8d5d2c82 AM |
24 | sheet = WebUtil.selectStylesheet(); |
25 | sheets = WebUtil.getStylesheets(); | |
8db09746 | 26 | for (i = 0; i < sheets.length; i += 1) { |
53fc7392 | 27 | addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title); |
da6dd893 | 28 | } |
da6dd893 JM |
29 | |
30 | // Logging selection dropdown | |
da6dd893 | 31 | llevels = ['error', 'warn', 'info', 'debug']; |
8db09746 | 32 | for (i = 0; i < llevels.length; i += 1) { |
53fc7392 | 33 | addOption($D('noVNC_logging'),llevels[i], llevels[i]); |
da6dd893 | 34 | } |
53fc7392 | 35 | |
da6dd893 | 36 | // Settings with immediate effects |
f7ec5b2c JM |
37 | UI.initSetting('logging', 'warn'); |
38 | WebUtil.init_logging(UI.getSetting('logging')); | |
39 | UI.initSetting('stylesheet', 'default'); | |
8db09746 | 40 | |
8d5d2c82 | 41 | WebUtil.selectStylesheet(null); // call twice to get around webkit bug |
f7ec5b2c | 42 | WebUtil.selectStylesheet(UI.getSetting('stylesheet')); |
da6dd893 | 43 | |
91308399 | 44 | /* Populate the controls if defaults are provided in the URL */ |
53fc7392 | 45 | UI.initSetting('host', ''); |
f7ec5b2c JM |
46 | UI.initSetting('port', ''); |
47 | UI.initSetting('password', ''); | |
48 | UI.initSetting('encrypt', false); | |
49 | UI.initSetting('true_color', true); | |
50 | UI.initSetting('cursor', false); | |
53fc7392 | 51 | UI.initSetting('shared', true); |
f7ec5b2c JM |
52 | UI.initSetting('connectTimeout', 2); |
53 | ||
53fc7392 | 54 | UI.rfb = RFB({'target': $D('noVNC_canvas'), |
d890e864 JM |
55 | 'onUpdateState': UI.updateState, |
56 | 'onClipboard': UI.clipReceive}); | |
53fc7392 | 57 | |
8db09746 | 58 | // Unfocus clipboard when over the VNC area |
53fc7392 CG |
59 | //$D('VNC_screen').onmousemove = function () { |
60 | // var keyboard = UI.rfb.get_keyboard(); | |
61 | // if ((! keyboard) || (! keyboard.get_focused())) { | |
62 | // $D('VNC_clipboard_text').blur(); | |
63 | // } | |
64 | // }; | |
65 | ||
ad3f7624 JM |
66 | // Show mouse selector buttons on touch screen devices |
67 | if ('ontouchstart' in document.documentElement) { | |
53fc7392 | 68 | $D('noVNC_mobile_buttons').style.display = "inline"; |
ad3f7624 | 69 | UI.setMouseButton(); |
53fc7392 | 70 | window.scrollTo(0, 1); |
ad3f7624 JM |
71 | } |
72 | ||
53fc7392 CG |
73 | //iOS Safari does not support CSS position:fixed. This detects iOS devices and enables javascript workaround. |
74 | if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) { | |
75 | alert("here"); | |
76 | setOnscroll(); | |
77 | setResize(); | |
78 | } | |
79 | ||
91308399 JM |
80 | }, |
81 | ||
da6dd893 JM |
82 | // Read form control compatible setting from cookie |
83 | getSetting: function(name) { | |
53fc7392 | 84 | var val, ctrl = $D('noVNC_' + name); |
8d5d2c82 | 85 | val = WebUtil.readCookie(name); |
da6dd893 JM |
86 | if (ctrl.type === 'checkbox') { |
87 | if (val.toLowerCase() in {'0':1, 'no':1, 'false':1}) { | |
88 | val = false; | |
89 | } else { | |
90 | val = true; | |
91 | } | |
92 | } | |
93 | return val; | |
94 | }, | |
95 | ||
96 | // Update cookie and form control setting. If value is not set, then | |
97 | // updates from control to current cookie setting. | |
98 | updateSetting: function(name, value) { | |
53fc7392 CG |
99 | |
100 | var i, ctrl = $D('noVNC_' + name); | |
da6dd893 JM |
101 | // Save the cookie for this session |
102 | if (typeof value !== 'undefined') { | |
8d5d2c82 | 103 | WebUtil.createCookie(name, value); |
da6dd893 | 104 | } |
53fc7392 CG |
105 | if(name === 'host') |
106 | { | |
107 | ||
108 | ||
109 | } | |
da6dd893 | 110 | // Update the settings control |
f7ec5b2c | 111 | value = UI.getSetting(name); |
53fc7392 | 112 | |
da6dd893 JM |
113 | if (ctrl.type === 'checkbox') { |
114 | ctrl.checked = value; | |
53fc7392 | 115 | |
da6dd893 | 116 | } else if (typeof ctrl.options !== 'undefined') { |
8db09746 | 117 | for (i = 0; i < ctrl.options.length; i += 1) { |
da6dd893 JM |
118 | if (ctrl.options[i].value === value) { |
119 | ctrl.selectedIndex = i; | |
120 | break; | |
121 | } | |
122 | } | |
123 | } else { | |
53fc7392 CG |
124 | /*Weird IE9 error leads to 'null' appearring in textboxes instead of ''.*/ |
125 | if(value === null) | |
126 | { | |
127 | value = ""; | |
128 | } | |
da6dd893 JM |
129 | ctrl.value = value; |
130 | } | |
131 | }, | |
132 | ||
133 | // Save control setting to cookie | |
134 | saveSetting: function(name) { | |
53fc7392 | 135 | var val, ctrl = $D('noVNC_' + name); |
da6dd893 JM |
136 | if (ctrl.type === 'checkbox') { |
137 | val = ctrl.checked; | |
138 | } else if (typeof ctrl.options !== 'undefined') { | |
139 | val = ctrl.options[ctrl.selectedIndex].value; | |
140 | } else { | |
141 | val = ctrl.value; | |
142 | } | |
8d5d2c82 | 143 | WebUtil.createCookie(name, val); |
8db09746 | 144 | //Util.Debug("Setting saved '" + name + "=" + val + "'"); |
da6dd893 JM |
145 | return val; |
146 | }, | |
147 | ||
148 | // Initial page load read/initialization of settings | |
149 | initSetting: function(name, defVal) { | |
a8edf9d8 | 150 | var val; |
da6dd893 JM |
151 | |
152 | // Check Query string followed by cookie | |
8d5d2c82 | 153 | val = WebUtil.getQueryVar(name); |
da6dd893 | 154 | if (val === null) { |
8d5d2c82 | 155 | val = WebUtil.readCookie(name, defVal); |
da6dd893 | 156 | } |
f7ec5b2c | 157 | UI.updateSetting(name, val); |
8db09746 | 158 | //Util.Debug("Setting '" + name + "' initialized to '" + val + "'"); |
da6dd893 JM |
159 | return val; |
160 | }, | |
161 | ||
162 | ||
163 | // Toggle the settings menu: | |
164 | // On open, settings are refreshed from saved cookies. | |
165 | // On close, settings are applied | |
166 | clickSettingsMenu: function() { | |
f7ec5b2c JM |
167 | if (UI.settingsOpen) { |
168 | UI.settingsApply(); | |
da6dd893 | 169 | |
f7ec5b2c | 170 | UI.closeSettingsMenu(); |
da6dd893 | 171 | } else { |
f7ec5b2c JM |
172 | UI.updateSetting('encrypt'); |
173 | UI.updateSetting('true_color'); | |
d890e864 | 174 | if (UI.rfb.get_display().get_cursor_uri()) { |
f7ec5b2c | 175 | UI.updateSetting('cursor'); |
da6dd893 | 176 | } else { |
f7ec5b2c | 177 | UI.updateSetting('cursor', false); |
53fc7392 | 178 | $D('noVNC_cursor').disabled = true; |
da6dd893 | 179 | } |
f7ec5b2c JM |
180 | UI.updateSetting('shared'); |
181 | UI.updateSetting('connectTimeout'); | |
182 | UI.updateSetting('stylesheet'); | |
183 | UI.updateSetting('logging'); | |
da6dd893 | 184 | |
f7ec5b2c | 185 | UI.openSettingsMenu(); |
da6dd893 JM |
186 | } |
187 | }, | |
188 | ||
189 | // Open menu | |
190 | openSettingsMenu: function() { | |
53fc7392 CG |
191 | if(UI.clipboardOpen == true) |
192 | { | |
193 | UI.showClipboard(); | |
194 | } | |
195 | //Close connection settings if open | |
196 | if(UI.ConnSettingsOpen == true) { | |
197 | connectPanelbutton(); | |
198 | } | |
199 | $D('noVNC_Settings').style.display = "block"; | |
f7ec5b2c | 200 | UI.settingsOpen = true; |
da6dd893 JM |
201 | }, |
202 | ||
203 | // Close menu (without applying settings) | |
204 | closeSettingsMenu: function() { | |
53fc7392 | 205 | $D('noVNC_Settings').style.display = "none"; |
f7ec5b2c | 206 | UI.settingsOpen = false; |
da6dd893 JM |
207 | }, |
208 | ||
209 | // Disable/enable controls depending on connection state | |
b5087acc JM |
210 | settingsDisabled: function(disabled, rfb) { |
211 | //Util.Debug(">> settingsDisabled"); | |
53fc7392 CG |
212 | $D('noVNC_encrypt').disabled = disabled; |
213 | $D('noVNC_true_color').disabled = disabled; | |
d890e864 | 214 | if (rfb && rfb.get_display() && rfb.get_display().get_cursor_uri()) { |
53fc7392 | 215 | $D('noVNC_cursor').disabled = disabled; |
da6dd893 | 216 | } else { |
f7ec5b2c | 217 | UI.updateSetting('cursor', false); |
53fc7392 | 218 | $D('noVNC_cursor').disabled = true; |
da6dd893 | 219 | } |
53fc7392 CG |
220 | $D('noVNC_shared').disabled = disabled; |
221 | $D('noVNC_connectTimeout').disabled = disabled; | |
b5087acc | 222 | //Util.Debug("<< settingsDisabled"); |
da6dd893 JM |
223 | }, |
224 | ||
225 | // Save/apply settings when 'Apply' button is pressed | |
226 | settingsApply: function() { | |
8db09746 | 227 | //Util.Debug(">> settingsApply"); |
f7ec5b2c JM |
228 | UI.saveSetting('encrypt'); |
229 | UI.saveSetting('true_color'); | |
d890e864 | 230 | if (UI.rfb.get_display().get_cursor_uri()) { |
f7ec5b2c | 231 | UI.saveSetting('cursor'); |
da6dd893 | 232 | } |
f7ec5b2c JM |
233 | UI.saveSetting('shared'); |
234 | UI.saveSetting('connectTimeout'); | |
235 | UI.saveSetting('stylesheet'); | |
236 | UI.saveSetting('logging'); | |
da6dd893 JM |
237 | |
238 | // Settings with immediate (non-connected related) effect | |
f7ec5b2c JM |
239 | WebUtil.selectStylesheet(UI.getSetting('stylesheet')); |
240 | WebUtil.init_logging(UI.getSetting('logging')); | |
8db09746 | 241 | //Util.Debug("<< settingsApply"); |
da6dd893 JM |
242 | }, |
243 | ||
244 | ||
245 | ||
f00b1e37 | 246 | setPassword: function() { |
53fc7392 | 247 | UI.rfb.sendPassword($D('noVNC_password').value); |
f00b1e37 JM |
248 | return false; |
249 | }, | |
250 | ||
63708ff5 | 251 | sendCtrlAltDel: function() { |
f7ec5b2c | 252 | UI.rfb.sendCtrlAltDel(); |
63708ff5 JM |
253 | }, |
254 | ||
ad3f7624 JM |
255 | setMouseButton: function(num) { |
256 | var b, blist = [1,2,4], button, | |
257 | mouse = UI.rfb.get_mouse(); | |
258 | ||
259 | if (typeof num === 'undefined') { | |
260 | // Show the default | |
261 | num = mouse.get_touchButton(); | |
262 | } else if (num === mouse.get_touchButton()) { | |
263 | // Set all buttons off (no clicks) | |
264 | mouse.set_touchButton(0); | |
265 | num = 0; | |
266 | } else { | |
267 | // Turn on one button | |
268 | mouse.set_touchButton(num); | |
269 | } | |
270 | ||
271 | for (b = 0; b < blist.length; b++) { | |
53fc7392 | 272 | button = $D('noVNC_mouse_button' + blist[b]); |
ad3f7624 JM |
273 | if (blist[b] === num) { |
274 | button.style.backgroundColor = "black"; | |
275 | button.style.color = "lightgray"; | |
276 | } else { | |
277 | button.style.backgroundColor = ""; | |
278 | button.style.color = ""; | |
279 | } | |
280 | } | |
ad3f7624 JM |
281 | }, |
282 | ||
8db09746 | 283 | updateState: function(rfb, state, oldstate, msg) { |
a7a89626 | 284 | var s, sb, c, cad, klass; |
53fc7392 CG |
285 | s = $D('noVNC_status'); |
286 | sb = $D('noVNC_status_bar'); | |
287 | c = $D('noVNC_connect_button'); | |
e4671910 | 288 | cad = $D('sendCtrlAltDelButton'); |
91308399 JM |
289 | switch (state) { |
290 | case 'failed': | |
f00b1e37 | 291 | case 'fatal': |
91308399 | 292 | c.disabled = true; |
160fabf6 | 293 | cad.disabled = true; |
f7ec5b2c | 294 | UI.settingsDisabled(true, rfb); |
53fc7392 | 295 | klass = "noVNC_status_error"; |
91308399 JM |
296 | break; |
297 | case 'normal': | |
298 | c.value = "Disconnect"; | |
f7ec5b2c | 299 | c.onclick = UI.disconnect; |
91308399 | 300 | c.disabled = false; |
160fabf6 | 301 | cad.disabled = false; |
f7ec5b2c | 302 | UI.settingsDisabled(true, rfb); |
53fc7392 | 303 | klass = "noVNC_status_normal"; |
91308399 JM |
304 | break; |
305 | case 'disconnected': | |
53fc7392 | 306 | $D('noVNC_defaultScreen').style.display = "block"; |
f00b1e37 | 307 | case 'loaded': |
91308399 | 308 | c.value = "Connect"; |
f7ec5b2c | 309 | c.onclick = UI.connect; |
91308399 JM |
310 | |
311 | c.disabled = false; | |
160fabf6 | 312 | cad.disabled = true; |
f7ec5b2c | 313 | UI.settingsDisabled(false, rfb); |
53fc7392 | 314 | klass = "noVNC_status_normal"; |
91308399 | 315 | break; |
f00b1e37 JM |
316 | case 'password': |
317 | c.value = "Send Password"; | |
f7ec5b2c | 318 | c.onclick = UI.setPassword; |
f00b1e37 JM |
319 | |
320 | c.disabled = false; | |
321 | cad.disabled = true; | |
f7ec5b2c | 322 | UI.settingsDisabled(true, rfb); |
53fc7392 | 323 | klass = "noVNC_status_warn"; |
f00b1e37 | 324 | break; |
91308399 JM |
325 | default: |
326 | c.disabled = true; | |
160fabf6 | 327 | cad.disabled = true; |
f7ec5b2c | 328 | UI.settingsDisabled(true, rfb); |
53fc7392 | 329 | klass = "noVNC_status_warn"; |
91308399 JM |
330 | break; |
331 | } | |
332 | ||
333 | if (typeof(msg) !== 'undefined') { | |
334 | s.setAttribute("class", klass); | |
63708ff5 | 335 | sb.setAttribute("class", klass); |
91308399 JM |
336 | s.innerHTML = msg; |
337 | } | |
338 | ||
339 | }, | |
340 | ||
8db09746 | 341 | clipReceive: function(rfb, text) { |
f7ec5b2c | 342 | Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); |
53fc7392 | 343 | $D('noVNC_clipboard_text').value = text; |
f7ec5b2c | 344 | Util.Debug("<< UI.clipReceive"); |
8db09746 JM |
345 | }, |
346 | ||
347 | ||
91308399 | 348 | connect: function() { |
f7ec5b2c | 349 | var host, port, password; |
da6dd893 | 350 | |
f7ec5b2c | 351 | UI.closeSettingsMenu(); |
53fc7392 CG |
352 | connectPanelbutton(); |
353 | host = $D('noVNC_host').value; | |
354 | port = $D('noVNC_port').value; | |
355 | password = $D('noVNC_password').value; | |
91308399 | 356 | if ((!host) || (!port)) { |
63708ff5 | 357 | throw("Must set host and port"); |
91308399 JM |
358 | } |
359 | ||
f7ec5b2c JM |
360 | UI.rfb.set_encrypt(UI.getSetting('encrypt')); |
361 | UI.rfb.set_true_color(UI.getSetting('true_color')); | |
362 | UI.rfb.set_local_cursor(UI.getSetting('cursor')); | |
363 | UI.rfb.set_shared(UI.getSetting('shared')); | |
364 | UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout')); | |
da6dd893 | 365 | |
f7ec5b2c | 366 | UI.rfb.connect(host, port, password); |
53fc7392 CG |
367 | //Close dialog. |
368 | setTimeout("setBarPosition()",100); | |
369 | $D('noVNC_defaultScreen').style.display = "none"; | |
91308399 JM |
370 | }, |
371 | ||
372 | disconnect: function() { | |
f7ec5b2c | 373 | UI.closeSettingsMenu(); |
f7ec5b2c | 374 | UI.rfb.disconnect(); |
53fc7392 CG |
375 | $D('noVNC_defaultScreen').style.display = "block"; |
376 | UI.openSettingsMenu(); | |
91308399 JM |
377 | }, |
378 | ||
d890e864 | 379 | displayBlur: function() { |
d1bd5ec7 JM |
380 | UI.rfb.get_keyboard().set_focused(false); |
381 | UI.rfb.get_mouse().set_focused(false); | |
91308399 JM |
382 | }, |
383 | ||
d890e864 | 384 | displayFocus: function() { |
d1bd5ec7 JM |
385 | UI.rfb.get_keyboard().set_focused(true); |
386 | UI.rfb.get_mouse().set_focused(true); | |
91308399 JM |
387 | }, |
388 | ||
389 | clipClear: function() { | |
53fc7392 | 390 | $D('noVNC_clipboard_text').value = ""; |
f7ec5b2c | 391 | UI.rfb.clipboardPasteFrom(""); |
91308399 JM |
392 | }, |
393 | ||
394 | clipSend: function() { | |
53fc7392 | 395 | var text = $D('noVNC_clipboard_text').value; |
f7ec5b2c JM |
396 | Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); |
397 | UI.rfb.clipboardPasteFrom(text); | |
398 | Util.Debug("<< UI.clipSend"); | |
53fc7392 CG |
399 | }, |
400 | ||
401 | showClipboard: function() { | |
402 | //Close settings if open | |
403 | if(UI.settingsOpen == true) { | |
404 | UI.closeSettingsMenu(); | |
405 | } | |
406 | //Close connection settings if open | |
407 | if(UI.ConnSettingsOpen == true) { | |
408 | connectPanelbutton(); | |
409 | } | |
410 | //Toggle Connection Panel | |
411 | if(UI.clipboardOpen == true) | |
412 | { $D('noVNC_clipboard').style.display = "none"; | |
413 | UI.clipboardOpen = false; | |
414 | } else { | |
415 | $D('noVNC_clipboard').style.display = "block"; | |
416 | UI.clipboardOpen = true; | |
417 | } | |
91308399 JM |
418 | } |
419 | ||
63708ff5 | 420 | }; |
7825b9ee | 421 | |
53fc7392 CG |
422 | function connectPanelbutton() { |
423 | //Close connection settings if open | |
424 | if(UI.settingsOpen == true) { | |
425 | UI.closeSettingsMenu(); | |
426 | } | |
427 | if(UI.clipboardOpen == true) | |
428 | { | |
429 | UI.showClipboard(); | |
430 | } | |
431 | ||
432 | //Toggle Connection Panel | |
433 | if(UI.ConnSettingsOpen == true) | |
434 | { | |
435 | $D('noVNC_controls').style.display = "none"; | |
436 | UI.ConnSettingsOpen = false; | |
437 | } else { | |
438 | $D('noVNC_controls').style.display = "block"; | |
439 | UI.ConnSettingsOpen = true; | |
440 | } | |
441 | } | |
7825b9ee CG |
442 | |
443 | function showkeyboard(){ | |
53fc7392 | 444 | //Get Current Scroll Position |
7825b9ee CG |
445 | var scrollx = (document.all)?document.body.scrollLeft:window.pageXOffset; |
446 | var scrolly = (document.all)?document.body.scrollTop:window.pageYOffset; | |
447 | ||
7825b9ee | 448 | |
53fc7392 CG |
449 | //Stop browser zooming on textbox. |
450 | zoomDisable(); | |
451 | $D('keyboardinput').focus(); | |
452 | scroll(scrollx,scrolly); | |
453 | //Renable user zoom. | |
7825b9ee CG |
454 | zoomEnable(); |
455 | } | |
456 | ||
457 | function zoomDisable(){ | |
458 | //Change viewport meta data to disable zooming. | |
1734b5e4 | 459 | changeViewportMeta("user-scalable=0"); |
7825b9ee CG |
460 | } |
461 | ||
462 | function zoomEnable(){ | |
463 | //Change viewport meta data to enable user zooming. | |
1734b5e4 CG |
464 | changeViewportMeta("user-scalable=1"); |
465 | } | |
466 | ||
467 | function changeViewportMeta(newattributes) { | |
468 | ||
469 | // First, get the array of meta-tag elements | |
470 | var metatags = document.getElementsByTagName("meta"); | |
471 | ||
472 | // Update only the Viewport meta tag | |
473 | for (var cnt = 0; cnt < metatags.length; cnt++) | |
474 | { | |
475 | ||
476 | var name = metatags[cnt].getAttribute("name"); | |
477 | var content = metatags[cnt].getAttribute("content"); | |
478 | ||
479 | // Update the Viewport meta tag | |
480 | if (metatags[cnt].getAttribute("name") == "viewport") | |
481 | metatags[cnt].setAttribute("content", newattributes); | |
482 | } | |
7825b9ee | 483 | } |
53fc7392 CG |
484 | |
485 | //iOS < Version 5 does not support position fixed. Javascript workaround: | |
486 | function setOnscroll() { | |
487 | window.onscroll = function() { | |
488 | setBarPosition(); | |
489 | }; | |
490 | } | |
491 | ||
492 | function setResize() { | |
493 | window.onResize = function() { | |
494 | setBarPosition(); | |
495 | }; | |
496 | } | |
497 | ||
498 | function setBarPosition() { | |
499 | $D('VNC_mobile_bar').style.top = (window.pageYOffset) + 'px'; | |
500 | $D('VNC_mobile_buttons').style.left = (window.pageXOffset) + 'px'; | |
501 | ||
502 | $D('VNC_mobile_buttons_right').style.right = 0 + 'px'; | |
503 | ||
504 | var vncwidth = $('#VNC_screen').width(); | |
505 | $D('VNC_mobile_bar').style.width = vncwidth + 'px'; | |
506 | } | |
507 | ||
508 | //Helper to add options to dropdown. | |
509 | function addOption(selectbox,text,value ) | |
510 | { | |
511 | var optn = document.createElement("OPTION"); | |
512 | optn.text = text; | |
513 | optn.value = value; | |
514 | selectbox.options.add(optn); | |
515 | } |