\ No newline at end of file
diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs
index 29dfdc58d9..63817a49dc 100644
--- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs
+++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs
@@ -81,11 +81,13 @@
-
- {{{capacityInputsHTML}}}
+
+ {{{capacityCreateHTML}}}
-
- {{#isFeatureEnabled "showback"}}
+
+{{#isFeatureEnabled "showback"}}
+
+
- {{/isFeatureEnabled}}
+{{/isFeatureEnabled}}
diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js
index fcfc33d3d5..803f81c068 100644
--- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js
+++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js
@@ -125,7 +125,7 @@ define(function(require) {
}
capacityContext = $(".capacityContext" + template_id, context);
- $.extend(tmp_json, CapacityInputs.retrieveResize(capacityContext));
+ $.extend(tmp_json, CapacityInputs.retrieveChanges(capacityContext));
extra_info['template'] = tmp_json;
@@ -209,20 +209,19 @@ define(function(require) {
}
if ((cpuCost != 0 || memoryCost != 0) && Config.isFeatureEnabled("showback")) {
- var cost = 0;
-
- var cpu = template_json.VMTEMPLATE.TEMPLATE.CPU;
- var memory = template_json.VMTEMPLATE.TEMPLATE.MEMORY;
-
- if (cpu != undefined && memory != undefined) {
- cost = cpuCost * cpu + memoryCost * memory;
- }
-
- $(".cost_value", capacityContext).html(cost.toFixed(2));
$(".capacity_cost_div", capacityContext).show();
CapacityInputs.setCallback(capacityContext, function(values){
- var cost = cpuCost * values.CPU + memoryCost * values.MEMORY;
+ var cost = 0;
+
+ if (values.CPU != undefined){
+ cost += cpuCost * values.CPU;
+ }
+
+ if (values.MEMORY != undefined){
+ cost += memoryCost * values.MEMORY;
+ }
+
$(".cost_value", capacityContext).html(cost.toFixed(2));
});
}
diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/resize.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/resize.js
index ca70b4a5ac..a41e95ccbe 100644
--- a/src/sunstone/public/app/tabs/vms-tab/dialogs/resize.js
+++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/resize.js
@@ -72,7 +72,7 @@ define(function(require) {
Tips.setup(context);
$('#' + DIALOG_ID + 'Form', context).submit(function() {
- var templateJSON = CapacityInputs.retrieveResize(context);
+ var templateJSON = CapacityInputs.retrieveChanges(context);
var enforce = $("#enforce", this).is(":checked");
diff --git a/src/sunstone/public/app/utils/user-inputs.js b/src/sunstone/public/app/utils/user-inputs.js
index 30ec84b2ed..aba6da9ee1 100644
--- a/src/sunstone/public/app/utils/user-inputs.js
+++ b/src/sunstone/public/app/utils/user-inputs.js
@@ -25,16 +25,27 @@ define(function(require) {
return {
'vmTemplateInsert': _generateVMTemplateUserInputs,
- 'serviceTemplateInsert': _generateServiceTemplateUserInputs
- }
+ 'serviceTemplateInsert': _generateServiceTemplateUserInputs,
+ 'marshall': _marshall,
+ 'unmarshall': _unmarshall,
+ 'parse': _parse,
+ 'generateInputElement': _generateInputElement,
+ 'attributeInput': _attributeInput
+ };
// It will replace the div's html with a row for each USER_INPUTS
// opts.text_header: header text for the text & password inputs
// opts.network_header: header text for the network inputs
// returns true if at least one input was inserted
function _generateVMTemplateUserInputs(div, template_json, opts) {
- return _generateInstantiateUserInputs(
- div, template_json.VMTEMPLATE.TEMPLATE.USER_INPUTS, opts);
+ // Delete the special user inputs for the capacity
+ var inputs = $.extend({}, template_json.VMTEMPLATE.TEMPLATE.USER_INPUTS);
+
+ delete inputs["CPU"];
+ delete inputs["MEMORY"];
+ delete inputs["VCPU"];
+
+ return _generateInstantiateUserInputs(div, inputs, opts);
}
// It will replace the div's html with a row for each USER_INPUTS
@@ -70,27 +81,15 @@ define(function(require) {
}
var network_attrs = [];
- var text_attrs = [];
+ var input_attrs = [];
$.each(user_inputs, function(key, value) {
- var parts = value.split("|");
- // 0 mandatory; 1 type; 2 desc;
- var attrs = {
- "name": key,
- "mandatory": parts[0],
- "type": parts[1],
- "description": parts[2],
- }
+ var attrs = _parse(key, value);
- switch (parts[1]) {
- case "vnet_id":
- network_attrs.push(attrs)
- break;
- case "text":
- case "text64":
- case "password":
- text_attrs.push(attrs)
- break;
+ if (attrs.type == "vnet_id"){
+ network_attrs.push(attrs);
+ } else {
+ input_attrs.push(attrs);
}
});
@@ -137,7 +136,7 @@ define(function(require) {
});
}
- if (text_attrs.length > 0) {
+ if (input_attrs.length > 0) {
if (opts.text_header.length > 0) {
div.append(
' ' +
@@ -152,33 +151,229 @@ define(function(require) {
div.append('');
- $.each(text_attrs, function(index, custom_attr) {
- var input;
-
- switch (custom_attr.type) {
- case "text":
- input = '';
- break;
- case "text64":
- input = '';
- break;
- case "password":
- input = '';
- break;
- }
-
+ $.each(input_attrs, function(index, custom_attr) {
$(".instantiate_user_inputs", div).append(
'
' +
'
' +
'' +
'
' +
'
');
});
}
- return (network_attrs.length > 0 || text_attrs.length > 0);
+ return (network_attrs.length > 0 || input_attrs.length > 0);
}
-})
+
+ /**
+ * Transforms a user input object to a string
+ * @param {object} attr user input object, e.g.
+ * { "name":
+ * "mandatory": true/false
+ * "type":
+ * "description":
+ * ["params":] "2..8" / "2,4,8"
+ * ["initial":] "3"
+ * }
+ * @return {string} String in the form "M|range|Description here|2..8|4"
+ */
+ function _marshall(attr) {
+ var st = "";
+
+ st += (attr.mandatory ? "M" : "O") + "|" +
+ (attr.type != undefined ? attr.type : "text") + "|" +
+ (attr.description != undefined ? attr.description : "");
+
+ switch (attr.type) {
+ case "number":
+ case "number-float":
+ st += ("| |" + (attr.initial != undefined ? attr.initial : "") );
+
+ break;
+ case "range":
+ case "range-float":
+ case "list":
+ st += ("|" + (attr.params != undefined ? attr.params : "") +
+ "|" + (attr.initial != undefined ? attr.initial : "") );
+
+ break;
+ }
+
+ return st;
+ }
+
+ /**
+ * Transforms a user input string to an object
+ * @param {string} value String in the form "M|range|Description here|2..8|4"
+ * @return {object} user input object, e.g.
+ * { "mandatory": true/false
+ * "type":
+ * "description":
+ * ["params":] "2..8" / "2,4,8"
+ * ["initial":] "3"
+ * }
+ */
+ function _unmarshall(value) {
+ var parts = value.split("|");
+
+ var attr = {
+ "mandatory": (parts[0] == "M"),
+ "type": parts[1],
+ "description": parts[2],
+ };
+
+ if (parts[3] != undefined){
+ attr.params = parts[3];
+ }
+
+ if (parts[4] != undefined){
+ attr.initial = parts[4];
+ }
+
+ return attr;
+ }
+
+ /**
+ * Returns a structure with the user input parameters
+ * @param {string} name Template Attribute name, e.g. USER_PASSWORD
+ * @param {string} value Template Attribute value,
+ * e.g. "M|range|Description here|2..8|4"
+ * @return {object} { "name":
+ "mandatory":
+ "type":
+ "description":
+ ["params":] "2..8" / "2,4,8"
+ ["initial":]
+ ["min":]
+ ["max":]
+ ["step":]
+ ["options":]
+ }
+ */
+ function _parse(name, value) {
+ var attr = _unmarshall(value);
+
+ attr.name = name;
+
+ // TODO: error management (params undefined)
+
+ switch (attr.type) {
+ case "number":
+ attr.step = "1";
+ break;
+
+ case "number-float":
+ attr.step = "0.01";
+ break;
+
+ case "range":
+ var params = attr.params.split(".."); // "2..8"
+
+ attr.min = parseInt( params[0] );
+ attr.max = parseInt( params[1] );
+ attr.step = "1";
+
+ break;
+
+ case "range-float":
+ var params = attr.params.split(".."); // "2.4..8.75"
+
+ attr.min = parseFloat( params[0] );
+ attr.max = parseFloat( params[1] );
+ attr.step = "0.01";
+
+ break;
+
+ case "list":
+ attr.options = attr.params.split(","); // "2,4,16"
+
+ break;
+ }
+
+ return attr;
+ }
+
+ /**
+ * Returns an html for the given user input attribute
+ * @param {object} attr structure as returned by parse
+ * @return {string} string containing an html element
+ */
+ function _attributeInput(attr) {
+ var input;
+
+ switch (attr.type) {
+ case "text":
+ input = '';
+ break;
+ case "text64":
+ input = '';
+ break;
+ case "password":
+ input = '';
+ break;
+ case "number":
+ case "number-float":
+ input = '';
+ break;
+ case "range":
+ case "range-float":
+ input =
+ '
'+
+ '
'+
+ ''+
+ '
'+
+ '
'+
+ ''+
+ '
'+
+ '
';
+
+ $(document).off("input", "input.uinput-slider-val");
+ $(document).on("input", "input.uinput-slider-val", function(){
+ $("input[type=range]", $(this).closest('.uinput-slider-container')).val( this.value );
+ });
+
+ $(document).off("input", "input.uinput-slider");
+ $(document).on("input", "input.uinput-slider", function(){
+ $("input[type=number]", $(this).closest('.uinput-slider-container')).val( this.value );
+ });
+
+ break;
+ case "list":
+ input = '';
+
+ break;
+ }
+
+ return input;
+ }
+
+ /**
+ * Returns an html for the given USER_INPUT attribute
+ * @param {string} name Template Attribute name, e.g. USER_PASSWORD
+ * @param {string} value Template Attribute value,
+ * e.g. "M|range|Description here|2..8|4"
+ * @return {string} string containing an html element
+ */
+ function _generateInputElement(name, value) {
+ var attrs = _parse(name, value);
+
+ return _attributeInput(attrs);
+ }
+});
diff --git a/src/sunstone/public/scss/app.scss b/src/sunstone/public/scss/app.scss
index c4588e8339..571698d41d 100644
--- a/src/sunstone/public/scss/app.scss
+++ b/src/sunstone/public/scss/app.scss
@@ -1470,4 +1470,14 @@ div.vis-network-tooltip {
background: #bfbfbf;
}
}
+}
+
+// For abide validation
+
+.error input {
+ border-bottom-color: $alert-color !important;
+}
+
+.error textarea {
+ border-bottom-color: $alert-color !important;
}
\ No newline at end of file