Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ 5110d813

History | View | Annotate | Download (32.1 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="close">{% trans "Close" %}</button>
225
                <button type="button" class="create next browse right">{% trans "Create New+" %}</button>
226
                <div class="bottomruler"></div>
227
            </div>
228
            <div class="page" id="add-dialog">
229
                <div class='container'>
230
                    <h3>
231
                        <label>{% trans "Tags for machine:" %}</label>
232
                        <span>Server name</span>
233
                        <p style='display:none;'>hidden server id</p>
234
                    </h3>
235
                    <hr class="topruler" />
236
                    <hr class="fatruler" />
237
                    <div class="content">
238
                        <label class="meta-key">{% trans "Key:" %}</label>
239
                        <input type="text" maxlength="15" class="key" value="{% trans 'max 15 characters' %}"/>
240
                        <hr class="meta-separator">
241
                        <label class="meta-value">{% trans "Value:" %}</label>
242
                        <textarea class="value">{% trans "max 150 characters" %}</textarea>
243
                    </div>
244
                </div>
245
                <button type="button" class="cancel prev browse left">{% trans "Cancel" %}</button>
246
                <button type="button" class="save">{% trans "Save" %}</button>
247
                <div class="bottomruler"></div>
248
            </div>
249
        </div>
250
    </div>
251
</div>
252

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

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

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

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

    
265
<script>
266

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

689
    return false;
690
});
691

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

703
    return false;
704
});
705

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

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

729
    return false;
730
});
731

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

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

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

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

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

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

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

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

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

    
861
</script>