Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ 5784dfe4

History | View | Annotate | Download (32 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">
19
    <h1 id="welcomeheader">{% trans "Welcome to the ocean!" %}</h1>
20
    <br />
21
    <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>
22
    <br />
23
    <br />
24
    <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>
25
    <br />
26
    <br />
27
    <span class="welcomefooter">{% trans "For more information or help, click " %}<a href="#">{% trans "here" %}</a>.</span>
28
</div>
29

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

    
184
<!-- base notification for error/success reporting -->
185
<a id="notification" rel="#error-success" href="#"></a>
186

    
187
<div class="modal" id="error-success">
188
    <h3>{% trans "Error!/Success!" %}</h3>
189
    <div><p>{% trans "More details about the result"%}</p></div>
190
</div>
191

    
192
<!-- metadata scrollable -->
193
<div>
194
    <!-- root element for scrollable -->
195
    <div id="metadata-wizard">
196

    
197
        <!-- root element for the items -->
198
        <div class="items">
199
            <div class="page" id="edit-dialog">
200
                <div class='container'>
201
                    <h3>
202
                        <label>{% trans "Tags for machine:" %}</label>
203
                        <span>Server name</span>
204
                        <p style='display:none;'>hidden server id</p>
205
                    </h3>
206
                    <hr class="topruler" />
207
                    <hr class="fatruler" />
208
                    <div class="content">
209
                        <ul class="meta-template" style="display:none">
210
                            <li>
211
                                <label>{% trans "Key" %}</label>
212
                                <button type="button" class="remove">{% trans "remove x" %}</button>
213
                                <hr class="meta-separator">
214
                                <p>{% trans "Value" %}</p>
215
                                <button type="button" class="edit">{% trans "edit" %}</button>
216
                                <button type="button" class="cancel">{% trans "cancel" %}</button>
217
                                <button type="button" class="save">{% trans "save" %}</button>
218
                            </li>
219
                        </ul>
220
                        <ul class="meta-list">
221
                        </ul>
222
                    </div>
223
                </div>
224
                <button type="button" class="create next browse right">{% trans "Create New+" %}</button>
225
                <div class="bottomruler"></div>
226
            </div>
227
            <div class="page" id="add-dialog">
228
                <div class='container'>
229
                    <h3>
230
                        <label>{% trans "Tags for machine:" %}</label>
231
                        <span>Server name</span>
232
                        <p style='display:none;'>hidden server id</p>
233
                    </h3>
234
                    <hr class="topruler" />
235
                    <hr class="fatruler" />
236
                    <div class="content">
237
                        <label class="meta-key">{% trans "Key:" %}</label>
238
                        <input type="text" maxlength="15" class="key" value="{% trans 'max 15 characters' %}"/>
239
                        <hr class="meta-separator">
240
                        <label class="meta-value">{% trans "Value:" %}</label>
241
                        <textarea class="value">{% trans "max 150 characters" %}</textarea>
242
                    </div>
243
                </div>
244
                <button type="button" class="cancel prev browse left">{% trans "Cancel" %}</button>
245
                <button type="button" class="save">{% trans "Save" %}</button>
246
                <div class="bottomruler"></div>
247
            </div>
248
        </div>
249
    </div>
250
</div>
251

    
252
<a id="metadata-scrollable" href="#" rel="#metadata-wizard"></a>
253

    
254
<div id="machinesview"></div>
255

    
256
<div class="confirm_multiple">
257
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "machines" %}</p>
258
    <button class="yes">{% trans "Confirm All" %}</button>
259
        <button class="no">{% trans "Cancel All" %}</button>
260
</div>
261

    
262
<div id="machines" class="separator"></div>
263

    
264
<script>
265

266
//add hover to labels
267
$('span.typebody').mouseover(function() {
268
    $(this).addClass('typehover');
269
});
270
$('span.typebody').mouseout(function() {
271
    $(this).removeClass('typehover');
272
});
273

274
// return value from metadata key "OS", if it exists
275
function os_icon(metadata) {
276
    if (!metadata) {
277
        return 'unknown';
278
    }
279

280
    if (metadata.values.OS == undefined || metadata.values.OS == '') {
281
        return 'unknown';
282
    } else {
283
        if (UrlExists("static/machines/" + metadata.values.OS + '-on.png')) {
284
            return metadata.values.OS;
285
        } else {
286
            return 'unknown';
287
        }
288
    }
289
} 
290

