Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ 7330b4c1

History | View | Annotate | Download (28.7 kB)

1
{% load i18n %}
2

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

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

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

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

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

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

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

    
177

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

433

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

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

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

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

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

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

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

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

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

544
    $('a#create').data('overlay').close();
545

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

548
    $("#wizard").hide();
549
});
550

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

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

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

622
// bring up add metadata overlay
623
function show_metadata_add_dialog() {
624
    var triggers = $("a#metadata-add-dialog").overlay({
625
        // some mask tweaks suitable for modal dialogs
626
        mask: '#000',
627
        effect: 'default',
628
        top: '10%',
629
        closeOnClick: false,
630
        oneInstance: false,
631
        load: false,
632
        onLoad: function() {
633
            // this is a workaround for the mask not appearing problem
634
            $("#add-dialog").expose();
635
        },
636
        onClose: function(){
637
            // reset input areas
638
            $(".meta-modal input.key").removeClass("input-enabled");
639
            $(".meta-modal input.key")[0].value = 'max 15 characters';
640
            $(".meta-modal textarea.value").removeClass("input-enabled");
641
            $(".meta-modal textarea.value")[0].value = 'max 150 characters';
642
            show_metadata_edit_dialog();        
643
        }
644
    });
645
    $("a#metadata-add-dialog").data('overlay').load();
646
    return false; 
647
}
648

649
// intercept click on create button in metadata edit dialog
650
$('#edit-dialog.meta-modal button.create').click( function(){
651
    // close edit metadata and open add metadata dialog
652
    $('a#metadata-edit-dialog').data('overlay').close();
653
    show_metadata_add_dialog();
654
});
655

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

666
// intercept click on edit button in metadata edit dialog
667
$('#edit-dialog.meta-modal button.edit').click( function(){
668
    // inline editing of selected key-value pair
669
    // on submission ajax call from updating
670
    // on success update the overlay
671
    // TODO
672
});
673

674
// intercept click on cancel button in metadata add dialog
675
$('#add-dialog.meta-modal button.cancel').click( function(){
676
    // close add metadata and open edit metadata dialog
677
    $('a#metadata-add-dialog').data('overlay').close();
678
});
679

680
// intercept create metadata key focus
681
$(".meta-modal input.key").live('focusin', function() {
682
    if ($(this).hasClass("input-enabled")) {
683
    } else {
684
        $(".meta-modal input.key").addClass("input-enabled"); 
685
        $(this).addClass("input-enabled"); 
686
        this.value = '';
687
    }
688
    return false;
689
});
690

691
// intercept create metadata key focus out
692
$(".meta-modal input.key").live('focusout', function() {
693
    if (this.value == "") {
694
        $(this).removeClass("input-enabled"); 
695
        this.value = 'max 15 characters';
696
    }
697
    return false;
698
});
699

700
// intercept create metadata key focus
701
$(".meta-modal textarea.value").live('focusin', function() {
702
    if ($(this).hasClass("input-enabled")) {
703
    } else {
704
        $(".meta-modal textarea.value").addClass("input-enabled"); 
705
        $(this).addClass("input-enabled"); 
706
        this.value = '';
707
    }
708
    return false;
709
});
710

711
// intercept create metadata key focus out
712
$(".meta-modal textarea.value").live('focusout', function() {
713
    if (this.value == "") {
714
        $(this).removeClass("input-enabled"); 
715
        this.value = 'max 150 characters';
716
    }
717
    return false;
718
});
719

720
// intercept click on save button in metadata add dialog
721
$('#add-dialog.meta-modal button.save').live('click', function() {
722
    // if both fields are filled in     
723
    if ($('input.key').hasClass("input-enabled") && $('textarea.value').hasClass("input-enabled")) {
724
        // get the server id, meta key and meta value needed for the ajax call     
725
        var serverID = $(this).parent().find('h3 p').text();
726
        var meta_key = $(this).parent().find('input.key').attr('value');
727
        var meta_value = $(this).parent().find('textarea.value')[0].value;
728
        // make the ajax call and list the new GET results
729
        add_metadata(serverID, meta_key, meta_value);
730
        // close add metadata and open edit metadata dialog
731
        $('a#metadata-add-dialog').data('overlay').close();
732
        show_metadata_edit_dialog();
733
    } else {
734
        // find which field is not filled in and focus there
735
        if (!$('input.key').hasClass("input-enabled")) {
736
            $('input.key').focus();
737
            $('input.key').focusin();
738
        } else {
739
            $('textarea.value').focus();
740
            $('textarea.value').focusin();
741
        }
742
    }
743
    return false;
744
});
745

746
// update metadata in edit dialog
747
function list_metadata(data) {    
748
    // empty the list if it already exists
749
    $("#edit-dialog div.content ul.meta-list").empty();
750
    // get the values to show
751
    meta = data.metadata.values;
752
    // show values
753
    for (key in meta) {
754
        pair = $("ul.meta-template li").clone();
755
        pair.find("label").text(key.substring(0,15));
756
        pair.find("p").text(meta[key].substring(0,30));
757
        pair.appendTo("#edit-dialog div.content ul.meta-list").fadeIn();
758
    }
759
}
760

761
// basic functions executed on page load
762
if (images.length > 0) {
763
    // populate image list
764
    update_wizard_images();
765
}
766
if (flavors.length > 0) {
767
    // configure flavors
768
    update_wizard_flavors(); 
769
}
770
// create tabs for main menu
771
$("ul.tabs").tabs("div.panes ul");
772

    
773
</script>