Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ daa78d17

History | View | Annotate | Download (29.5 kB)

1
{% load i18n %}
2

    
3
<div id="machines" class="separator"></div>
4

    
5
<!-- the create button -->
6
<div id="createcontainer">
7
    <span id="createbody">{% trans "Start by creating a new Virtual Machine:" %}</span><br />
8
    <a id="create" rel="#wizard" href="#">{% trans "Create New +" %}</a>
9
</div>
10

    
11
<!-- changing between standard/list view -->
12
<div id="view-select">
13
    <a id="standard" href="/machines/standard"></a>
14
    <a id="list" href="/machines/list"></a>
15
    <a id="single" href="#"></a>
16
</div>
17

    
18
<div id="emptymachineslist"><h1 id="welcomeheader">{% trans "Welcome to the ocean!" %}</h1><br />
19
    <span class="welcomebody">{% trans "From this panel you will be able to manage your Virtual Machines (VMs). If you don't know what a VM is: take the " %}<a href="#">{% trans "tour" %}</a>.</span><br /><br />
20
    <span class="welcomebody">{% trans "The panel is currently empty, because you don't have any VMs yet. You can start by creating your new VM by clicking the blue button on the right. The wizard will guide you through the hole process." %}</span><br /><br />
21
    <span class="welcomefooter">{% trans "For more information or help, click " %}<a href="#">{% trans "here" %}</a>.</span>
22
</div>
23

    
24
<!-- the form -->
25
<form action="#">
26
        <!-- scrollable root element -->
27
        <div class="modal" id="wizard">
28
                <!-- status bar -->
29
                <ul id="status">
30
                        <li class="active"><span class="headernumber" class="first">1</span><div class="headerbody first">{% trans "Image" %}</div></li>
31
                        <li><span class="headernumber">2</span><div class="headerbody">{% trans "Flavor" %}</div></li>
32
                        <li class="third"><span class="headernumber">3</span><div class="headerbody">{% trans "Name" %}</div></li>
33
                </ul>
34
                <!-- scrollable items -->
35
                <div class="items">
36
                        <!-- pages -->
37
                        <div class="page">
38
                <h2>{% trans "Select an OS" %}</h2>
39
                <hr class="topruler" />
40
                <ul class="tabs">
41
                    <li><a href="#">{% trans "system images" %}</a></li>
42
                    <li><a href="#">{% trans "custom images" %}</a></li>
43
                </ul>
44
                <div class="panes">
45
                            <li id="image-template" style="display:none">
46
                                    <label for="image.id"> 
47
                            <a>
48
                                <div class="image-container">
49
                                    <div class="image">
50
                                        <input class="radio" type="radio" name="image-id" id="image-id" />
51
                                        <img src="" class="image-logo"/>
52
                                        <strong class="image-title">image.title</strong>
53
                                        <br />
54
                                        <span class="description">image.description</span> 
55
                                        <span id="size" class="size">?? MB</span><span class="size"> MB</span>                         
56
                                    </div>
57
                                </div>  
58
                            </a>
59
                                    </label>
60
                            </li>
61
                    <ul class="pane" id="standard-images">
62
                                            <!-- standard images -->
63
                                    </ul>
64
                    <ul class="pane" id="custom-images">
65
                                            <!-- custom images -->
66
                    </ul>
67
                </div>
68
                <hr class="bottomruler" />
69
                                <button type="button" class="prev" id="cancel">{% trans "Cancel" %}</button>
70
                                <button type="button" class="next right">{% trans "Next" %}</button>
71
            </div>
72
                        <div class="page">
73
                                <h2>{% trans "Select CPUs, RAM and Disk Size" %}</h2>
74
                <hr class="topruler" />
75
                <ul>
76
                    <li id="machinetype">
77
                        <div class="machine-type">
78
                            <label for="small" id="small">
79
                                <input type="radio" id="small" name="machine-type" value="small" checked="true" />
80
                                <span class="typebody" id="small-body">{% trans "small" %}</span>
