diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index bcb82d3aba1..6602c161c46 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -1835,6 +1835,7 @@ div.list-view td.state.off span { float: left; width: 245px; } + .detail-group .main-groups table td.value > span.copypasteenabledvalue { text-overflow: ellipsis; -o-text-overflow: ellipsis; @@ -1849,7 +1850,7 @@ div.list-view td.state.off span { } div.copypasteicon { - background: url("../images/sprites.png") no-repeat scroll -271px -65px; + background: url("../images/sprites.png") no-repeat -271px -65px; float: left; height: 21px; margin-left: 6px; @@ -1858,7 +1859,7 @@ div.copypasteicon { } div.copypasteicon:hover { - background: url("../images/sprites.png") no-repeat scroll -271px -646px; + background: url("../images/sprites.png") no-repeat -271px -646px; } .detail-group .main-groups table td.value > span.copypasteenabledvalue { @@ -1875,7 +1876,7 @@ div.copypasteicon:hover { } div.copypasteicon { - background: url("../images/sprites.png") no-repeat scroll -271px -65px; + background: url("../images/sprites.png") no-repeat -271px -65px; float: left; height: 21px; margin-left: 6px; @@ -1884,10 +1885,9 @@ div.copypasteicon { } div.copypasteicon:hover { - background: url("../images/sprites.png") no-repeat scroll -271px -646px; + background: url("../images/sprites.png") no-repeat -271px -646px; } - .detail-group .main-groups table td.value > span select { width: 100% !important; } @@ -6050,6 +6050,94 @@ label.error { border-radius: 6px 6px 6px 6px; } +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group { + float: left; + margin-top: 12px; + width: 100%; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-header { + border-bottom: 1px solid #D4D4D4; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + background: #C2C2C2 0px 4px; + padding: 6px; + height: 17px; +} + +.multi-wizard.instance-wizard .disk-select-group.selected .disk-select-header { + background: #505050; + /*+border-radius:4px 4px 0 0;*/ + -moz-border-radius: 4px 4px 0 0; + -webkit-border-radius: 4px 4px 0 0; + -khtml-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-header input { + float: left; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-header .title { + float: left; + font-size: 14px; + padding: 2px; +} + +.multi-wizard.instance-wizard .disk-select-group.selected .disk-select-header .title { + color: #FFFFFF; + /*+text-shadow:0px -1px #000000;*/ + -moz-text-shadow: 0px -1px #000000; + -webkit-text-shadow: 0px -1px #000000; + -o-text-shadow: 0px -1px #000000; + text-shadow: 0px -1px #000000; +} + +.multi-wizard.instance-wizard .data-disk-offering .multi-disk-select-container { + max-height: 257px; + overflow: auto; + border: 1px solid #DDDBDB; + padding: 13px; + background: #E4E4E4; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select-container { + max-height: 114px; + float: left; + margin: 0; + border: none; + /*+border-radius:0;*/ + -moz-border-radius: 0; + -webkit-border-radius: 0; + -khtml-border-radius: 0; + border-radius: 0; + display: none; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group.selected .select-container { + display: block; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select { + padding: 0 0 17px; + height: 0; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group.custom-size .section.custom-size { + display: block !important; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select input { + margin: 13px 12px 12px; +} + +.multi-wizard.instance-wizard .data-disk-offering .disk-select-group .select-desc { + margin: 13px 0 0; +} + .multi-wizard.instance-wizard .data-disk-offering.required .select-container { height: 344px; position: relative; @@ -12491,7 +12579,8 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it background-position: -168px -31px; } -.reset .icon, .reinstall .icon { +.reset .icon, +.reinstall .icon { background-position: -168px -31px; } diff --git a/ui/index.jsp b/ui/index.jsp index 4910b9f11fc..5840e7171d9 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -250,7 +250,7 @@ -
+
diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index c2d3030b149..d6020746f4f 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -335,7 +335,14 @@ customIopsDoFlag: 'iscustomizediops', data: { diskOfferings: diskOfferingObjs - } + }, + multiDisk: false + // multiDisk: + // [ + // { id: 1, label: 'vm-disk-1' }, + // { id: 2, label: 'vm-disk-2' }, + // { id: 3, label: 'vm-disk-3' } + // ] }); } }); diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index 1a0c323d53c..0174cfc98f1 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -491,7 +491,11 @@ return { response: { success: function(args) { + var multiDisk = args.multiDisk; + + $step.find('.multi-disk-select-container').remove(); $step.removeClass('custom-disk-size'); + if (args.required) { $step.find('.section.no-thanks').hide(); $step.addClass('required'); @@ -500,15 +504,67 @@ $step.removeClass('required'); } - $step.find('.content .select-container').append( - makeSelects('diskofferingid', args.data.diskOfferings, { - id: 'id', - name: 'name', - desc: 'displaytext' - }, { - 'wizard-field': 'disk-offering' - }) - ); + var $selectContainer = $step.find('.content .select-container:not(.multi-disk)'); + + if (multiDisk) { // Render as multiple groups for each disk + var $multiDiskSelect = $('
').addClass('multi-disk-select-container'); + + $(multiDisk).map(function(index, disk) { + var $group = $('
').addClass('disk-select-group'); + var $header = $('
').addClass('disk-select-header').append( + $('
').addClass('title').html(disk.label) + ).appendTo($group); + var $checkbox = $('').addClass('multi-disk-select') + .attr({ + type: 'checkbox', + 'disk-id': disk.id + }) + .prependTo($header); + var $multiSelectContainer = $selectContainer.clone().append( + makeSelects('diskofferingid.' + disk.id, args.data.diskOfferings, { + id: 'id', + name: 'name', + desc: 'displaytext' + }, { + 'wizard-field': 'disk-offering' + }) + ).appendTo($group).addClass('multi-disk'); + + $group.appendTo($multiDiskSelect); + + // Show-hide disk group selects + $checkbox.click(function() { + $group.toggleClass('selected'); + $group.find('.select:first input[type=radio]').click(); + + if (!$multiDiskSelect.find('input[type=checkbox]:checked').size()) { + $step.find('.no-thanks input[type=radio]').click(); + } else { + $step.find('.no-thanks input[type=radio]').attr('checked', false); + } + }); + + // Add custom disk size box + $step.find('.section.custom-size').clone().hide().appendTo($group); + }); + + $multiDiskSelect.insertAfter($selectContainer); + $selectContainer.hide(); + + // Fix issue with containers always showing after reload + $multiDiskSelect.find('.select-container').attr('style', null); + } else { + $selectContainer.show(); + $step.find('.content .select-container').append( + makeSelects('diskofferingid', args.data.diskOfferings, { + id: 'id', + name: 'name', + desc: 'displaytext' + }, { + 'wizard-field': 'disk-offering' + }) + ); + } $step.find('input[type=radio]').bind('change', function() { var $target = $(this); @@ -516,53 +572,73 @@ var item = $.grep(args.data.diskOfferings, function(elem) { return elem.id == val; })[0]; + var isMultiDisk = $step.find('.multi-disk-select').size(); + + // Uncheck any multi-select groups + if ($target.closest('.no-thanks').size() && isMultiDisk) { + $step.find('.disk-select-group input[type=checkbox]:checked').click(); + $(this).attr('checked', true); + + return true; + } if (!item) { - // handle removal of custom size controls - $step.find('.section.custom-size').hide(); - $step.removeClass('custom-disk-size'); - - // handle removal of custom IOPS controls - $step.removeClass('custom-iops-do'); + if (isMultiDisk) { + $(this).closest('.disk-select-group .section.custom-size').hide(); + $(this).closest('.disk-select-group').removeClass('custom-size'); + } else { + // handle removal of custom size controls + $step.find('.section.custom-size').hide(); + $step.removeClass('custom-disk-size'); + // handle removal of custom IOPS controls + $step.removeClass('custom-iops-do'); + } + return true; } var custom = item[args.customFlag]; - $step.find('.custom-size-label').remove(); + if (!isMultiDisk) $step.find('.custom-size-label').remove(); - if (custom) { + if (custom && !isMultiDisk) { $target.parent().find('.name') + .append( + $('').addClass('custom-size-label') + .append(': ') .append( - $('').addClass('custom-size-label') - .append(': ') - .append( - $('').addClass('custom-disk-size').html( - $step.find('.custom-size input[name=size]').val() - ) - ) - .append(' GB') + $('').addClass('custom-disk-size').html( + $step.find('.custom-size input[name=size]').val() + ) + ) + .append(' GB') ); $target.parent().find('.select-desc .desc') + .append( + $('').addClass('custom-size-label') + .append(', ') .append( - $('').addClass('custom-size-label') - .append(', ') - .append( - $('').addClass('custom-disk-size').html( - $step.find('.custom-size input[name=size]').val() - ) - ) - .append(' GB') + $('').addClass('custom-disk-size').html( + $step.find('.custom-size input[name=size]').val() + ) + ) + .append(' GB') ); $step.find('.section.custom-size').show(); $step.addClass('custom-disk-size'); $target.closest('.select-container').scrollTop( $target.position().top ); + } else if (custom && isMultiDisk) { + $(this).closest('.disk-select-group').addClass('custom-size'); } else { - $step.find('.section.custom-size').hide(); - $step.removeClass('custom-disk-size'); + if (isMultiDisk) { + $(this).closest('.disk-select-group').removeClass('custom-size'); + } else { + $step.find('.section.custom-size').hide(); + $step.removeClass('custom-disk-size'); + } } var customIops = item[args.customIopsDoFlag]; @@ -1118,7 +1194,7 @@ $wizard.find('.tab-view').tabs(); $wizard.find('.slider').each(function() { var $slider = $(this); - + $slider.slider({ min: minCustomDiskSize, max: maxCustomDiskSize,