mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
When both VPC and isolated networks are present, fix case where unchecking first isolated networks triggers checkbox for VPC tier network, thus making it appear as if no network is selected. reviewed-by: jessica
866 lines
32 KiB
JavaScript
866 lines
32 KiB
JavaScript
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
(function($, cloudStack) {
|
|
/**
|
|
* Instance wizard
|
|
*/
|
|
cloudStack.uiCustom.instanceWizard = function(args) {
|
|
return function(listViewArgs) {
|
|
var context = listViewArgs.context;
|
|
|
|
var instanceWizard = function(data) {
|
|
var $wizard = $('#template').find('div.instance-wizard').clone();
|
|
var $progress = $wizard.find('div.progress ul li');
|
|
var $steps = $wizard.find('div.steps').children().hide();
|
|
var $diagramParts = $wizard.find('div.diagram').children().hide();
|
|
var $form = $wizard.find('form');
|
|
|
|
$form.validate();
|
|
|
|
// Close instance wizard
|
|
var close = function() {
|
|
$wizard.dialog('destroy');
|
|
$('div.overlay').fadeOut(function() { $('div.overlay').remove(); });
|
|
};
|
|
|
|
// Save instance and close wizard
|
|
var completeAction = function() {
|
|
var data = cloudStack.serializeForm($form);
|
|
var $wizardLoading = $('<div>').addClass('loading-overlay').appendTo($wizard).css('z-index', '10000');
|
|
|
|
args.action({
|
|
// Populate data
|
|
context: context,
|
|
data: data,
|
|
response: {
|
|
success: function(args) {
|
|
var $listView = $('.list-view.instances');
|
|
|
|
if ($listView.size()) {
|
|
var $loading = $('.list-view.instances').listView('prependItem', {
|
|
data: [
|
|
{
|
|
name: data.displayname ? data.displayname : _l('label.new.vm'),
|
|
zonename: $wizard.find('select[name=zoneid] option').filter(function() {
|
|
return $(this).val() == data.zoneid;
|
|
}).html(),
|
|
state: 'Creating'
|
|
}
|
|
],
|
|
actionFilter: function(args) { return []; }
|
|
});
|
|
}
|
|
|
|
listViewArgs.complete({
|
|
_custom: args._custom,
|
|
messageArgs: cloudStack.serializeForm($form),
|
|
$item: $listView.size()? $loading : $('<div>')
|
|
});
|
|
|
|
close();
|
|
},
|
|
error: function(message) {
|
|
$wizard.remove();
|
|
$('div.overlay').remove();
|
|
|
|
if (message) {
|
|
cloudStack.dialog.notice({ message: message });
|
|
}
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
var makeSelects = function(name, data, fields, options) {
|
|
var $selects = $('<div>');
|
|
options = options ? options : {};
|
|
|
|
$(data).each(function() {
|
|
var id = this[fields.id];
|
|
|
|
var $select = $('<div>')
|
|
.addClass('select')
|
|
.append(
|
|
$('<input>')
|
|
.attr({
|
|
type: (function(type) {
|
|
return type ? type : 'radio';
|
|
})(options ? options.type : null),
|
|
name: name,
|
|
'wizard-field': options['wizard-field']
|
|
})
|
|
.val(id)
|
|
.click(function() {
|
|
var $radio = $(this).closest('.select').find('input[type=radio]');
|
|
|
|
if ($(this).attr('type') == 'checkbox') {
|
|
if ($(this).closest('.select-container').hasClass('single-select') ||
|
|
!$(this).closest('.select').siblings().filter(':visible').size()) {
|
|
$(this).closest('.select').siblings().find('input[type=checkbox]')
|
|
.attr('checked', false);
|
|
$(this).closest('.select').find('input[type=radio]').click();
|
|
}
|
|
}
|
|
|
|
if ($radio.is(':checked') && !$(this).is(':checked')) {
|
|
if (!$radio.closest('.select').index()) {
|
|
return false;
|
|
} else {
|
|
$radio
|
|
.closest('.select')
|
|
.siblings().filter(':first')
|
|
.find('input[type=radio]').click();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
})
|
|
)
|
|
.append(
|
|
$('<div>').addClass('select-desc')
|
|
.append($('<div>').addClass('name').html(this[fields.name]))
|
|
.append($('<div>').addClass('desc').html(this[fields.desc]))
|
|
)
|
|
.data('json-obj', this);
|
|
|
|
$selects.append($select);
|
|
|
|
if (options.secondary) {
|
|
var $secondary = $('<div>').addClass('secondary-input').append(
|
|
$('<input>')
|
|
.attr({
|
|
type: options.secondary.type,
|
|
name: options.secondary.name,
|
|
'wizard-field': options.secondary['wizard-field']
|
|
})
|
|
.val(id)
|
|
.click(function() {
|
|
var $checkbox = $(this).closest('.select').find('input[type=checkbox]');
|
|
|
|
if (!$checkbox.is(':checked')) {
|
|
$checkbox.attr('checked', true);
|
|
}
|
|
|
|
if ($(this).closest('.select-container').hasClass('single-select')) {
|
|
$(this).closest('.select').siblings().find('input[type=checkbox]')
|
|
.attr('checked', false);
|
|
}
|
|
})
|
|
.after(
|
|
$('<div>').addClass('name').html(options.secondary.desc)
|
|
)
|
|
).appendTo($select);
|
|
}
|
|
});
|
|
|
|
cloudStack.evenOdd($selects, 'div.select', {
|
|
even: function($elem) {
|
|
$elem.addClass('even');
|
|
},
|
|
odd: function($elem) {
|
|
$elem.addClass('odd');
|
|
}
|
|
});
|
|
|
|
return $selects.children();
|
|
};
|
|
|
|
var dataProvider = function(step, providerArgs, callback) {
|
|
// Call appropriate data provider
|
|
args.steps[step - 1]($.extend(providerArgs, {
|
|
currentData: cloudStack.serializeForm($form),
|
|
initArgs: args,
|
|
context: context
|
|
}));
|
|
};
|
|
|
|
var dataGenerators = {
|
|
setup: function($step, formData) {
|
|
var originalValues = function(formData) {
|
|
$step.find('select').val(
|
|
formData.zoneid
|
|
);
|
|
|
|
$step.find('input[type=radio]').filter(function() {
|
|
return $(this).val() == formData['select-template'];
|
|
}).click();
|
|
};
|
|
|
|
return {
|
|
response: {
|
|
success: function(args) {
|
|
// Zones
|
|
$(args.data.zones).each(function() {
|
|
$step.find('.select-zone select').append(
|
|
$('<option>')
|
|
.attr({
|
|
value: this.id,
|
|
'wizard-field': 'zone'
|
|
})
|
|
.html(this.name)
|
|
);
|
|
});
|
|
|
|
originalValues(formData);
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
'select-iso': function($step, formData) {
|
|
var originalValues = function(formData) {
|
|
var $inputs = $step.find('.wizard-step-conditional:visible')
|
|
.find('input[type=radio]');
|
|
var $selected = $inputs.filter(function() {
|
|
return $(this).val() == formData.templateid;
|
|
});
|
|
|
|
if (!$selected.size()) {
|
|
$inputs.filter(':first').click();
|
|
} else {
|
|
$selected.click();
|
|
}
|
|
$step.find('select[name=hypervisorid]:visible').val(
|
|
formData.hypervisorid
|
|
);
|
|
};
|
|
|
|
$step.find('.wizard-step-conditional').hide();
|
|
|
|
return {
|
|
response: {
|
|
success: function(args) {
|
|
if (formData['select-template']) {
|
|
$step.find('.wizard-step-conditional').filter(function() {
|
|
return $(this).hasClass(formData['select-template']);
|
|
}).show();
|
|
} else {
|
|
$step.find('.select-iso').show();
|
|
}
|
|
var makeIsos = function(type, append) {
|
|
var $selects = makeSelects('templateid', args.data.templates[type], {
|
|
name: 'name',
|
|
desc: 'displaytext',
|
|
id: 'id'
|
|
}, {
|
|
'wizard-field': 'template'
|
|
});
|
|
|
|
if (type == 'featuredisos' || type == 'communityisos' || type == 'myisos') {
|
|
// Create hypervisor select
|
|
$selects.find('input').bind('click', function() {
|
|
var $select = $(this).closest('.select');
|
|
|
|
//$select.siblings().removeClass('selected').find('.hypervisor').remove(); //SelectISO has 3 tabs now. This line only remove hypervisor div in the same tab, not enough. The following 3 lines will remove hypervisor div in all of 3 tabs.
|
|
$("#instance-wizard-featured-isos .select-container div.selected").removeClass('selected').find('div.hypervisor').remove();
|
|
$("#instance-wizard-community-isos .select-container div.selected").removeClass('selected').find('div.hypervisor').remove();
|
|
$("#instance-wizard-my-isos .select-container div.selected").removeClass('selected').find('div.hypervisor').remove();
|
|
|
|
$select.addClass('selected').append(
|
|
$('<div>').addClass('hypervisor')
|
|
.append($('<label>').html('Hypervisor:'))
|
|
.append($('<select>').attr({ name: 'hypervisorid' }))
|
|
);
|
|
|
|
// Get hypervisor data
|
|
$(args.data.hypervisors).each(function() {
|
|
$select.find('select').append(
|
|
$('<option>').attr({
|
|
value: this[args.hypervisor.idField],
|
|
'wizard-field': 'hypervisor'
|
|
})
|
|
.html(this[args.hypervisor.nameField])
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
append($selects);
|
|
};
|
|
|
|
// Featured ISOs
|
|
$(
|
|
[
|
|
['featuredtemplates', 'instance-wizard-featured-templates'],
|
|
['communitytemplates', 'instance-wizard-community-templates'],
|
|
['mytemplates', 'instance-wizard-my-templates'],
|
|
|
|
['featuredisos', 'instance-wizard-featured-isos'],
|
|
['communityisos', 'instance-wizard-community-isos'],
|
|
['myisos', 'instance-wizard-my-isos']
|
|
//['isos', 'instance-wizard-all-isos']
|
|
]
|
|
).each(function() {
|
|
var item = this;
|
|
var $selectContainer = $wizard.find('#' + item[1]).find('.select-container');
|
|
|
|
makeIsos(item[0], function($elem) {
|
|
$selectContainer.append($elem);
|
|
});
|
|
});
|
|
|
|
originalValues(formData);
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
'service-offering': function($step, formData) {
|
|
var originalValues = function(formData) {
|
|
if (formData.serviceofferingid) {
|
|
$step.find('input[type=radio]').filter(function() {
|
|
return $(this).val() == formData.serviceofferingid;
|
|
}).click();
|
|
} else {
|
|
$step.find('input[type=radio]:first').click();
|
|
}
|
|
};
|
|
|
|
return {
|
|
response: {
|
|
success: function(args) {
|
|
$step.find('.content .select-container').append(
|
|
makeSelects('serviceofferingid', args.data.serviceOfferings, {
|
|
name: 'name',
|
|
desc: 'displaytext',
|
|
id: 'id'
|
|
}, {
|
|
'wizard-field': 'service-offering'
|
|
})
|
|
);
|
|
|
|
originalValues(formData);
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
'data-disk-offering': function($step, formData) {
|
|
var originalValues = function(formData) {
|
|
var $targetInput = $step.find('input[type=radio]').filter(function() {
|
|
return $(this).val() == formData.diskofferingid;
|
|
}).click();
|
|
|
|
if (!$targetInput.size()) {
|
|
$step.find('input[type=radio]:visible').filter(':first').click();
|
|
}
|
|
};
|
|
|
|
$step.find('.section.custom-size').hide();
|
|
|
|
return {
|
|
response: {
|
|
success: function(args) {
|
|
$step.removeClass('custom-disk-size');
|
|
if (args.required) {
|
|
$step.find('.section.no-thanks').hide();
|
|
$step.addClass('required');
|
|
} else {
|
|
$step.find('.section.no-thanks').show();
|
|
$step.removeClass('required');
|
|
}
|
|
|
|
$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);
|
|
var val = $target.val();
|
|
var item = $.grep(args.data.diskOfferings, function(elem) {
|
|
return elem.id == val;
|
|
})[0];
|
|
|
|
if (!item) return true;
|
|
|
|
var custom = item[args.customFlag];
|
|
|
|
$step.find('.custom-size-label').remove();
|
|
|
|
if (custom) {
|
|
$target.parent().find('.name')
|
|
.append(
|
|
$('<span>').addClass('custom-size-label')
|
|
.append(': ')
|
|
.append(
|
|
$('<span>').addClass('custom-disk-size').html(
|
|
$step.find('.custom-size input[name=size]').val()
|
|
)
|
|
)
|
|
.append(' GB')
|
|
);
|
|
$target.parent().find('.select-desc .desc')
|
|
.append(
|
|
$('<span>').addClass('custom-size-label')
|
|
.append(', ')
|
|
.append(
|
|
$('<span>').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 {
|
|
$step.find('.section.custom-size').hide();
|
|
$step.removeClass('custom-disk-size');
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
originalValues(formData);
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
'network': function($step, formData) {
|
|
var originalValues = function(formData) {
|
|
// Default networks
|
|
$step.find('input[type=radio]').filter(function() {
|
|
return $(this).val() == formData['defaultNetwork'];
|
|
}).click();
|
|
|
|
// Optional networks
|
|
var selectedOptionalNetworks = [];
|
|
|
|
if ($.isArray(formData['shared-networks']) != -1) {
|
|
$(formData['shared-networks']).each(function() {
|
|
selectedOptionalNetworks.push(this);
|
|
});
|
|
} else {
|
|
selectedOptionalNetworks.push(formData['shared-networks']);
|
|
}
|
|
|
|
var $checkboxes = $step.find('input[name=shared-networks]');
|
|
$(selectedOptionalNetworks).each(function() {
|
|
var networkID = this;
|
|
$checkboxes.filter(function() {
|
|
return $(this).val() == networkID;
|
|
}).attr('checked', 'checked');
|
|
});
|
|
};
|
|
|
|
var $newNetwork = $step.find('.new-network');
|
|
var $newNetworkCheckbox = $newNetwork.find('input[type=checkbox]');
|
|
|
|
// Setup new network field
|
|
$newNetworkCheckbox.unbind('click');
|
|
$newNetworkCheckbox.click(function() {
|
|
$newNetwork.toggleClass('unselected');
|
|
|
|
// Select another default if hiding field
|
|
if ($newNetwork.hasClass('unselected')) {
|
|
$step.find('input[type=radio]:first').click();
|
|
} else {
|
|
$newNetwork.find('input[type=radio]').click();
|
|
}
|
|
});
|
|
|
|
setTimeout(function() {
|
|
var $checkbox = $step.find('.new-network input[type=checkbox]');
|
|
var $newNetwork = $checkbox.closest('.new-network');
|
|
|
|
if ($step.find('.select.my-networks .select-container .select:visible').size()) {
|
|
$checkbox.attr('checked', false);
|
|
$newNetwork.addClass('unselected');
|
|
} else {
|
|
$checkbox.attr('checked', true);
|
|
$newNetwork.removeClass('unselected');
|
|
}
|
|
|
|
$checkbox.change();
|
|
});
|
|
|
|
// Show relevant conditional sub-step if present
|
|
$step.find('.wizard-step-conditional').hide();
|
|
|
|
// Filter network list by VPC ID
|
|
var filterNetworkList = function(vpcID) {
|
|
var $selects = $step.find('.my-networks .select-container .select');
|
|
var $visibleSelects = $($.grep($selects, function(select) {
|
|
var $select = $(select);
|
|
|
|
return args.vpcFilter($select.data('json-obj'), vpcID);
|
|
}));
|
|
var $addNetworkForm = $step.find('.select.new-network');
|
|
var $addNewNetworkCheck = $addNetworkForm.find('input[name=new-network]');
|
|
|
|
// VPC networks cannot be created via instance wizard
|
|
if (vpcID != -1) {
|
|
$step.find('.my-networks .select-container').addClass('single-select');
|
|
$addNetworkForm.hide();
|
|
|
|
if ($addNewNetworkCheck.is(':checked')) {
|
|
$addNewNetworkCheck.click();
|
|
$addNewNetworkCheck.attr('checked', false);
|
|
}
|
|
} else {
|
|
$step.find('.my-networks .select-container').removeClass('single-select');
|
|
$addNetworkForm.show();
|
|
}
|
|
|
|
$selects.find('input[type=checkbox]').attr('checked', false);
|
|
$selects.hide();
|
|
$visibleSelects.show();
|
|
|
|
// Select first visible item by default
|
|
$visibleSelects.filter(':first')
|
|
.find('input[type=radio]')
|
|
.click();
|
|
|
|
cloudStack.evenOdd($visibleSelects, 'div.select', {
|
|
even: function($elem) {
|
|
$elem.removeClass('odd');
|
|
$elem.addClass('even');
|
|
},
|
|
odd: function($elem) {
|
|
$elem.removeClass('even');
|
|
$elem.addClass('odd');
|
|
}
|
|
});
|
|
};
|
|
|
|
var $vpcSelect = $step.find('select[name=vpc-filter]');
|
|
|
|
$vpcSelect.unbind('change');
|
|
$vpcSelect.change(function() {
|
|
filterNetworkList($vpcSelect.val());
|
|
});
|
|
|
|
return {
|
|
response: {
|
|
success: function(args) {
|
|
var vpcs = args.data.vpcs;
|
|
|
|
// Populate VPC drop-down
|
|
$vpcSelect.html('');
|
|
$(vpcs).map(function(index, vpc) {
|
|
var $option = $('<option>');
|
|
var id = vpc.id;
|
|
var description = vpc.name;
|
|
|
|
$option.attr('value', id);
|
|
$option.html(description);
|
|
$option.appendTo($vpcSelect);
|
|
});
|
|
|
|
// 'No VPC' option
|
|
$('<option>').attr('value', '-1').html('None').prependTo($vpcSelect);
|
|
|
|
$vpcSelect.val(-1);
|
|
|
|
// Populate network offering drop-down
|
|
$(args.data.networkOfferings).each(function() {
|
|
$('<option>')
|
|
.val(this.id)
|
|
.html(this.name)
|
|
.appendTo($newNetwork.find('select'));
|
|
});
|
|
|
|
if (args.type) {
|
|
$step.find('.wizard-step-conditional').filter(function() {
|
|
return $(this).hasClass(args.type);
|
|
}).show();
|
|
} else {
|
|
$step.find('.select-network').show();
|
|
}
|
|
|
|
// My networks
|
|
$step.find('.my-networks .select-container').append(
|
|
makeSelects('my-networks', $.merge(args.data.myNetworks, args.data.sharedNetworks), {
|
|
name: 'name',
|
|
desc: 'type',
|
|
id: 'id'
|
|
}, {
|
|
type: 'checkbox',
|
|
'wizard-field': 'my-networks',
|
|
secondary: {
|
|
desc: 'Default',
|
|
name: 'defaultNetwork',
|
|
type: 'radio',
|
|
'wizard-field': 'default-network'
|
|
}
|
|
})
|
|
);
|
|
|
|
// Show non-VPC networks by default
|
|
filterNetworkList(-1);
|
|
|
|
// Security groups (alt. page)
|
|
$step.find('.security-groups .select-container').append(
|
|
makeSelects('security-groups', args.data.securityGroups, {
|
|
name: 'name',
|
|
desc: 'description',
|
|
id: 'id'
|
|
}, {
|
|
type: 'checkbox',
|
|
'wizard-field': 'security-groups'
|
|
})
|
|
);
|
|
|
|
originalValues(formData);
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
'review': function($step, formData) {
|
|
$step.find('[wizard-field]').each(function() {
|
|
var field = $(this).attr('wizard-field');
|
|
var fieldName;
|
|
var $input = $wizard.find('[wizard-field=' + field + ']').filter(function() {
|
|
return $(this).is(':selected') || $(this).is(':checked');
|
|
});
|
|
|
|
if ($input.is('option')) {
|
|
fieldName = $input.html();
|
|
} else if ($input.is('input[type=radio]')) {
|
|
// Choosen New network as default
|
|
if ($input.parents('div.new-network').size()) {
|
|
fieldName = $input.closest('div.new-network').find('input[name="new-network-name"]').val();
|
|
// Choosen Network from existed
|
|
} else if ($input.parents('div.my-networks').size()) {
|
|
fieldName = $input.closest('div.select').find('.select-desc .name').html();
|
|
} else {
|
|
fieldName = $input.parent().find('.select-desc .name').html();
|
|
}
|
|
} else if ($input.eq(0).is('input[type=checkbox]')) {
|
|
fieldName = '';
|
|
$input.each(function(index) {
|
|
if (index != 0) fieldName += '<br />';
|
|
fieldName += $(this).next('div.select-desc').find('.name').html();
|
|
});
|
|
}
|
|
|
|
if (fieldName) {
|
|
$(this).html(fieldName);
|
|
} else {
|
|
$(this).html('(' + _l('label.none') + ')');
|
|
}
|
|
|
|
var conditionalFieldFrom = $(this).attr('conditional-field');
|
|
if (conditionalFieldFrom) {
|
|
if ($wizard.find('.'+conditionalFieldFrom).css('display') == 'block') {
|
|
$(this).closest('div.select').show();
|
|
} else {
|
|
$(this).closest('div.select').hide();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
// Go to specified step in wizard,
|
|
// updating nav items and diagram
|
|
var showStep = function(index, options) {
|
|
if (!options) options = {};
|
|
var targetIndex = index - 1;
|
|
|
|
if (index <= 1) targetIndex = 0;
|
|
if (targetIndex == $steps.size()) {
|
|
completeAction();
|
|
return;
|
|
}
|
|
|
|
var $targetStep = $($steps.hide()[targetIndex]).show();
|
|
var stepID = $targetStep.attr('wizard-step-id');
|
|
var formData = cloudStack.serializeForm($form);
|
|
|
|
if (!$targetStep.hasClass('loaded')) {
|
|
// Remove previous content
|
|
if (!$targetStep.hasClass('review')) { // Review row content is not autogenerated
|
|
$targetStep.find('.select-container:not(.fixed) div, option:not(:disabled)').remove();
|
|
}
|
|
|
|
dataProvider(
|
|
index,
|
|
dataGenerators[stepID](
|
|
$targetStep,
|
|
formData
|
|
)
|
|
);
|
|
|
|
$targetStep.addClass('loaded');
|
|
}
|
|
|
|
// Show launch vm button if last step
|
|
var $nextButton = $wizard.find('.button.next');
|
|
$nextButton.find('span').html(_l('label.next'));
|
|
$nextButton.removeClass('final');
|
|
if ($targetStep.hasClass('review')) {
|
|
$nextButton.find('span').html(_l('label.launch.vm'));
|
|
$nextButton.addClass('final');
|
|
}
|
|
|
|
// Hide previous button on first step
|
|
var $previousButton = $wizard.find('.button.previous');
|
|
if (index == 1) $previousButton.hide();
|
|
else $previousButton.show();
|
|
|
|
// Update progress bar
|
|
var $targetProgress = $progress.removeClass('active').filter(function() {
|
|
return $(this).index() <= targetIndex;
|
|
}).toggleClass('active');
|
|
|
|
// Update diagram; show/hide as necessary
|
|
$diagramParts.filter(function() {
|
|
return $(this).index() <= targetIndex;
|
|
}).fadeIn('slow');
|
|
$diagramParts.filter(function() {
|
|
return $(this).index() > targetIndex;
|
|
}).fadeOut('slow');
|
|
|
|
setTimeout(function() {
|
|
if (!$targetStep.find('input[type=radio]:checked').size()) {
|
|
$targetStep.find('input[type=radio]:first').click();
|
|
}
|
|
}, 50);
|
|
};
|
|
|
|
// Events
|
|
$wizard.click(function(event) {
|
|
var $target = $(event.target);
|
|
var $activeStep = $form.find('.step:visible');
|
|
|
|
// Next button
|
|
if ($target.closest('div.button.next').size()) {
|
|
// Make sure ISO or template is selected
|
|
if ($activeStep.hasClass('select-iso') &&
|
|
!$activeStep.find('.content:visible input:checked').size()) {
|
|
cloudStack.dialog.notice({ message: 'message.step.1.continue' });
|
|
return false;
|
|
}
|
|
|
|
//step 5 - select network
|
|
if($activeStep.find('.wizard-step-conditional.select-network:visible').size() > 0) {
|
|
if($activeStep.find('input[type=checkbox]:checked').size() == 0) { //if no checkbox is checked
|
|
cloudStack.dialog.notice({ message: 'message.step.4.continue' });
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//step 6 - review (spcifiy displyname, group as well)
|
|
if ($activeStep.hasClass('review')) {
|
|
if($activeStep.find('input[name=displayname]').size() > 0 && $activeStep.find('input[name=displayname]').val().length > 0) {
|
|
//validate
|
|
var b = cloudStack.validate.vmHostName($activeStep.find('input[name=displayname]').val());
|
|
if(b == false)
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!$form.valid()) {
|
|
if ($form.find('input.error:visible, select.error:visible').size()) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
showStep($steps.filter(':visible').index() + 2);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Previous button
|
|
if ($target.closest('div.button.previous').size()) {
|
|
var index = $steps.filter(':visible').index();
|
|
if (index) showStep(index);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Close button
|
|
if ($target.closest('div.button.cancel').size()) {
|
|
close();
|
|
|
|
return false;
|
|
}
|
|
|
|
// Edit link
|
|
if ($target.closest('div.edit').size()) {
|
|
var $edit = $target.closest('div.edit');
|
|
|
|
showStep($edit.find('a').attr('href'));
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
showStep(1);
|
|
|
|
$wizard.bind('change', function(event) {
|
|
var $target = $(event.target);
|
|
var $step = $target.closest('.step');
|
|
var $futureSteps = $step.siblings().filter(function() {
|
|
return $(this).index() > $step.index();
|
|
});
|
|
|
|
// Reset all fields in futher steps
|
|
$futureSteps.removeClass('loaded');
|
|
});
|
|
|
|
var maxCustomDiskSize = args.maxDiskOfferingSize ?
|
|
args.maxDiskOfferingSize() : 100;
|
|
|
|
// Setup tabs and slider
|
|
$wizard.find('.section.custom-size .size.max span').html(maxCustomDiskSize);
|
|
$wizard.find('.tab-view').tabs();
|
|
$wizard.find('.slider').slider({
|
|
min: 1,
|
|
max: maxCustomDiskSize,
|
|
start: function(event) {
|
|
$wizard.find('div.data-disk-offering div.custom-size input[type=radio]').click();
|
|
},
|
|
slide: function(event, ui) {
|
|
$wizard.find('div.data-disk-offering div.custom-size input[type=text]').val(
|
|
ui.value
|
|
);
|
|
$wizard.find('div.data-disk-offering span.custom-disk-size').html(
|
|
ui.value
|
|
);
|
|
}
|
|
});
|
|
|
|
return $wizard.dialog({
|
|
title: _l('label.vm.add'),
|
|
width: 800,
|
|
height: 570,
|
|
closeOnEscape: false,
|
|
zIndex: 5000
|
|
})
|
|
.closest('.ui-dialog').overlay();
|
|
};
|
|
|
|
instanceWizard(args);
|
|
};
|
|
};
|
|
})(jQuery, cloudStack);
|