81
                            </label>
82
                        </div>
83
                        <div class="machine-type">      
84
                            <label for="medium" id="medium">
85
                                <input type="radio" id="medium" name="machine-type" value="medium" />                  
86
                                <span class="typebody" id="medium-body">{% trans "medium" %}</span>
87
                            </label>
88
                        </div>
89
                        <div class="machine-type">
90
                            <label for="large" id="large">
91
                                <input type="radio" id="large" name="machine-type" value="large" />
92
                                <span class="typebody" id="large-body">{% trans "large" %}</span>
93
                            </label>
94
                        </div>
95
                        <div class="machine-type">
96
                            <label for="custom" id="custom">
97
                                <input type="radio" name="machine-type" id="custom" value="large" />
98
                                <span class="typebody" id="custom-body">{% trans "custom" %}</span>
99
                            </label>
100
                        </div>
101
                    </li>
102
                    <div id="page2-container">
103
                        <li class="slider-container">
104
                                        <label><strong class="sliders">CPUs</strong></label>
105
                            <input type="range" id="cpu" style="display:none" />
106
                            <input type="text" class="range" id="cpu-indicator" />
107
                                        <span class="units">cores</span>
108
                        </li>
109
                        <li class="slider-container">
110
                                        <label><strong class="sliders">RAM</strong></label>
111
                            <input type="range" id="ram" style="display:none" />
112
                            <input type="text" class="range" id="ram-indicator" />
113
                                        <span class="units">MB</span>
114
                        </li>
115
                        <li class="slider-container">
116
                                    <label><strong class="sliders">Size</strong></label>
117
                            <input type="range" id="storage" style="display:none" />
118
                            <input type="text" class="range" id="storage-indicator" />
119
                                        <span class="units">GB</span>
120
                        </li>
121
                        <li>
122
                            <div class="cost">
123
                                <span> {% trans "Your wallet:" %} 10,000 Credits </span> | <span>{% trans "This setup will cost you:" %}<input type="text" id="credits-indicator" value="20" class="range" disabled="disabled" /> {% trans "C/hour" %}</span>
124
                            </div>
125
                        </li>
126
                    </div>
127
                </ul>
128
                <hr class="bottomruler" />
129
                                <button type="button" class="prev">{% trans "Back" %}</button>
130
                                <button type="button" class="next right">{% trans "Next" %}</button>
131
            </div>
132
                        <div class="page">
133
                                <h2>{% trans "Confirm your settings" %}</h2>
134
                <hr class="topruler" />
135
                <ul id="page3-container">
136
                    <li class="required" id="label-name">
137
                        <label>
138
                            <strong>Name:</strong>
139
                            <input type="text" class="text" name="machine_name" id="name" value="My Ubuntu 10.04 x86_64 server"/>
140
                        </label>
141
                    </li>
142
                    <li>
143
                        <span>{% trans "Image:" %}</span> <span id="machine_image-label">Ubuntu 10.04 x86_64 server</span>
144
                    </li>
145
                    <li>
146
                        <span>{% trans "CPUs:" %}</span> <span id="machine_cpu-label">2</span> <span>{% trans "cores" %}</span>
147
                    </li>
148
                    <li>
149
                        <span>{% trans "RAM:" %}</span> <span id="machine_ram-label">1024</span><span>MB</span>
150
                    </li>
151
                    <li>
152
                        <span>{% trans "System Disk:" %}</span> <span id="machine_storage-label">10</span><span>GB</span>
153
                    </li>
154
                    <li>
155
                        <span>{% trans "Cost per Hour:" %}</span> <span>40 {% trans "credits" %}</span>
156
                    </li>
157
                    <li>
158
                        <span>{% trans "Credits in Wallet:" %}</span> <span>10.000</span>
159
                    </li>
160
                </ul>
161
                <hr class="bottomruler" />
162
                                <button type="button" class="prev">{% trans "Back" %}</button>
