Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ db234816

History | View | Annotate | Download (26.4 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="meta-editor-1" rel="#editor-1" href="#"></a>
179

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

    
206
<a id="meta-editor-2" rel="#editor-2" href="#"></a>
207

    
208
<div class="meta-modal" id="editor-2">
209
    <div class='container'>
210
        <h3>
211
            <label>{% trans "Metadata for machine:" %}</label>
212
            <span></span>
213
        </h3>
214
        <hr class="topruler" />
215
        <hr class="fatruler" />
216
        <div class="content">
217
            <label class="meta-key">{% trans "Key:" %}</label>
218
            <input type="text" maxlength="15" class="key" value="max 15 characters"/>
219
            <hr class="meta-separator">
220
            <label class="meta-value">{% trans "Value:" %}</label>
221
            <input type="text" maxlength="150" class="value" value="max 150 characters"/>
222
        </div>
223
    </div>
224
    <button type="button" class="cancel">{% trans "Cancel" %}</button>
225
    <button type="button" class="save">{% trans "Save" %}</button>
226
    <div class="bottomruler" /> 
227
</div>
228

    
229
<div id="machinesview"></div>
230

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

    
237
<div id="machines" class="separator"></div>
238

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

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

254
    if (metadata.values.OS == undefined || metadata.values.OS == '') {
255
        return 'unknown';
256
    } else {
257
        return metadata.values.OS;
258
    }
259
} 
260

261
// switch to list view
262
$("a#list").click(function(){
263
    list_view(); 
264
    return false;
265
});
266

267
// switch to standard view
268
$("a#standard").click(function(){
269
    standard_view();
270
    return false;
271
});
272

273
// launch VM creation wizard
274
$("a#create").click(function(){
275
    // launch wizard only if images and flavors are found
276
    if (images.length > 0  && flavors.length > 0) {
277
        $("#wizard").scrollable().begin();
278
        $("#wizard").show();
279
        $('a#create').data('overlay').load()   
280
    } else if (images.length == 0 ) {
281
        ajax_error('NO_IMAGES');
282
        return false;   
283
    } else if (flavors.length == 0) {
284
        ajax_error('NO_FLAVORS');
285
        return false;
286
    }
287
});
288

289
// create wizard overlay
290
$(function() { 
291
    $("a#create").overlay({
292
        mask: '#000', 
293
        effect: 'default', 
294
        top: '5%', 
295
        oneInstance: false,
296
        closeOnClick: false
297
    });
298
});
299

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

365
// disable sliders in flavor selection
366
function disableSliders() {
367
    $("#cpu").attr('disabled',true);
368
    $("#ram").attr('disabled',true);
369
    $("#storage").attr('disabled',true);
370
}
371

372
//update radio button when clicking on text
373
$("#small-body").live('click' ,function() { 
374
    $(this).parent().find("#small").click();
375
});
376
$("#medium-body").live('click' ,function() { 
377
    $(this).parent().find("#medium").click();
378
});
379
$("#large-body").live('click' ,function() { 
380
    $(this).parent().find("#large").click();
381
});
382
$("#custom-body").live('click' ,function() { 
383
    $(this).parent().find("#custom").click();
384
});
385

386
//select image div on radio button select
387
$('.radio').live('click' ,function() {           
388
    $(this).parents("div").find(".image").removeClass('selecteddiv');
389
    if($(this).is(':checked'))  {
390
        $(this).parent().addClass('selecteddiv');
391
    }
392
    
393
});
394

395
// validate cpu input box
396
$("#cpu-indicator").live('change',function(){
397
    var v = Number(this.value);
398
    var i = cpus.indexOf(v);
399
    if (isNaN(v)) {
400
        $(this).value = cpus[0];
401
        $("#cpu").data('rangeinput').setValue(0);
402
    } else if (i == -1) {
403
        for (var j=0; j < cpus.length; j++)
404
            if (v<cpus[j])
405
                break;
406
        $("#cpu").data('rangeinput').setValue(j);
407
    } else {
408
        $("#cpu").data('rangeinput').setValue(i);
409
    }   
410
    return false;
411
});
412

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

431

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