291
//helper function to check file existance
292
function UrlExists(url)
293
{
294
    var http = new XMLHttpRequest();
295
    http.open('HEAD', url, false);
296
    http.send();
297
    return http.status!=404;
298
}
299

300
// switch to list view
301
$("a#list").click(function(){
302
    list_view(); 
303
    return false;
304
});
305

306
// switch to standard view
307
$("a#standard").click(function(){
308
    standard_view();
309
    return false;
310
});
311

312
// launch VM creation wizard
313
$("a#create").click(function(){
314
    // launch wizard only if images and flavors are found
315
    if (images.length > 0  && flavors.length > 0) {
316
        $("#wizard").scrollable().begin();
317
        $("#wizard").show();
318
        $('a#create').data('overlay').load()   
319
    } else if (images.length == 0 ) {
320
        ajax_error('NO_IMAGES');
321
        return false;   
322
    } else if (flavors.length == 0) {
323
        ajax_error('NO_FLAVORS');
324
        return false;
325
    }
326
});
327

328
// create wizard overlay
329
$(function() { 
330
    $("a#create").overlay({
331
        mask: '#000', 
332
        effect: 'default', 
333
        top: '5%', 
334
        oneInstance: false,
335
        closeOnClick: false
336
    });
337
});
338

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

404
// disable sliders in flavor selection
405
function disableSliders() {
406
    $("#cpu").attr('disabled',true);
407
    $("#ram").attr('disabled',true);
408
    $("#storage").attr('disabled',true);
409
}
410

411
//update radio button when clicking on text
412
$("#small-body").live('click' ,function() { 
413
    $(this).parent().find("#small").click();
414
});
415
$("#medium-body").live('click' ,function() { 
416
    $(this).parent().find("#medium").click();
417
});
418
$("#large-body").live('click' ,function() { 
419
    $(this).parent().find("#large").click();
420
});
421
$("#custom-body").live('click' ,function() { 
422
    $(this).parent().find("#custom").click();
423
});
424

425
//select image div on radio button select
426
$('.radio').live('click' ,function() {           
427
    $(this).parents("div").find(".image").removeClass('selecteddiv');
428
    if($(this).is(':checked'))  {
429
        $(this).parent().addClass('selecteddiv');
430
    }
431
    
432
});
433

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

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

470
// validate storage input box
471
$("#storage-indicator").live('change',function(){
472
    var v = Number(this.value);
473
    var i = disks.indexOf(v);
474
    if (isNaN(v)) {
475
        $(this).value = disks[0];
476
        $("#storage").data('rangeinput').setValue(0);
477
    } else if (i == -1) {
478
        for (var j=0; j < disks.length; j++)
479
            if (v<disks[j])
480
                break;
481
        $("#storage").data('rangeinput').setValue(j);
482
    } else {
483
        $("#storage").data('rangeinput').setValue(i);
484
    }   
485
    return false;
486
});
487

488
// selecting the small size
489
$("#small").click(function(){
490
    $("#cpu").data('rangeinput').setValue(0);
491
    $("#ram").data('rangeinput').setValue(0);
492
    $("#storage").data('rangeinput').setValue(0);
493
    $("#cpu-indicator")[0].value = cpus[0];
494
    $("#ram-indicator")[0].value = ram[0];
495
    $("#storage-indicator")[0].value = disks[0];
496
    $("#small").addClass("active");
497
    $("#medium").removeClass("active");    
498
    $("#large").removeClass("active");    
499
    $("#custom").removeClass("active");    
500
});
501

502
// selecting the medium size
503
$("#medium").click(function(){
504
    $("#cpu").data('rangeinput').setValue(1);
505
    $("#ram").data('rangeinput').setValue(1);
506
    $("#storage").data('rangeinput').setValue(1);
507
    $("#cpu-indicator")[0].value = cpus[1];
508
    $("#ram-indicator")[0].value = ram[1];
509
    $("#storage-indicator")[0].value = disks[1];  
510
    $("#medium").addClass("active");  
511
    $("#small").removeClass("active");    
512
    $("#large").removeClass("active");    
513
    $("#custom").removeClass("active");  
514
});
515