163
                                <button type="button" class="next right" id="start">{% trans "Create VM" %}</button>        
164
            </div>
165
                </div>
166
        </div>
167
</form>
168

    
169
<!-- base notification for error/success reporting -->
170
<a id="notification" rel="#error-success" href="#"></a>
171

    
172
<div class="modal" id="error-success">
173
    <h3>{% trans "Error!/Success!" %}</h3>
174
    <div><p>{% trans "More details about the result"%}</p></div>
175
</div>
176

    
177

    
178
<a id="metadata-edit-dialog" rel="#edit-dialog" href="#"></a>
179

    
180
<div class="meta-modal" id="edit-dialog">
181
    <div class='container'>
182
        <h3>
183
            <label>{% trans "Tags for machine:" %}</label>
184
            <span>Server name</span>
185
            <p style='display:none;'>hidden server id</p>
186
        </h3>
187
        <hr class="topruler" />
188
        <hr class="fatruler" />
189
        <div class="content">
190
            <ul class="meta-template" style="display:none">
191
                <li>
192
                    <label>{% trans "Key" %}</label>
193
                    <button type="button" class="remove">{% trans "remove x" %}</button>
194
                    <hr class="meta-separator">
195
                    <p>{% trans "Value" %}</p>
196
                    <button type="button" class="edit">{% trans "edit" %}</button>
197
                </li>
198
            </ul>
199
            <ul class="meta-list">
200
            </ul>
201
        </div>
202
    </div>
203
    <button type="button" class="create">{% trans "Create New+" %}</button>
204
    <div class="bottomruler" /> 
205
</div>
206

    
207
<a id="metadata-add-dialog" rel="#add-dialog" href="#"></a>
208

    
209
<div class="meta-modal" id="add-dialog">
210
    <div class='container'>
211
        <h3>
212
            <label>{% trans "Tags for machine:" %}</label>
213
            <span>Server name</span>
214
            <p style='display:none;'>hidden server id</p>
215
        </h3>
216
        <hr class="topruler" />
217
        <hr class="fatruler" />
218
        <div class="content">
219
            <label class="meta-key">{% trans "Key:" %}</label>
220
            <input type="text" maxlength="15" class="key" value="{% trans 'max 15 characters' %}"/>
221
            <hr class="meta-separator">
222
            <label class="meta-value">{% trans "Value:" %}</label>
223
            <textarea class="value">{% trans "max 150 characters" %}</textarea>
224
        </div>
225
    </div>
226
    <button type="button" class="cancel">{% trans "Cancel" %}</button>
227
    <button type="button" class="save">{% trans "Save" %}</button>
228
    <div class="bottomruler" /> 
229
</div>
230

    
231
<div id="machinesview"></div>
232

    
233
<div class="confirm_multiple">
234
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "machines" %}</p>
235
    <button class="yes">{% trans "Confirm All" %}</button>
236
        <button class="no">{% trans "Cancel All" %}</button>
237
</div>
238

    
239
<div id="machines" class="separator"></div>
240

    
241
<script>
242
//add hover to labels
243
$('span.typebody').mouseover(function() {
244
    $(this).addClass('typehover');
245
});
246
$('span.typebody').mouseout(function() {
247
    $(this).removeClass('typehover');
248
});
249

250
// return value from metadata key "OS", if it exists
251
function os_icon(metadata) {
252
    if (!metadata) {
253
        return 'unknown';
254
    }
255

256
    if (metadata.values.OS == undefined || metadata.values.OS == '') {
257
        return 'unknown';
258
    } else {
259
        if (UrlExists("static/machines/" + metadata.values.OS + '-on.png')) {
260
            return metadata.values.OS;
261
        } else {
262
            return 'unknown';
263
        }
264
    }
265

266
} 
267

268
//helper function to check file existance
269
function UrlExists(url)
270
{
271
    var http = new XMLHttpRequest();
272
    http.open('HEAD', url, false);
273
    http.send();
274
    return http.status!=404;
275
}
276