450
// selecting the small size
451
$("#small").click(function(){
452
    $("#cpu").data('rangeinput').setValue(0);
453
    $("#ram").data('rangeinput').setValue(0);
454
    $("#storage").data('rangeinput').setValue(0);
455
    $("#cpu-indicator")[0].value = cpus[0];
456
    $("#ram-indicator")[0].value = ram[0];
457
    $("#storage-indicator")[0].value = disks[0];
458
    $("#small").addClass("active");
459
    $("#medium").removeClass("active");    
460
    $("#large").removeClass("active");    
461
    $("#custom").removeClass("active");    
462
});
463

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

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

492
// selecting the custom flavor enables the sliders
493
$("#custom").click(function(){
494
    $("#cpu").attr('disabled',false);
495
    $("#ram").attr('disabled',false);
496
    $("#storage").attr('disabled',false);
497
    $("strong.sliders").style = 'color: #778899;';
498
    $("#custom input").attr('checked', 'checked');                
499
    $("#custom").addClass("active"); 
500
    $("#medium").removeClass("active");    
501
    $("#large").removeClass("active");    
502
    $("#small").removeClass("active");  
503
});
504

505
//when textbox gains focus, add selection in css
506
$('#cpu-indicator').focus(function() {
507
    $(this).addClass('selectedrange');
508
});
509
$('#ram-indicator').focus(function() {
510
    $(this).addClass('selectedrange');
511
});
512
$('#storage-indicator').focus(function() {
513
    $(this).addClass('selectedrange');
514
});
515

516
//when textbox loses focus, clear selection in css
517
$('#cpu-indicator').blur(function() {
518
    $(this).removeClass('selectedrange');
519
});
520
$('#ram-indicator').blur(function() {
521
    $(this).removeClass('selectedrange');
522
});
523
$('#storage-indicator').blur(function() {
524
    $(this).removeClass('selectedrange');
525
});
526

527
// exit the wizard
528
$("#cancel").click(function(){
529
    $("a#create").overlay().close();
530
});
531

532
// starting a new VM through the wizard
533
$("#start").click(function(){
534
    var imageRef = $('input[type=radio][name=image-id]:checked')[0].id.replace('img-radio-','');   
535
    var flavorRef = identify_flavor($("#cpu-indicator")[0].value, $("#storage-indicator")[0].value, $("#ram-indicator")[0].value);
536
    var machineName = $('input[name=machine_name]')[0].value;
537
    if (jQuery.trim(machineName) == ''){
538
        return false;
539
    }
540
    create_vm(machineName, imageRef, flavorRef);
541

542
    $('a#create').data('overlay').close();
543

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

546
    $("#wizard").hide();
547
});
548

549
// confirm all actions
550
$("div.confirm_multiple .yes").live('click', function(){
551
    while(pending_actions.length > 0){ // if there is a pending action for this server execute it
552
        action = pending_actions.pop(); // extract action
553
        var serverID = action[1];
554
        if ($.cookie("list") != '1') { // standard view
555
            $('#' + serverID + ' .selected').removeClass('selected');
556
            $('#' + serverID + ' .display').removeClass('display');
557
            if (action[0] == shutdown) {
558
                $('#' + serverID + ' .status').text('Shutting down');
559
            } else if (action[0] == start) {
560
                $('#' + serverID + ' .status').text('Starting');
561
            } else if (action[0] == reboot) {
562
                $('#' + serverID + ' .status').text('Rebooting');
563
            } else if (action[0] == destroy) {
564
                $('#' + serverID + ' .status').text('Destroying');
565
            }
566
            $('#' + serverID + ' .spinner').show();
567
        } else { // list view
568
            osIcon = $('#'+serverID).parent().parent().find('.list-logo');
569
            osIcon.attr('os',osIcon.attr('src'));
570
            osIcon.attr('src','static/progress.gif');
571
            if (action[0] == shutdown) {
572
                $('#' + serverID).parent().parent().find('span.status').text('Shutting down');
573
            } else if (action[0] == start) {
574
                $('#' + serverID).parent().parent().find('span.status').text('Starting');
575
            } else if (action[0] == reboot) {
576
                $('#' + serverID).parent().parent().find('span.status').text('Rebooting');
577
            } else if (action[0] == destroy) {
578
                $('#' + serverID).parent().parent().find('span.status').text('Destroying');
579
            }
580
        }
581
        action[0]([serverID]); // execute action
582
    }
583
    update_confirmations();    
584
});
585

586
// cancel all actions
587
$("div.confirm_multiple .no").live('click', function(){
588
    pending_actions = [];
589
    $('.machine .selected').removeClass('selected');
590
    $('.machine .display').removeClass('display');
591
    update_confirmations();
592
});
593