516
// selecting the large size
517
$("#large").click(function(){
518
    $("#cpu").data('rangeinput').setValue(2);
519
    $("#ram").data('rangeinput').setValue(2);
520
    $("#storage").data('rangeinput').setValue(2);
521
    $("#cpu-indicator")[0].value = cpus[2];
522
    $("#ram-indicator")[0].value = ram[2];
523
    $("#storage-indicator")[0].value = disks[2];   
524
    $("#large").addClass("active"); 
525
    $("#medium").removeClass("active");    
526
    $("#small").removeClass("active");    
527
    $("#custom").removeClass("active");  
528
});
529

530
// selecting the custom flavor enables the sliders
531
$("#custom").click(function(){
532
    $("#cpu").attr('disabled',false);
533
    $("#ram").attr('disabled',false);
534
    $("#storage").attr('disabled',false);
535
    $("strong.sliders").style = 'color: #778899;';
536
    $("#custom input").attr('checked', 'checked');                
537
    $("#custom").addClass("active"); 
538
    $("#medium").removeClass("active");    
539
    $("#large").removeClass("active");    
540
    $("#small").removeClass("active");  
541
});
542

543
//when textbox gains focus, add selection in css
544
$('#cpu-indicator').focus(function() {
545
    $(this).addClass('selectedrange');
546
});
547
$('#ram-indicator').focus(function() {
548
    $(this).addClass('selectedrange');
549
});
550
$('#storage-indicator').focus(function() {
551
    $(this).addClass('selectedrange');
552
});
553

554
//when textbox loses focus, clear selection in css
555
$('#cpu-indicator').blur(function() {
556
    $(this).removeClass('selectedrange');
557
});
558
$('#ram-indicator').blur(function() {
559
    $(this).removeClass('selectedrange');
560
});
561
$('#storage-indicator').blur(function() {
562
    $(this).removeClass('selectedrange');
563
});
564

565
// exit the wizard
566
$("#cancel").click(function(){
567
    $("a#create").overlay().close();
568
});
569

570
// starting a new VM through the wizard
571
$("#start").click(function(){
572
    var imageRef = $('input[type=radio][name=image-id]:checked')[0].id.replace('img-radio-','');   
573
    var flavorRef = identify_flavor($("#cpu-indicator")[0].value, $("#storage-indicator")[0].value, $("#ram-indicator")[0].value);
574
    var machineName = $('input[name=machine_name]')[0].value;
575
    if (jQuery.trim(machineName) == ''){
576
        return false;
577
    }
578
    create_vm(machineName, imageRef, flavorRef);
579

580
    $('a#create').data('overlay').close();
581

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

584
    $("#wizard").hide();
585
});
586

587
// metadata wizard
588
$(function() {
589
        // initialize scrollable
590
    $("#metadata-wizard").scrollable();
591
    // create wizard overlay
592
    $("a#metadata-scrollable").overlay({
593
        mask: '#000',
594
        effect: 'default',
595
        top: '10%',
596
        closeOnClick: false,
597
        oneInstance: false,
598
        load: false,
599
        onClose: function(){
600
            // reset input areas
601
            reset_metadata_input();
602
        }
603
    });
604
});
605

606
// bring up metadata scrollable
607
function show_metadata_wizard() {
608
    // get metadata for current server and fill the dialog
609
    serverID = $("#edit-dialog h3 p").text();
610
    get_metadata(serverID);
611
    $("#metadata-wizard").scrollable().begin();
612
    $("#metadata-wizard").show();
613
    $("a#metadata-scrollable").data('overlay').load();
614
    return false; 
615
}
616

617
function reset_metadata_input() {
618
    // reset input areas
619
    $("#metadata-wizard input.key").removeClass("input-enabled");
620
    $("#metadata-wizard input.key")[0].value = 'max 15 characters';
621
    $("#metadata-wizard textarea.value").removeClass("input-enabled");
622
    $("#metadata-wizard textarea.value")[0].value = 'max 150 characters';
623
}
624