277

278
// switch to list view
279
$("a#list").click(function(){
280
    list_view(); 
281
    return false;
282
});
283

284
// switch to standard view
285
$("a#standard").click(function(){
286
    standard_view();
287
    return false;
288
});
289

290
// launch VM creation wizard
291
$("a#create").click(function(){
292
    // launch wizard only if images and flavors are found
293
    if (images.length > 0  && flavors.length > 0) {
294
        $("#wizard").scrollable().begin();
295
        $("#wizard").show();
296
        $('a#create').data('overlay').load()   
297
    } else if (images.length == 0 ) {
298
        ajax_error('NO_IMAGES');
299
        return false;   
300
    } else if (flavors.length == 0) {
301
        ajax_error('NO_FLAVORS');
302
        return false;
303
    }
304
});
305

306
// create wizard overlay
307
$(function() { 
308
    $("a#create").overlay({
309
        mask: '#000', 
310
        effect: 'default', 
311
        top: '5%', 
312
        oneInstance: false,
313
        closeOnClick: false
314
    });
315
});
316

317
// wizard
318
$(function() {
319
    var root = $("#wizard").scrollable();
320
    var api = root.scrollable();
321
    // rangeinput with default configuration
322
    // validation logic is done inside the onBeforeSeek callback
323
    api.onBeforeSeek(function(event, i) {
324
            // we are going 1 step backwards so no need for validation
325
            if (api.getIndex() < i) {
326
             // 1. get current page
327
                     var page = root.find(".page").eq(api.getIndex()),
328
                         // 2. .. and all required fields inside the page
329
                         inputs = page.find(".required :input").removeClass("error"),
330
                         // 3. .. which are empty
331
                         empty = inputs.filter(function() {
332
                                return $(this).val().replace(/\s*/g, '') == '';
333
                         });
334
                     // if there are empty fields, then
335
                    if (empty.length) {
336
                            // add a CSS class name "error" for empty & required fields
337
                            empty.addClass("error");
338
                            // cancel seeking of the scrollable by returning false
339
                            return false;
340
                    // everything is good
341
                    } 
342
            } 
343
        // update confirm step
344
        if (api.getIndex()==0) {
345
            var image = $("input[type=radio][name=image-id]:checked");
346
            var imageRef = image.length ? image[0].id : false
347
            if (imageRef) {
348
                var imageName = $("label[for=" + imageRef + "] .image-title").text();
349
                $("#machine_image-label")[0].textContent = imageName;
350
                $("input[type=text][name=machine_name]")[0].value = "My " + imageName + " server";
351
            }
352
        } else if (api.getIndex()==1) {
353
            $("#machine_cpu-label")[0].textContent = $("#cpu-indicator")[0].value;
354
            $("#machine_ram-label")[0].textContent = $("#ram-indicator")[0].value;
355
            $("#machine_storage-label")[0].textContent = $("#storage-indicator")[0].value;
356
        }   
357
    });
358
    api.onSeek(function(event, i) {
359
            // update status bar
360
            $("#status li").removeClass("active").eq(i).addClass("active");
361
    });
362
    // if tab is pressed on the next button seek to next page
363
    $(root).live('keydown', function (e) {
364
       if ( e.keyCode == 9 ){
365
           if(e.preventDefault) {
366
               e.preventDefault();
367
           }
368
           api.next();
369
        }
370
    });
371
    //submit wizard by pressing enter on the name textbox
372
    $("#name").keypress(function (e) {
373
                if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
374
                        $('#start').click();
375
                        return false;
376
                } else {
377
                        return true;
378
                }
379
    });
380
});
381

382
// disable sliders in flavor selection
383
function disableSliders() {
384
    $("#cpu").attr('disabled',true);
385
    $("#ram").attr('disabled',true);
386
    $("#storage").attr('disabled',true);
387
}
388