594
// bring up edit metadata overlay
595
function editMetadata() {
596
    var triggers = $("a#meta-editor-1").overlay({
597
        // some mask tweaks suitable for modal dialogs
598
        mask: '#000',
599
        effect: 'default',
600
        top: '10%',
601
        closeOnClick: false,
602
        oneInstance: false,
603
        load: false,
604
        onClose: function() {
605
            // remove all entries so they won't be preloaded next time you open the dialog
606
            $("#editor-1 div.content ul.meta-list").empty();
607
        },
608
        onLoad: function() {
609
            // this is a workaround for the mask not appearing problem
610
            $("#editor-1").expose();
611
        }
612
    });
613
    // get metadata for current server and fill the dialog
614
    serverID = $("#editor-1 h3").attr('id');
615
    get_metadata(serverID);
616
    $("a#meta-editor-1").data('overlay').load();
617
    return false; 
618
}
619

620
// bring up add metadata overlay
621
function addMetadata() {
622
    var triggers = $("a#meta-editor-2").overlay({
623
        // some mask tweaks suitable for modal dialogs
624
        mask: '#000',
625
        effect: 'default',
626
        top: '10%',
627
        closeOnClick: false,
628
        oneInstance: false,
629
        load: false,
630
        onLoad: function() {
631
            // this is a workaround for the mask not appearing problem
632
            $("#editor-2").expose();
633
        }
634
    });
635
    $("a#meta-editor-2").data('overlay').load();
636
    return false; 
637
}
638

639
// intercept click on create button in metadata edit dialog
640
$('#editor-1.meta-modal button.create').click( function(){
641
    // close edit metadata and open add metadata dialog
642
    $('a#meta-editor-1').data('overlay').close();
643
    addMetadata();
644
});
645

646
// intercept click on remove button in metadata edit dialog
647
$('#editor-1.meta-modal button.remove').live('click', function() { 
648
    // get the server id and meta key needed for the ajax call   
649
    var serverID = $(this).closest('div.container').children('h3').attr('id');
650
    var meta_key = $(this).parent().find('label').text();
651
    // make the ajax call and list the new GET results
652
    delete_metadata(serverID, meta_key);
653
    return false;
654
});
655

656
// intercept click on edit button in metadata edit dialog
657
$('#editor-1.meta-modal button.edit').click( function(){
658
    // inline editing of selected key-value pair
659
    // on submission ajax call from updating
660
    // on success update the overlay
661
    // TODO
662
});
663

664
// intercept click on cancel button in metadata add dialog
665
$('#editor-2.meta-modal button.cancel').click( function(){
666
    // close add metadata and open edit metadata dialog
667
    $('a#meta-editor-2').data('overlay').close();
668
    editMetadata();
669
});
670

671
// intercept click on save button in metadata add dialog
672
$('#editor-2.meta-modal button.save').live('click', function() {
673
    // get the server id, meta key and meta value needed for the ajax call       
674
    var serverID = $(this).parent().find('h3').attr('id');
675
    var meta_key = $(this).parent().find('input.key').attr('value');
676
    var meta_value = $(this).parent().find('input.value').attr('value');
677
    // make the ajax call and list the new GET results
678
    add_metadata(serverID, meta_key, meta_value);
679
    // close add metadata and open edit metadata dialog
680
    $('a#meta-editor-2').data('overlay').close();
681
    editMetadata();
682
    return false;
683
});
684

685
// update metadata in edit dialog
686
function list_metadata(data) {    
687
    // empty the list if it already exists
688
    $("#editor-1 div.content ul.meta-list").empty();
689
    // get the values to show
690
    meta = data.metadata.values;
691
    // show values
692
    for (key in meta) {
693
        pair = $("ul.meta-template li").clone();
694
        pair.find("label").text(key.substring(0,15));
695
        pair.find("p").text(meta[key].substring(0,30));
696
        pair.appendTo("#editor-1 div.content ul.meta-list").fadeIn();
697
    }
698
}
699

700
// basic functions executed on page load
701
if (images.length > 0) {
702
    // populate image list
703
    update_wizard_images();
704
}
705
if (flavors.length > 0) {
706
    // configure flavors
707
    update_wizard_flavors(); 
708
}
709
// create tabs for main menu
710
$("ul.tabs").tabs("div.panes ul");
711

    
712
</script>