Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ 5593ab62

History | View | Annotate | Download (31.2 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
    // show input form for tag value
674
    $(this).parent().find('p').html("<textarea class=\"edit-meta-value\" l=\"3\">" +
675
                                        $(this).parent().find('p').text() + 
676
                                        "</textarea><p class=\"oldValue\">" + 
677
                                        $(this).parent().find('p').text() + "</p>");
678
    // show/hide the appropriate buttons
679
    $(this).hide(); // this button (edit)
680
    $(this).siblings().show(); // save and cancel buttons
681

682
    return false;
683
});
684

685
// intercept click on cancel button in metadata edit dialog
686
$('#edit-dialog button.cancel').live('click', function(){
687
    // put the old value and close the forms
688
    $(this).parent().find('p').html($(this).parent().find('p.oldValue').text());
689
    // show/hide the appropriate buttons
690
    $(this).hide(); // this button (cancel)
691
    $(this).next().hide(); // the save button
692
    $(this).prev().show(); // the edit button
693

694
    return false;
695
});
696

697
// intercept click on save button in metadata edit dialog
698
$('#edit-dialog button.save').live('click', function(){
699
    // get the updated values and the old key
700
    var oldKey = $(this).parent().find('label').text();
701
    var newValue = $(this).parent().find('textarea.edit-meta-value').val().substring(0,150);
702
    // put the new value and close the forms
703
    $(this).parent().find('p').html(newValue);
704
    // update meatadata pair
705
    add_metadata(serverID, newKey, newValue);
706

707
    // show/hide the appropriate buttons
708
    $(this).hide(); // this button (save)
709
    $(this).prev().hide(); // the cancel button
710
    $(this).prev().prev().show(); // the edit button
711

712
    return false;
713
});
714

715
// intercept create metadata key focus
716
$("#metadata-wizard input.key").live('focusin', function() {
717
    if ($(this).hasClass("input-enabled")) {
718
    } else {
719
        $("#metadata-wizard input.key").addClass("input-enabled"); 
720
        $(this).addClass("input-enabled"); 
721
        this.value = '';
722
    }
723
    return false;
724
});
725

726
// intercept create metadata key focus out
727
$("#metadata-wizard input.key").live('focusout', function() {
728
    if (this.value == "") {
729
        $(this).removeClass("input-enabled"); 
730
        this.value = 'max 15 characters';
731
    }
732
    return false;
733
});
734

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

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

755
// intercept click on cancel button in metadata add dialog
756
$('#add-dialog button.cancel').live('click', function() {
757
    reset_metadata_input();
758
});
759

760
// intercept click on save button in metadata add dialog
761
$('#add-dialog button.save').live('click', function() {
762
    // if both fields are filled in     
763
    if ($('input.key').hasClass("input-enabled") && $('textarea.value').hasClass("input-enabled")) {
764
        // get the server id, meta key and meta value needed for the ajax call     
765
        var serverID = $(this).parent().find('h3 p').text();
766
        var meta_key = $(this).parent().find('input.key').attr('value');
767
        var meta_value = $(this).parent().find('textarea.value')[0].value;
768
        // make the ajax call and list the new GET results
769
        add_metadata(serverID, meta_key, meta_value);
770
        // reset input areas
771
        reset_metadata_input();
772
        // go to previous step
773
        $('#add-dialog button.prev').click();
774
    } else {
775
        // find which field is not filled in and focus there
776
        if (!$('input.key').hasClass("input-enabled")) {
777
            $('input.key').focus();
778
            $('input.key').focusin();
779
        } else {
780
            $('textarea.value').focus();
781
            $('textarea.value').focusin();
782
        }
783
    }
784
    return false;
785
});
786

787
// confirm all actions
788
$("div.confirm_multiple .yes").live('click', function(){
789
    while(pending_actions.length > 0){ // if there is a pending action for this server execute it
790
        action = pending_actions.pop(); // extract action
791
        var serverID = action[1];
792
        if ($.cookie("list") != '1') { // standard view
793
            $('#' + serverID + ' .selected').removeClass('selected');
794
            $('#' + serverID + ' .display').removeClass('display');
795
            if (action[0] == shutdown) {
796
                $('#' + serverID + ' .status').text('Shutting down');
797
            } else if (action[0] == start) {
798
                $('#' + serverID + ' .status').text('Starting');
799
            } else if (action[0] == reboot) {
800
                $('#' + serverID + ' .status').text('Rebooting');
801
            } else if (action[0] == destroy) {
802
                $('#' + serverID + ' .status').text('Destroying');
803
            }
804
            $('#' + serverID + ' .spinner').show();
805
        } else { // list view
806
            osIcon = $('#'+serverID).parent().parent().find('.list-logo');
807
            osIcon.attr('os',osIcon.attr('src'));
808
            osIcon.attr('src','static/progress.gif');
809
            if (action[0] == shutdown) {
810
                $('#' + serverID).parent().parent().find('span.status').text('Shutting down');
811
            } else if (action[0] == start) {
812
                $('#' + serverID).parent().parent().find('span.status').text('Starting');
813
            } else if (action[0] == reboot) {
814
                $('#' + serverID).parent().parent().find('span.status').text('Rebooting');
815
            } else if (action[0] == destroy) {
816
                $('#' + serverID).parent().parent().find('span.status').text('Destroying');
817
            }
818
        }
819
        action[0]([serverID]); // execute action
820
    }
821
    update_confirmations();    
822
});
823

824
// cancel all actions
825
$("div.confirm_multiple .no").live('click', function(){
826
    pending_actions = [];
827
    $('.machine .selected').removeClass('selected');
828
    $('.machine .display').removeClass('display');
829
    update_confirmations();
830
});
831

832
// basic functions executed on page load
833
if (images.length > 0) {
834
    // populate image list
835
    update_wizard_images();
836
}
837
if (flavors.length > 0) {
838
    // configure flavors
839
    update_wizard_flavors(); 
840
}
841
// create tabs for main menu
842
$("ul.tabs").tabs("div.panes ul");
843

    
844
</script>