389
//update radio button when clicking on text
390
$("#small-body").live('click' ,function() { 
391
    $(this).parent().find("#small").click();
392
});
393
$("#medium-body").live('click' ,function() { 
394
    $(this).parent().find("#medium").click();
395
});
396
$("#large-body").live('click' ,function() { 
397
    $(this).parent().find("#large").click();
398
});
399
$("#custom-body").live('click' ,function() { 
400
    $(this).parent().find("#custom").click();
401
});
402

403
//select image div on radio button select
404
$('.radio').live('click' ,function() {           
405
    $(this).parents("div").find(".image").removeClass('selecteddiv');
406
    if($(this).is(':checked'))  {
407
        $(this).parent().addClass('selecteddiv');
408
    }
409
    
410
});
411

412
// validate cpu input box
413
$("#cpu-indicator").live('change',function(){
414
    var v = Number(this.value);
415
    var i = cpus.indexOf(v);
416
    if (isNaN(v)) {
417
        $(this).value = cpus[0];
418
        $("#cpu").data('rangeinput').setValue(0);
419
    } else if (i == -1) {
420
        for (var j=0; j < cpus.length; j++)
421
            if (v<cpus[j])
422
                break;
423
        $("#cpu").data('rangeinput').setValue(j);
424
    } else {
425
        $("#cpu").data('rangeinput').setValue(i);
426
    }   
427
    return false;
428
});
429

430
// validate ram input box
431
$("#ram-indicator").live('change',function(){
432
    var v = Number(this.value);
433
    var i = ram.indexOf(v);
434
    if (isNaN(v)) {
435
        $(this).value = cpus[0];
436
        $("#ram").data('rangeinput').setValue(0);
437
    } else if (i == -1) {
438
        for (var j=0; j < ram.length; j++)
439
            if (v<ram[j])
440
                break;
441
        $("#ram").data('rangeinput').setValue(j);
442
    } else {
443
        $("#ram").data('rangeinput').setValue(i);
444
    }   
445
    return false;
446
});
447

448

449
// validate storage input box
450
$("#storage-indicator").live('change',function(){
451
    var v = Number(this.value);
452
    var i = disks.indexOf(v);
453
    if (isNaN(v)) {
454
        $(this).value = disks[0];
455
        $("#storage").data('rangeinput').setValue(0);
456
    } else if (i == -1) {
457
        for (var j=0; j < disks.length; j++)
458
            if (v<disks[j])
459
                break;
460
        $("#storage").data('rangeinput').setValue(j);
461
    } else {
462
        $("#storage").data('rangeinput').setValue(i);
463
    }   
464
    return false;
465
});
466

467
// selecting the small size
468
$("#small").click(function(){
469
    $("#cpu").data('rangeinput').setValue(0);
470
    $("#ram").data('rangeinput').setValue(0);
471
    $("#storage").data('rangeinput').setValue(0);
472
    $("#cpu-indicator")[0].value = cpus[0];
473
    $("#ram-indicator")[0].value = ram[0];
474
    $("#storage-indicator")[0].value = disks[0];
475
    $("#small").addClass("active");
476
    $("#medium").removeClass("active");    
477
    $("#large").removeClass("active");    
478
    $("#custom").removeClass("active");    
479
});
480

481
// selecting the medium size
482
$("#medium").click(function(){
483
    $("#cpu").data('rangeinput').setValue(1);
484
    $("#ram").data('rangeinput').setValue(1);
485
    $("#storage").data('rangeinput').setValue(1);
486
    $("#cpu-indicator")[0].value = cpus[1];
487
    $("#ram-indicator")[0].value = ram[1];
488
    $("#storage-indicator")[0].value = disks[1];  
489
    $("#medium").addClass("active");  
490
    $("#small").removeClass("active");    
491
    $("#large").removeClass("active");    
492
    $("#custom").removeClass("active");  
493
});
494