625
// update metadata list
626
function list_metadata(data) {    
627
    // empty the list if it already exists
628
    $("#edit-dialog div.content ul.meta-list").empty();
629
    // get the values to show
630
    meta = data.metadata.values;
631
    // show values
632
    for (key in meta) {
633
        pair = $("ul.meta-template li").clone();
634
        //truncate metadata
635
        pair.find("label").text(key.substring(0,15));
636
        if (meta[key].length > 25) {
637
            pair.find("p").text(meta[key].substring(0,25) + "...");
638
        } else {
639
            pair.find("p").text(meta[key]);            
640
        }
641
        pair.appendTo("#edit-dialog div.content ul.meta-list").fadeIn();
642
    }
643
}
644

645
// trapping keydown event
646
jQuery.expr[':'].focus = function( elem ) {
647
  return elem === document.activeElement && ( elem.type || elem.href );
648
};
649

650
$('*').keydown(function (){
651
    if ($('#add-dialog').is(":visible") && !$('#edit-dialog input').length && !($('input.key').is(':focus') || $('textarea.value').is(':focus'))){
652
        $('input.key').focus();
653
        $('input.key').focusin(); 
654
    }
655
    return true;
656
});
657

658
// intercept click on remove button in metadata edit dialog
659
$('#edit-dialog button.remove').live('click', function() { 
660
    // get the server id and meta key needed for the ajax call   
661
    var serverID = $(this).closest('div.container').find('h3 p').text();
662
    var meta_key = $(this).parent().find('label').text();
663
    // make the ajax call and list the new GET results
664
    delete_metadata(serverID, meta_key);
665
    return false;
666
});
667

668
// intercept click on edit button in metadata edit dialog
669
$('#edit-dialog button.edit').live('click', function(){
670
    // TODO
671
    // show input form for tag name
672
    $(this).parent().find('label').html("<input type=\"text\" maxlength=\"15\" class=\"edit-meta-key\" value=\"" +
673
                                        $(this).parent().find('label').text() + 
674
                                        "\" / ><label class=\"oldValue\">" + 
675
                                        $(this).parent().find('label').text() + "</label>");
676
    // show input form for tag value
677
    $(this).parent().find('p').html("<textarea class=\"edit-meta-value\" l=\"3\">" +
678
                                        $(this).parent().find('p').text() + 
679
                                        "</textarea><p class=\"oldValue\">" + 
680
                                        $(this).parent().find('p').text() + "</p>");
681
    // show/hide the appropriate buttons
682
    $(this).hide(); // this button (edit)
683
    $(this).siblings().show(); // save and cancel buttons
684
    $(this).siblings('button.remove').addClass('more-margin');
685

686
    return false;
687
});
688

689
// intercept click on cancel button in metadata edit dialog
690
$('#edit-dialog button.cancel').live('click', function(){
691
    // put the old values and close the forms
692
    $(this).parent().find('label').html($(this).parent().find('label.oldValue').text());
693
    $(this).parent().find('p').html($(this).parent().find('p.oldValue').text());
694
    // show/hide the appropriate buttons
695
    $(this).hide(); // this button (cancel)
696
    $(this).next().hide(); // the save button
697
    $(this).prev().show(); // the edit button
698
    $(this).siblings('button.remove').removeClass('more-margin');
699

700
    return false;
701
});
702

703
// intercept click on save button in metadata edit dialog
704
$('#edit-dialog button.save').live('click', function(){
705
    // get the updated values and the old key
706
    var oldKey = $(this).parent().find('label.oldValue').text();
707
    var newKey = $(this).parent().find('input.edit-meta-key').val();
708
    var newValue = $(this).parent().find('textarea.edit-meta-value').val();
709
    // put the new values and close the forms
710
    $(this).parent().find('label').html(newKey);
711
    $(this).parent().find('p').html(newValue);
712
    // check if the new metadata key is the same with the old one
713
    if ( oldKey != newKey ) {
714
        // if the key has changed, delete old pair
715
        delete_metadata(serverID, oldKey)
716
    }
717
    // add or update meatadata pair
718
    add_metadata(serverID, newKey, newValue);
719

720
    // show/hide the appropriate buttons
721
    $(this).hide(); // this button (save)
722
    $(this).prev().hide(); // the cancel button
723
    $(this).prev().prev().show(); // the edit button
724
    $(this).siblings('button.remove').removeClass('more-margin');
725

726
    return false;
727
});
728

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

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