495
// selecting the large size
496
$("#large").click(function(){
497
    $("#cpu").data('rangeinput').setValue(2);
498
    $("#ram").data('rangeinput').setValue(2);
499
    $("#storage").data('rangeinput').setValue(2);
500
    $("#cpu-indicator")[0].value = cpus[2];
501
    $("#ram-indicator")[0].value = ram[2];
502
    $("#storage-indicator")[0].value = disks[2];   
503
    $("#large").addClass("active"); 
504
    $("#medium").removeClass("active");    
505
    $("#small").removeClass("active");    
506
    $("#custom").removeClass("active");  
507
});
508

509
// selecting the custom flavor enables the sliders
510
$("#custom").click(function(){
511
    $("#cpu").attr('disabled',false);
512
    $("#ram").attr('disabled',false);
513
    $("#storage").attr('disabled',false);
514
    $("strong.sliders").style = 'color: #778899;';
515
    $("#custom input").attr('checked', 'checked');                
516
    $("#custom").addClass("active"); 
517
    $("#medium").removeClass("active");    
518
    $("#large").removeClass("active");    
519
    $("#small").removeClass("active");  
520
});
521

522
//when textbox gains focus, add selection in css
523
$('#cpu-indicator').focus(function() {
524
    $(this).addClass('selectedrange');
525
});
526
$('#ram-indicator').focus(function() {
527
    $(this).addClass('selectedrange');
528
});
529
$('#storage-indicator').focus(function() {
530
    $(this).addClass('selectedrange');
531
});
532

533
//when textbox loses focus, clear selection in css
534
$('#cpu-indicator').blur(function() {
535
    $(this).removeClass('selectedrange');
536
});
537
$('#ram-indicator').blur(function() {
538
    $(this).removeClass('selectedrange');
539
});
540
$('#storage-indicator').blur(function() {
541
    $(this).removeClass('selectedrange');
542
});
543

544
// exit the wizard
545
$("#cancel").click(function(){
546
    $("a#create").overlay().close();
547
});
548

549
// starting a new VM through the wizard
550
$("#start").click(function(){
551
    var imageRef = $('input[type=radio][name=image-id]:checked')[0].id.replace('img-radio-','');   
552
    var flavorRef = identify_flavor($("#cpu-indicator")[0].value, $("#storage-indicator")[0].value, $("#ram-indicator")[0].value);
553
    var machineName = $('input[name=machine_name]')[0].value;
554
    if (jQuery.trim(machineName) == ''){
555
        return false;
556
    }
557
    create_vm(machineName, imageRef, flavorRef);
558

559
    $('a#create').data('overlay').close();
560

561
    try{console.warn('creating ' + $("input[name=machine_name]")[0].value)} catch(err){}
562

563
    $("#wizard").hide();
564
});
565

566
// confirm all actions
567
$("div.confirm_multiple .yes").live('click', function(){
568
    while(pending_actions.length > 0){ // if there is a pending action for this server execute it
569
        action = pending_actions.pop(); // extract action
570
        var serverID = action[1];
571
        if ($.cookie("list") != '1') { // standard view
572
            $('#' + serverID + ' .selected').removeClass('selected');
573
            $('#' + serverID + ' .display').removeClass('display');
574
            if (action[0] == shutdown) {
575
                $('#' + serverID + ' .status').text('Shutting down');
576
            } else if (action[0] == start) {
577
                $('#' + serverID + ' .status').text('Starting');
578
            } else if (action[0] == reboot) {
579
                $('#' + serverID + ' .status').text('Rebooting');
580
            } else if (action[0] == destroy) {
581
                $('#' + serverID + ' .status').text('Destroying');
582
            }
583
            $('#' + serverID + ' .spinner').show();
584
        } else { // list view
585
            osIcon = $('#'+serverID).parent().parent().find('.list-logo');
586
            osIcon.attr('os',osIcon.attr('src'));
587
            osIcon.attr('src','static/progress.gif');
588
            if (action[0] == shutdown) {
589
                $('#' + serverID).parent().parent().find('span.status').text('Shutting down');
590
            } else if (action[0] == start) {
591
                $('#' + serverID).parent().parent().find('span.status').text('Starting');
592
            } else if (action[0] == reboot) {
593
                $('#' + serverID).parent().parent().find('span.status').text('Rebooting');
594
            } else if (action[0] == destroy) {
595
                $('#' + serverID).parent().parent().find('span.status').text('Destroying');
596
            }
597
        }
598
        action[0]([serverID]); // execute action
599
    }
600
    update_confirmations();    
601
});
602

603
// cancel all actions
604
$("div.confirm_multiple .no").live('click', function(){
605
    pending_actions = [];
606
    $('.machine .selected').removeClass('selected');
607
    $('.machine .display').removeClass('display');
608
    update_confirmations();
609
});
610

611
// bring up edit metadata overlay
612
function show_metadata_edit_dialog() {
613
    var triggers = $("a#metadata-edit-dialog").overlay({
614
        // some mask tweaks suitable for modal dialogs
615
        mask: '#000',
616
        effect: 'default',
617
        top: '10%',
618
        closeOnClick: false,
619
        oneInstance: false,
620
        load: false,
621
        onClose: function() {
622
            // remove all entries so they won't be preloaded next time you open the dialog
623
            $("#edit-dialog div.content ul.meta-list").empty();
624
        },
625
        onLoad: function() {
626
            // this is a workaround for the mask not appearing problem
627
            $("#edit-dialog").expose();
628
        }
629
    });
630
    // get metadata for current server and fill the dialog
631
    serverID = $("#edit-dialog h3 p").text();
632
    get_metadata(serverID);
633
    $("a#metadata-edit-dialog").data('overlay').load();
634
    return false; 
635
}
636

637
// bring up add metadata overlay
638
function show_metadata_add_dialog() {
639
    var triggers = $("a#metadata-add-dialog").overlay({
640
        // some mask tweaks suitable for modal dialogs
641
        mask: '#000',
642
        effect: 'default',
643
        top: '10%',
644
        closeOnClick: false,
645
        oneInstance: false,
646
        load: false,
647
        onLoad: function() {
648
            // this is a workaround for the mask not appearing problem
649
            $("#add-dialog").expose();
650
        },
651
        onClose: function(){
652
            // reset input areas
653
            $(".meta-modal input.key").removeClass("input-enabled");
654
            $(".meta-modal input.key")[0].value = 'max 15 characters';
655
            $(".meta-modal textarea.value").removeClass("input-enabled");
656
            $(".meta-modal textarea.value")[0].value = 'max 150 characters';
657
            show_metadata_edit_dialog();        
658
        }
659
    });
660
    $("a#metadata-add-dialog").data('overlay').load();
661
    return false; 
662
}
663

664
// trapping keydown event
665
jQuery.expr[':'].focus = function( elem ) {
666
  return elem === document.activeElement && ( elem.type || elem.href );
667
};
668

669
$('*').keydown(function (){
670
    if ($('#add-dialog').is(":visible") && !($('input.key').is(':focus') || $('textarea.value').is(':focus'))){
671
        $('input.key').focus();
672
        $('input.key').focusin();         
673
    }
674
    return true;
675
});
676

677
// intercept click on create button in metadata edit dialog
678
$('#edit-dialog.meta-modal button.create').click( function(){
679
    // close edit metadata and open add metadata dialog
680
    $('a#metadata-edit-dialog').data('overlay').close();
681
    show_metadata_add_dialog();
682
});
683

684
// intercept click on remove button in metadata edit dialog
685
$('#edit-dialog.meta-modal button.remove').live('click', function() { 
686
    // get the server id and meta key needed for the ajax call   
687
    var serverID = $(this).closest('div.container').find('h3 p').text();
688
    var meta_key = $(this).parent().find('label').text();
689
    // make the ajax call and list the new GET results
690
    delete_metadata(serverID, meta_key);
691
    return false;
692
});
693