749
// intercept create metadata key focus
750
$("#metadata-wizard textarea.value").live('focusin', function() {
751
    if ($(this).hasClass("input-enabled")) {
752
    } else {
753
        $("#metadata-wizard textarea.value").addClass("input-enabled"); 
754
        $(this).addClass("input-enabled"); 
755
        this.value = '';
756
    }
757
    return false;
758
});
759

760
// intercept create metadata key focus out
761
$("#metadata-wizard textarea.value").live('focusout', function() {
762
    if (this.value == "") {
763
        $(this).removeClass("input-enabled"); 
764
        this.value = 'max 150 characters';
765
    }
766
    return false;
767
});
768

769
// intercept click on cancel button in metadata add dialog
770
$('#add-dialog button.cancel').live('click', function() {
771
    reset_metadata_input();
772
});
773

774
// intercept click on save button in metadata add dialog
775
$('#add-dialog button.save').live('click', function() {
776
    // if both fields are filled in     
777
    if ($('input.key').hasClass("input-enabled") && $('textarea.value').hasClass("input-enabled")) {
778
        // get the server id, meta key and meta value needed for the ajax call     
779
        var serverID = $(this).parent().find('h3 p').text();
780
        var meta_key = $(this).parent().find('input.key').attr('value');
781
        var meta_value = $(this).parent().find('textarea.value')[0].value;
782
        // make the ajax call and list the new GET results
783
        add_metadata(serverID, meta_key, meta_value);
784
        // reset input areas
785
        reset_metadata_input();
786
        // go to previous step
787
        $('#add-dialog button.prev').click();
788
    } else {
789
        // find which field is not filled in and focus there
790
        if (!$('input.key').hasClass("input-enabled")) {
791
            $('input.key').focus();
792
            $('input.key').focusin();
793
        } else {
794
            $('textarea.value').focus();
795
            $('textarea.value').focusin();
796
        }
797
    }
798
    return false;
799
});
800

801
// confirm all actions
802
$("div.confirm_multiple .yes").live('click', function(){
803
    while(pending_actions.length > 0){ // if there is a pending action for this server execute it
804
        action = pending_actions.pop(); // extract action
805
        var serverID = action[1];
806
        if ($.cookie("list") != '1') { // standard view
807
            $('#' + serverID + ' .selected').removeClass('selected');
808
            $('#' + serverID + ' .display').removeClass('display');
809
            if (action[0] == shutdown) {
810
                $('#' + serverID + ' .status').text('Shutting down');
811
            } else if (action[0] == start) {
812
                $('#' + serverID + ' .status').text('Starting');
813
            } else if (action[0] == reboot) {
814
                $('#' + serverID + ' .status').text('Rebooting');
815
            } else if (action[0] == destroy) {
816
                $('#' + serverID + ' .status').text('Destroying');
817
            }
818
            $('#' + serverID + ' .spinner').show();
819
        } else { // list view
820
            osIcon = $('#'+serverID).parent().parent().find('.list-logo');
821
            osIcon.attr('os',osIcon.attr('src'));
822
            osIcon.attr('src','static/progress.gif');
823
            if (action[0] == shutdown) {
824
                $('#' + serverID).parent().parent().find('span.status').text('Shutting down');
825
            } else if (action[0] == start) {
826
                $('#' + serverID).parent().parent().find('span.status').text('Starting');
827
            } else if (action[0] == reboot) {
828
                $('#' + serverID).parent().parent().find('span.status').text('Rebooting');
829
            } else if (action[0] == destroy) {
830
                $('#' + serverID).parent().parent().find('span.status').text('Destroying');
831
            }
832
        }
833
        action[0]([serverID]); // execute action
834
    }
835
    update_confirmations();    
836
});
837

838
// cancel all actions
839
$("div.confirm_multiple .no").live('click', function(){
840
    pending_actions = [];
841
    $('.machine .selected').removeClass('selected');
842
    $('.machine .display').removeClass('display');
843
    update_confirmations();
844
});
845

846
// basic functions executed on page load
847
if (images.length > 0) {
848
    // populate image list
849
    update_wizard_images();
850
}
851
if (flavors.length > 0) {
852
    // configure flavors
853
    update_wizard_flavors(); 
854
}
855
// create tabs for main menu
856
$("ul.tabs").tabs("div.panes ul");
857

    
858
</script>