694
// intercept click on edit button in metadata edit dialog
695
$('#edit-dialog.meta-modal button.edit').click( function(){
696
    // inline editing of selected key-value pair
697
    // on submission ajax call from updating
698
    // on success update the overlay
699
    // TODO
700
});
701

702
// intercept click on cancel button in metadata add dialog
703
$('#add-dialog.meta-modal button.cancel').click( function(){
704
    // close add metadata and open edit metadata dialog
705
    $('a#metadata-add-dialog').data('overlay').close();
706
});
707

708
// intercept create metadata key focus
709
$(".meta-modal input.key").live('focusin', function() {
710
    if ($(this).hasClass("input-enabled")) {
711
    } else {
712
        $(".meta-modal input.key").addClass("input-enabled"); 
713
        $(this).addClass("input-enabled"); 
714
        this.value = '';
715
    }
716
    return false;
717
});
718

719
// intercept create metadata key focus out
720
$(".meta-modal input.key").live('focusout', function() {
721
    if (this.value == "") {
722
        $(this).removeClass("input-enabled"); 
723
        this.value = 'max 15 characters';
724
    }
725
    return false;
726
});
727

728
// intercept create metadata key focus
729
$(".meta-modal textarea.value").live('focusin', function() {
730
    if ($(this).hasClass("input-enabled")) {
731
    } else {
732
        $(".meta-modal textarea.value").addClass("input-enabled"); 
733
        $(this).addClass("input-enabled"); 
734
        this.value = '';
735
    }
736
    return false;
737
});
738

739
// intercept create metadata key focus out
740
$(".meta-modal textarea.value").live('focusout', function() {
741
    if (this.value == "") {
742
        $(this).removeClass("input-enabled"); 
743
        this.value = 'max 150 characters';
744
    }
745
    return false;
746
});
747

748
// intercept click on save button in metadata add dialog
749
$('#add-dialog.meta-modal button.save').live('click', function() {
750
    // if both fields are filled in     
751
    if ($('input.key').hasClass("input-enabled") && $('textarea.value').hasClass("input-enabled")) {
752
        // get the server id, meta key and meta value needed for the ajax call     
753
        var serverID = $(this).parent().find('h3 p').text();
754
        var meta_key = $(this).parent().find('input.key').attr('value');
755
        var meta_value = $(this).parent().find('textarea.value')[0].value;
756
        // make the ajax call and list the new GET results
757
        add_metadata(serverID, meta_key, meta_value);
758
        // close add metadata and open edit metadata dialog
759
        $('a#metadata-add-dialog').data('overlay').close();
760
        show_metadata_edit_dialog();
761
    } else {
762
        // find which field is not filled in and focus there
763
        if (!$('input.key').hasClass("input-enabled")) {
764
            $('input.key').focus();
765
            $('input.key').focusin();
766
        } else {
767
            $('textarea.value').focus();
768
            $('textarea.value').focusin();
769
        }
770
    }
771
    return false;
772
});
773

774
// update metadata in edit dialog
775
function list_metadata(data) {    
776
    // empty the list if it already exists
777
    $("#edit-dialog div.content ul.meta-list").empty();
778
    // get the values to show
779
    meta = data.metadata.values;
780
    // show values
781
    for (key in meta) {
782
        pair = $("ul.meta-template li").clone();
783
        //truncate metadata
784
        pair.find("label").text(key.substring(0,15));
785
        if (meta[key].length > 25) {
786
            pair.find("p").text(meta[key].substring(0,25) + "...");
787
        } else {
788
            pair.find("p").text(meta[key]);            
789
        }
790
        pair.appendTo("#edit-dialog div.content ul.meta-list").fadeIn();
791
    }
792
}
793

794
// basic functions executed on page load
795
if (images.length > 0) {
796
    // populate image list
797
    update_wizard_images();
798
}
799
if (flavors.length > 0) {
800
    // configure flavors
801
    update_wizard_flavors(); 
802
}
803
// create tabs for main menu
804
$("ul.tabs").tabs("div.panes ul");
805

    
806
</script>