mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-26 06:50:09 +03:00
Feature #4317: Add new user-input types, make capacity user-inputs
New types: number, range, list. The capacity definition creates user inputs for the CPU, MEMORY and VCPU
This commit is contained in:
parent
6653c64c6e
commit
1f1d0fcf01
@ -27,6 +27,7 @@ define(function(require) {
|
||||
var CustomTagsTable = require('utils/custom-tags-table');
|
||||
var FilesTable = require('tabs/files-tab/datatable')
|
||||
var OpenNebulaHost = require('opennebula/host');
|
||||
var UserInputs = require('utils/user-inputs');
|
||||
|
||||
/*
|
||||
TEMPLATES
|
||||
@ -161,28 +162,76 @@ define(function(require) {
|
||||
that.contextFilesTable.initialize(selectOptions);
|
||||
that.contextFilesTable.refreshResourceTableSelect();
|
||||
|
||||
// TODO: bug, user_input_name pattern is ignored
|
||||
|
||||
context.on("click", ".add_service_custom_attr", function() {
|
||||
$(".service_custom_attrs tbody").append(
|
||||
$(".service_custom_attrs tbody", context).append(
|
||||
'<tr>' +
|
||||
'<td>' +
|
||||
'<input class="user_input_name" type="text" pattern="[\\w]+"/>' +
|
||||
'<small class="error">' + Locale.tr("Only word characters are allowed") + '</small>' +
|
||||
'<label>' + Locale.tr("Name") +
|
||||
'<input class="user_input_name" type="text" pattern="[\\w]+"/>' +
|
||||
'<small class="error">' + Locale.tr("Only word characters are allowed") + '</small>' +
|
||||
'</label>' +
|
||||
'</td>' +
|
||||
'<td>' +
|
||||
'<select class="user_input_type" >' +
|
||||
'<option value="text">' + Locale.tr("text") + '</option>' +
|
||||
'<option value="text64">' + Locale.tr("text (base64)") + '</option>' +
|
||||
'<option value="password">' + Locale.tr("password") + '</option>' +
|
||||
'</select>' +
|
||||
'<label>' + Locale.tr("Type") +
|
||||
'<select class="user_input_type" >' +
|
||||
'<option value="text">' + Locale.tr("text") + '</option>' +
|
||||
'<option value="text64">' + Locale.tr("text (base64)") + '</option>' +
|
||||
'<option value="password">' + Locale.tr("password") + '</option>' +
|
||||
'<option value="number">' + Locale.tr("number") + '</option>' +
|
||||
'<option value="number-float">'+Locale.tr("number (float)") + '</option>' +
|
||||
'<option value="range">' + Locale.tr("range") + '</option>' +
|
||||
'<option value="range-float">' +Locale.tr("range (float)") + '</option>' +
|
||||
'<option value="list">' + Locale.tr("list") + '</option>' +
|
||||
'</select>' +
|
||||
'</label>' +
|
||||
'</td>' +
|
||||
'<td>' +
|
||||
'<textarea class="user_input_description"/>' +
|
||||
'<label>' + Locale.tr("Description") +
|
||||
'<textarea class="user_input_description"/>' +
|
||||
'</label>' +
|
||||
|
||||
'<div class="user_input_type_right number number-float">' +
|
||||
'<label class="user_input_opt">' + Locale.tr("Default value") +
|
||||
'<input type=text class="user_input_initial" placeholder="42"/>' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
|
||||
'<div class="user_input_type_right range range-float">' +
|
||||
'<label class="user_input_opt">' + Locale.tr("Options") +
|
||||
'<input type=text class="user_input_params" placeholder="2..16"/>' +
|
||||
'</label>' +
|
||||
'<label class="user_input_opt">' + Locale.tr("Default value") +
|
||||
'<input type=text class="user_input_initial" placeholder="8"/>' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
|
||||
'<div class="user_input_type_right list">' +
|
||||
'<label class="user_input_opt">' + Locale.tr("Options") +
|
||||
'<input type=text class="user_input_params" placeholder="optA,optB,optC"/>' +
|
||||
'</label>' +
|
||||
'<label class="user_input_opt">' + Locale.tr("Default value") +
|
||||
'<input type=text class="user_input_initial" placeholder="optB"/>' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
|
||||
'</td>' +
|
||||
'<td>' +
|
||||
'</br>' +
|
||||
'<a href="#"><i class="fa fa-times-circle remove-tab"></i></a>' +
|
||||
'</td>' +
|
||||
'</tr>');
|
||||
})
|
||||
|
||||
$("select.user_input_type", context).change();
|
||||
});
|
||||
|
||||
context.on("change", "select.user_input_type", function() {
|
||||
var row = $(this).closest("tr");
|
||||
$(".user_input_type_right", row).hide();
|
||||
|
||||
$(".user_input_type_right."+this.value, row).show();
|
||||
});
|
||||
|
||||
context.on("click", ".service_custom_attrs i.remove-tab", function() {
|
||||
var tr = $(this).closest('tr');
|
||||
@ -241,11 +290,29 @@ define(function(require) {
|
||||
var userInputsJSON = {};
|
||||
$(".service_custom_attrs tbody tr", context).each(function() {
|
||||
if ($(".user_input_name", $(this)).val()) {
|
||||
var attr_name = $(".user_input_name", $(this)).val();
|
||||
var attr_type = $(".user_input_type", $(this)).val();
|
||||
var attr_desc = $(".user_input_description", $(this)).val();
|
||||
userInputsJSON[attr_name] = "M|" + attr_type + "|" + attr_desc;
|
||||
contextJSON[attr_name] = "$" + attr_name.toUpperCase();
|
||||
var attr = {};
|
||||
attr.name = $(".user_input_name", $(this)).val();
|
||||
attr.mandatory = true;
|
||||
attr.type = $(".user_input_type", $(this)).val();
|
||||
attr.description = $(".user_input_description", $(this)).val();
|
||||
|
||||
switch(attr.type){
|
||||
case "number":
|
||||
case "number-float":
|
||||
attr.initial = $("."+attr.type+" input.user_input_initial", $(this)).val();
|
||||
break;
|
||||
|
||||
case "range":
|
||||
case "range-float":
|
||||
case "list":
|
||||
attr.params = $("."+attr.type+" input.user_input_params", $(this)).val();
|
||||
attr.initial = $("."+attr.type+" input.user_input_initial", $(this)).val();
|
||||
break;
|
||||
}
|
||||
|
||||
userInputsJSON[attr.name] = UserInputs.marshall(attr);
|
||||
|
||||
contextJSON[attr.name] = "$" + attr.name.toUpperCase();
|
||||
}
|
||||
});
|
||||
|
||||
@ -300,10 +367,27 @@ define(function(require) {
|
||||
$(".add_service_custom_attr", context).trigger("click");
|
||||
|
||||
var context = $(".service_custom_attrs tbody tr", context).last();
|
||||
var parts = value.split("|");
|
||||
|
||||
$(".user_input_name", context).val(key);
|
||||
$(".user_input_type", context).val(parts[1]);
|
||||
$(".user_input_description", context).val(TemplateUtils.escapeDoubleQuotes(TemplateUtils.htmlDecode(parts[2])));
|
||||
|
||||
var attr = UserInputs.unmarshall(value);
|
||||
|
||||
$(".user_input_type", context).val(attr.type).change();
|
||||
$(".user_input_description", context).val(attr.description);
|
||||
|
||||
switch(attr.type){
|
||||
case "number":
|
||||
case "number-float":
|
||||
$("."+attr.type+" input.user_input_initial", context).val(attr.initial);
|
||||
break;
|
||||
|
||||
case "range":
|
||||
case "range-float":
|
||||
case "list":
|
||||
$("."+attr.type+" input.user_input_params", context).val(attr.params);
|
||||
$("."+attr.type+" input.user_input_initial", context).val(attr.initial);
|
||||
break;
|
||||
}
|
||||
|
||||
if (contextJSON) {
|
||||
delete contextJSON[key];
|
||||
|
@ -112,13 +112,14 @@
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:30%">{{tr "Name"}}</th>
|
||||
<th style="width:20%">{{tr "Type"}}</th>
|
||||
<th style="width:50%">{{tr "Description"}}</th>
|
||||
<th style="width:30%"></th>
|
||||
<th style="width:20%"></th>
|
||||
<th style="width:50%"></th>
|
||||
<th style="width:3%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tbody style="vertical-align:top">
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
|
@ -21,7 +21,7 @@ define(function(require) {
|
||||
|
||||
var Locale = require('utils/locale');
|
||||
var Tips = require('utils/tips');
|
||||
var CapacityInputs = require('./general/capacity-inputs');
|
||||
var CapacityCreate = require('./general/capacity-create');
|
||||
var WizardFields = require('utils/wizard-fields');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
@ -62,7 +62,7 @@ define(function(require) {
|
||||
|
||||
function _html() {
|
||||
return TemplateHTML({
|
||||
'capacityInputsHTML': CapacityInputs.html(),
|
||||
'capacityCreateHTML': CapacityCreate.html(),
|
||||
'logos': Config.vmLogos
|
||||
});
|
||||
}
|
||||
@ -103,7 +103,7 @@ define(function(require) {
|
||||
// There is another listener in context.js setup
|
||||
});
|
||||
|
||||
CapacityInputs.setup(context);
|
||||
CapacityCreate.setup($("div.capacityCreate", context));
|
||||
}
|
||||
|
||||
function _retrieve(context) {
|
||||
@ -131,6 +131,8 @@ define(function(require) {
|
||||
templateJSON['SUNSTONE'] = sunstone_template;
|
||||
}
|
||||
|
||||
$.extend(templateJSON, CapacityCreate.retrieve($("div.capacityCreate", context)));
|
||||
|
||||
return templateJSON;
|
||||
}
|
||||
|
||||
@ -182,6 +184,8 @@ define(function(require) {
|
||||
delete templateJSON["HYPERVISOR"];
|
||||
}
|
||||
|
||||
CapacityCreate.fill($("div.capacityCreate", context), templateJSON);
|
||||
|
||||
WizardFields.fill(context, templateJSON);
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,246 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* Licensed 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
/*
|
||||
DEPENDENCIES
|
||||
*/
|
||||
|
||||
require('foundation.slider');
|
||||
var Locale = require('utils/locale');
|
||||
var Tips = require('utils/tips');
|
||||
var WizardFields = require('utils/wizard-fields');
|
||||
var UserInputs = require('utils/user-inputs');
|
||||
|
||||
/*
|
||||
TEMPLATES
|
||||
*/
|
||||
|
||||
var TemplateHTML = require('hbs!./capacity-create/html');
|
||||
|
||||
/*
|
||||
CONSTRUCTOR
|
||||
*/
|
||||
|
||||
return {
|
||||
'html': _html,
|
||||
'setup': _setup,
|
||||
'fill': _fill,
|
||||
'retrieve': _retrieve
|
||||
};
|
||||
|
||||
/*
|
||||
FUNCTION DEFINITIONS
|
||||
*/
|
||||
|
||||
function _html() {
|
||||
return TemplateHTML();
|
||||
}
|
||||
|
||||
function _setup(context) {
|
||||
// MB to GB
|
||||
context.on("input", "div.memory_input input", function(){
|
||||
if (this.value && this.value >= 0) {
|
||||
$("div.memory_gb_input input", context).val( this.value / 1024 );
|
||||
} else {
|
||||
$("div.memory_gb_input input", context).val("");
|
||||
}
|
||||
});
|
||||
|
||||
// MB to GB, range input
|
||||
context.on("input", "div.memory_modify_opt.range input.mb_unit", function(){
|
||||
var val = this.value.split("..").map(function(e){
|
||||
if(isNaN(e) || e == ""){
|
||||
return "";
|
||||
}
|
||||
|
||||
return e / 1024;
|
||||
}).join("..");
|
||||
|
||||
$("div.memory_modify_opt.range input.gb_unit", context).val(val);
|
||||
});
|
||||
|
||||
// MB to GB, list input
|
||||
context.on("input", "div.memory_modify_opt.list input.mb_unit", function(){
|
||||
var val = this.value.split(",").map(function(e){
|
||||
if(isNaN(e) || e == ""){
|
||||
return "";
|
||||
}
|
||||
|
||||
return e / 1024;
|
||||
}).join(",");
|
||||
|
||||
$("div.memory_modify_opt.list input.gb_unit", context).val(val);
|
||||
});
|
||||
|
||||
// GB to MB
|
||||
context.on("input", "div.memory_gb_input input", function(){
|
||||
if (this.value && this.value >= 0) {
|
||||
$("div.memory_input input", context).val( Math.floor(this.value * 1024) );
|
||||
} else {
|
||||
$("div.memory_input input", context).val("");
|
||||
}
|
||||
});
|
||||
|
||||
// GB to MB, range input
|
||||
context.on("input", "div.memory_modify_opt.range input.gb_unit", function(){
|
||||
var val = this.value.split("..").map(function(e){
|
||||
if(isNaN(e) || e == ""){
|
||||
return "";
|
||||
}
|
||||
|
||||
return Math.floor(e * 1024);
|
||||
}).join("..");
|
||||
|
||||
$("div.memory_modify_opt.range input.mb_unit", context).val(val);
|
||||
});
|
||||
|
||||
// GB to MB, list input
|
||||
context.on("input", "div.memory_modify_opt.list input.gb_unit", function(){
|
||||
var val = this.value.split(",").map(function(e){
|
||||
if(isNaN(e) || e == ""){
|
||||
return "";
|
||||
}
|
||||
|
||||
return Math.floor(e * 1024);
|
||||
}).join(",");
|
||||
|
||||
$("div.memory_modify_opt.list input.mb_unit", context).val(val);
|
||||
});
|
||||
|
||||
// Unit select
|
||||
$("#memory_unit", context).on('change', function() {
|
||||
var memory_unit_val = $('#memory_unit :selected', context).val();
|
||||
|
||||
if (memory_unit_val == 'GB') {
|
||||
$(".mb_unit", context).hide();
|
||||
$(".gb_unit", context).show();
|
||||
} else {
|
||||
$(".mb_unit", context).show();
|
||||
$(".gb_unit", context).hide();
|
||||
}
|
||||
|
||||
$(".memory_modify_unit", context).text(memory_unit_val);
|
||||
});
|
||||
|
||||
$("#memory_unit", context).change();
|
||||
|
||||
// Select for memory, cpu, vcpu modification on instantiate
|
||||
$.each(["memory","cpu","vcpu"], function(i,classname){
|
||||
$("."+classname+"_modify_type", context).on("change", function(){
|
||||
$("."+classname+"_modify_opt", context).hide();
|
||||
$("."+classname+"_modify_opt."+this.value, context).show();
|
||||
|
||||
$("#memory_unit", context).change();
|
||||
});
|
||||
|
||||
$("."+classname+"_modify_type", context).change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the capacity inputs
|
||||
* @param {Object} context JQuery selector
|
||||
* @param {Object} template VM or VMTemplate object
|
||||
*/
|
||||
function _fill(context, element) {
|
||||
|
||||
var fields = $('[wizard_field]', context);
|
||||
|
||||
fields.each(function() {
|
||||
var field_name = $(this).attr('wizard_field');
|
||||
$(this).data("original_value", element[field_name]);
|
||||
});
|
||||
|
||||
WizardFields.fill(context, element);
|
||||
|
||||
// Update memory_gb with the value set in memory
|
||||
$("div.memory_input input", context).trigger("input");
|
||||
|
||||
if ($("div.memory_input input", context).val() && $("div.memory_input input", context).val() < 1024){
|
||||
$("#memory_unit", context).val("MB").change();
|
||||
} else {
|
||||
$("#memory_unit", context).val("GB").change();
|
||||
}
|
||||
|
||||
var userInputsJSON = element['USER_INPUTS'];
|
||||
|
||||
if (userInputsJSON) {
|
||||
$.each(["memory","cpu","vcpu"], function(i,classname){
|
||||
var name = classname.toUpperCase();
|
||||
|
||||
if (userInputsJSON[name] != undefined){
|
||||
var attr = UserInputs.unmarshall(userInputsJSON[name]);
|
||||
|
||||
$("."+classname+"_modify_type", context).val(attr.type).change();
|
||||
|
||||
$("input."+classname+"_modify_opt."+attr.type, context).val(attr.params).trigger("input");
|
||||
|
||||
delete userInputsJSON[name];
|
||||
} else {
|
||||
$("."+classname+"_modify_type", context).val("fixed").change();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the input values
|
||||
* @param {Object} context JQuery selector
|
||||
* @return {Object} If the input is not empty, returns:
|
||||
* - CPU
|
||||
* - MEMORY
|
||||
* - VCPU
|
||||
* - USER_INPUTS for cpu, memory, vcpu
|
||||
*/
|
||||
function _retrieve(context) {
|
||||
var templateJSON = WizardFields.retrieve(context);
|
||||
|
||||
var userInputsJSON = {};
|
||||
|
||||
$.each(["memory","cpu","vcpu"], function(i,classname){
|
||||
var attr = {};
|
||||
|
||||
attr.type = $("."+classname+"_modify_type", context).val();
|
||||
|
||||
if (attr.type == "fixed"){
|
||||
// No user input, continue
|
||||
return true;
|
||||
}
|
||||
|
||||
attr.name = classname.toUpperCase();
|
||||
attr.mandatory = true;
|
||||
attr.description = "";
|
||||
|
||||
attr.initial = $('input[wizard_field="'+attr.name+'"]', context).val();
|
||||
|
||||
if (attr.type == "range" ||
|
||||
attr.type == "range-float" ||
|
||||
attr.type == "list"){
|
||||
|
||||
attr.params = $("input."+classname+"_modify_opt."+attr.type, context).val();
|
||||
}
|
||||
|
||||
userInputsJSON[attr.name] = UserInputs.marshall(attr);
|
||||
});
|
||||
|
||||
if (!$.isEmptyObject(userInputsJSON)) {
|
||||
templateJSON['USER_INPUTS'] = userInputsJSON;
|
||||
}
|
||||
|
||||
return templateJSON;
|
||||
}
|
||||
});
|
@ -0,0 +1,148 @@
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
{{! Copyright 2002-2015, OpenNebula Project, OpenNebula Systems }}
|
||||
{{! }}
|
||||
{{! Licensed 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. }}
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns">
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label class="" for="MEMORY">
|
||||
{{tr "Memory"}}
|
||||
{{{tip (tr "Amount of RAM required for the VM, in Megabytes.")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="small-8 columns">
|
||||
<div class="mb_unit memory_input">
|
||||
<input type="number" min="0" step="256" wizard_field="MEMORY" id="MEMORY"/>
|
||||
</div>
|
||||
<div class="gb_unit memory_gb_input">
|
||||
<input type="number" min="0" step="0.25" name="memory_gb"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-4 columns">
|
||||
<select id="memory_unit" name="MEMORY_UNIT">
|
||||
<option value="MB">{{tr "MB"}}</option>
|
||||
<option value="GB" selected>{{tr "GB"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-6 small-12 columns">
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label>
|
||||
{{tr "Memory modification"}}
|
||||
{{{tip (tr "Allow users to modify this template's memory on instantiate")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="small-4 columns">
|
||||
<select class="memory_modify_type" >
|
||||
<option value="fixed">{{tr "fixed"}}</option>
|
||||
<option selected value="number">{{tr "number"}}</option>
|
||||
<option value="range">{{tr "range"}}</option>
|
||||
<option value="list">{{tr "list"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small-6 columns">
|
||||
<div class="memory_modify_opt range">
|
||||
<input type=text class="mb_unit memory_modify_opt range" placeholder="512..4096"/>
|
||||
<input type=text class="gb_unit" placeholder="0.5..4"/>
|
||||
</div>
|
||||
<div class="memory_modify_opt list">
|
||||
<input type=text class="mb_unit memory_modify_opt list" placeholder="1024,4096,8192"/>
|
||||
<input type=text class="gb_unit" placeholder="1,4,8"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-2 columns">
|
||||
<span class="memory_modify_opt range list memory_modify_unit">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns">
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label class="" for="CPU">
|
||||
{{tr "CPU"}}
|
||||
{{{tip (tr "Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.")}}}
|
||||
</label>
|
||||
<div class="cpu_input">
|
||||
<input type="number" step="0.01" min="0" wizard_field="CPU" id="CPU"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-6 small-12 columns">
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label>
|
||||
{{tr "CPU modification"}}
|
||||
{{{tip (tr "Allow users to modify this template's CPU on instantiate")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="small-4 columns">
|
||||
<select class="cpu_modify_type" >
|
||||
<option value="fixed">{{tr "fixed"}}</option>
|
||||
<option selected value="number">{{tr "number"}}</option>
|
||||
<option value="range">{{tr "range"}}</option>
|
||||
<option value="list">{{tr "list"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small-8 columns">
|
||||
<input type=text class="cpu_modify_opt range" placeholder="0.5..8"/>
|
||||
<input type=text class="cpu_modify_opt list" placeholder="0.5,1,4,16"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns">
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label class="" for="VCPU">
|
||||
{{tr "VCPU"}}
|
||||
{{{tip (tr "Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")}}}
|
||||
</label>
|
||||
<div class="vcpu_input">
|
||||
<input type="number" step="1" min="0" wizard_field="VCPU" id="VCPU"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-6 small-12 columns">
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label>
|
||||
{{tr "VCPU modification"}}
|
||||
{{{tip (tr "Allow users to modify this template's VCPU on instantiate")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="small-4 columns">
|
||||
<select class="vcpu_modify_type" >
|
||||
<option value="fixed">{{tr "fixed"}}</option>
|
||||
<option selected value="number">{{tr "number"}}</option>
|
||||
<option value="range">{{tr "range"}}</option>
|
||||
<option value="list">{{tr "list"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small-8 columns">
|
||||
<input type=text class="vcpu_modify_opt range" placeholder="1..8"/>
|
||||
<input type=text class="vcpu_modify_opt list" placeholder="4,8,16"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -23,6 +23,7 @@ define(function(require) {
|
||||
var Locale = require('utils/locale');
|
||||
var Tips = require('utils/tips');
|
||||
var WizardFields = require('utils/wizard-fields');
|
||||
var UserInputs = require('utils/user-inputs');
|
||||
|
||||
/*
|
||||
TEMPLATES
|
||||
@ -40,7 +41,7 @@ define(function(require) {
|
||||
'setCallback': _setCallback,
|
||||
'fill': _fill,
|
||||
'retrieve': _retrieve,
|
||||
'retrieveResize': _retrieveResize
|
||||
'retrieveChanges': _retrieveChanges
|
||||
};
|
||||
|
||||
/*
|
||||
@ -52,139 +53,38 @@ define(function(require) {
|
||||
}
|
||||
|
||||
function _setup(context) {
|
||||
// Define the cpu slider
|
||||
var cpu_input = $("#CPU", context);
|
||||
var cpu_slider = $("#cpu_slider", context)
|
||||
|
||||
context.foundation('slider', 'reflow');
|
||||
|
||||
//cpu_slider.attr('data-options', 'start: 0; end: 1600; step: 50;');
|
||||
|
||||
cpu_slider.on('change.fndtn.slider', function(){
|
||||
if ($(this).attr('data-slider') >= 0) {
|
||||
cpu_input.val($(this).attr('data-slider') / 100);
|
||||
}
|
||||
});
|
||||
|
||||
cpu_input.on('change', function() {
|
||||
// MB to GB
|
||||
context.on("input", "div.memory_input input", function(){
|
||||
if (this.value && this.value >= 0) {
|
||||
cpu_slider.foundation('slider', 'set_value', this.value * 100);
|
||||
$("div.memory_gb_input input", context).val( this.value / 1024 );
|
||||
} else {
|
||||
cpu_slider.foundation('slider', 'set_value', -1);
|
||||
$("div.memory_gb_input input", context).val("");
|
||||
}
|
||||
});
|
||||
|
||||
cpu_slider.foundation('slider', 'set_value', 100);
|
||||
|
||||
// Define the memory slider
|
||||
|
||||
var final_memory_input = $("#MEMORY", context);
|
||||
var memory_input = $("#MEMORY_TMP", context);
|
||||
var memory_unit = $("#memory_unit", context);
|
||||
|
||||
var current_memory_unit = memory_unit.val();
|
||||
|
||||
var update_final_memory_input = function() {
|
||||
if (current_memory_unit == 'MB') {
|
||||
final_memory_input.val(Math.floor(memory_input.val()));
|
||||
} else {
|
||||
final_memory_input.val(Math.floor(memory_input.val() * 1024));
|
||||
}
|
||||
}
|
||||
|
||||
memory_input.on('change', function() {
|
||||
// GB to MB
|
||||
context.on("input", "div.memory_gb_input input", function(){
|
||||
if (this.value && this.value >= 0) {
|
||||
$("#memory_slider", context).foundation('slider', 'set_value', this.value * 100);
|
||||
update_final_memory_input();
|
||||
$("div.memory_input input", context).val( Math.floor(this.value * 1024) );
|
||||
} else {
|
||||
$("#memory_slider", context).foundation('slider', 'set_value', -1);
|
||||
final_memory_input.val("");
|
||||
$("div.memory_input input", context).val("");
|
||||
}
|
||||
});
|
||||
|
||||
final_memory_input.on('change', function() {
|
||||
if (this.value && this.value >= 0) {
|
||||
$("#memory_slider", context).foundation('slider', 'set_value', this.value * 100);
|
||||
memory_input.val(Math.floor(this.value));
|
||||
} else {
|
||||
$("#memory_slider", context).foundation('slider', 'set_value', -1);
|
||||
memory_input.val("");
|
||||
}
|
||||
});
|
||||
|
||||
$("#memory_slider", context).on('change.fndtn.slider', function() {
|
||||
if ($(this).attr('data-slider') >= 0) {
|
||||
memory_input.val($(this).attr('data-slider') / 100);
|
||||
update_final_memory_input();
|
||||
}
|
||||
});
|
||||
|
||||
memory_unit.on('change', function() {
|
||||
// Unit select
|
||||
$("#memory_unit", context).on('change', function() {
|
||||
var memory_unit_val = $('#memory_unit :selected', context).val();
|
||||
|
||||
if (current_memory_unit != memory_unit_val) {
|
||||
current_memory_unit = memory_unit_val
|
||||
var new_val;
|
||||
if (memory_unit_val == 'GB') {
|
||||
$("#memory_slider", context).detach();
|
||||
$(".memory_slider_container", context).html(
|
||||
'<div id="memory_slider" class="range-slider radius" data-slider data-options="start: 0; end: 1600; step: 50;">'+
|
||||
'<span class="range-slider-handle"></span>'+
|
||||
'<span class="range-slider-active-segment"></span>'+
|
||||
'<input type="hidden">'+
|
||||
'</div>');
|
||||
|
||||
new_val = memory_input.val() / 1024;
|
||||
} else if (memory_unit_val == 'MB') {
|
||||
$("#memory_slider", context).detach();
|
||||
$(".memory_slider_container", context).html(
|
||||
'<div id="memory_slider" class="range-slider radius" data-slider data-options="start: 0; end: 409600; step: 12800;">'+
|
||||
'<span class="range-slider-handle"></span>'+
|
||||
'<span class="range-slider-active-segment"></span>'+
|
||||
'<input type="hidden">'+
|
||||
'</div>');
|
||||
|
||||
new_val = Math.floor(memory_input.val() * 1024);
|
||||
}
|
||||
|
||||
$("#memory_slider", context).foundation('slider', 'reflow');
|
||||
memory_input.val(new_val);
|
||||
$("#memory_slider", context).foundation('slider', 'set_value', new_val * 100);
|
||||
$("#memory_slider", context).on('change.fndtn.slider', function() {
|
||||
if ($(this).attr('data-slider') >= 0) {
|
||||
memory_input.val($(this).attr('data-slider') / 100);
|
||||
update_final_memory_input();
|
||||
}
|
||||
});
|
||||
|
||||
update_final_memory_input();
|
||||
}
|
||||
});
|
||||
|
||||
// init::start is ignored for some reason
|
||||
$("#memory_slider", context).foundation('slider', 'set_value', 51200);
|
||||
|
||||
// Define the vcpu slider
|
||||
|
||||
var vcpu_input = $("#VCPU", context);
|
||||
var vcpu_slider = $("#vcpu_slider", context)
|
||||
|
||||
//vcpu_slider.attr('data-options', 'start: 0; end: 1600; step: 50;');
|
||||
vcpu_slider.on('change.fndtn.slider', function(){
|
||||
if ($(this).attr('data-slider') > 0) {
|
||||
vcpu_input.val($(this).attr('data-slider') / 100);
|
||||
}
|
||||
});
|
||||
|
||||
vcpu_input.on('change', function() {
|
||||
if (this.value && this.value > 0) {
|
||||
vcpu_slider.foundation('slider', 'set_value', this.value * 100);
|
||||
if (memory_unit_val == 'GB') {
|
||||
$("div.memory_input", context).hide();
|
||||
$("div.memory_gb_input", context).show();
|
||||
} else {
|
||||
vcpu_slider.foundation('slider', 'set_value', -1);
|
||||
$("div.memory_input", context).show();
|
||||
$("div.memory_gb_input", context).hide();
|
||||
}
|
||||
});
|
||||
|
||||
vcpu_slider.foundation('slider', 'set_value', 0);
|
||||
$("#memory_unit", context).change();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,6 +101,61 @@ define(function(require) {
|
||||
});
|
||||
|
||||
WizardFields.fill(context, element.TEMPLATE);
|
||||
|
||||
var userInputs = element.TEMPLATE.USER_INPUTS;
|
||||
if (userInputs != undefined){
|
||||
|
||||
if (userInputs.CPU != undefined){
|
||||
var input = UserInputs.generateInputElement("CPU", userInputs.CPU);
|
||||
|
||||
$("div.cpu_input", context).html(input);
|
||||
}
|
||||
|
||||
if (userInputs.VCPU != undefined){
|
||||
var input = UserInputs.generateInputElement("VCPU", userInputs.VCPU);
|
||||
|
||||
$("div.vcpu_input", context).html(input);
|
||||
}
|
||||
|
||||
if (userInputs.MEMORY != undefined){
|
||||
// Normal input for MB
|
||||
var attr = UserInputs.parse("MEMORY", userInputs.MEMORY);
|
||||
attr.step = 256;
|
||||
var input = UserInputs.attributeInput(attr);
|
||||
|
||||
$("div.memory_input", context).html(input);
|
||||
|
||||
// Modified input for GB
|
||||
var attr_gb = UserInputs.parse("MEMORY", userInputs.MEMORY);
|
||||
|
||||
if (attr_gb.type == "range"){
|
||||
attr_gb.type = "range-float";
|
||||
attr_gb.min = (attr_gb.min / 1024);
|
||||
attr_gb.max = (attr_gb.max / 1024);
|
||||
attr_gb.initial = (attr_gb.initial / 1024);
|
||||
attr_gb.step = (0.25);
|
||||
} else if (attr_gb.type == "list"){
|
||||
attr_gb.options = attr_gb.options.map(function(e){
|
||||
return e / 1024;
|
||||
});
|
||||
|
||||
attr_gb.initial = attr_gb.initial / 1024;
|
||||
} else {
|
||||
// TODO: error?
|
||||
}
|
||||
|
||||
input = UserInputs.attributeInput(attr_gb);
|
||||
$("div.memory_gb_input", context).html(input);
|
||||
$("div.memory_gb_input input", context).removeAttr("wizard_field");
|
||||
}
|
||||
}
|
||||
|
||||
// Update memory_gb with the value set in memory
|
||||
$("div.memory_input input", context).trigger("input");
|
||||
|
||||
if ($("div.memory_input input", context).val() >= 1024){
|
||||
$("#memory_unit", context).val("GB").change();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,9 +164,11 @@ define(function(require) {
|
||||
* @param {Function} callback will be called as callback( retrieve(context) )
|
||||
*/
|
||||
function _setCallback(context, callback) {
|
||||
context.on("change.fndtn.slider", function(){
|
||||
context.on("input", function(){
|
||||
callback( _retrieve(context) );
|
||||
});
|
||||
|
||||
callback( _retrieve(context) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,7 +192,7 @@ define(function(require) {
|
||||
* - MEMORY
|
||||
* - VCPU
|
||||
*/
|
||||
function _retrieveResize(context) {
|
||||
function _retrieveChanges(context) {
|
||||
var templateJSON = WizardFields.retrieve(context);
|
||||
|
||||
var fields = $('[wizard_field]', context);
|
||||
|
@ -16,70 +16,45 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<div class="">
|
||||
<input type="hidden" wizard_field="MEMORY" id="MEMORY" name="memory" />
|
||||
<label class="" for="MEMORY">
|
||||
{{tr "Memory"}}
|
||||
{{{tip (tr "Amount of RAM required for the VM, in Megabytes.")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="small-10 columns">
|
||||
<div class="memory_input">
|
||||
<input type="number" min="0" step="256" wizard_field="MEMORY" id="MEMORY" disabled/>
|
||||
</div>
|
||||
<div class="large-12 columns">
|
||||
<label class="" for="MEMORY">
|
||||
{{tr "Memory"}}
|
||||
{{{tip (tr "Amount of RAM required for the VM, in Megabytes.")}}}
|
||||
</label>
|
||||
<div class="memory_gb_input">
|
||||
<input type="number" min="0" step="0.25" name="memory_gb" disabled/>
|
||||
</div>
|
||||
<div class="medium-8 columns memory_slider_container">
|
||||
<div id="memory_slider" class="range-slider radius" data-slider data-options="start: 0; end: 409600; step: 12800;">
|
||||
<span class="range-slider-handle"></span>
|
||||
<span class="range-slider-active-segment"></span>
|
||||
<input type="hidden">
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-2 small-6 columns">
|
||||
<input type="text" id="MEMORY_TMP" name="memory_tmp" size="4" />
|
||||
</div>
|
||||
<div class="medium-2 small-6 columns">
|
||||
<select id="memory_unit" name="MEMORY_UNIT">
|
||||
<option value="MB">{{tr "MB"}}</option>
|
||||
<option value="GB">{{tr "GB"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small-2 columns">
|
||||
<select id="memory_unit" name="MEMORY_UNIT">
|
||||
<option value="MB">{{tr "MB"}}</option>
|
||||
<option value="GB" selected>{{tr "GB"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label class="" for="CPU">
|
||||
{{tr "CPU"}}
|
||||
{{{tip (tr "Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.")}}}
|
||||
</label>
|
||||
<div class="cpu_input">
|
||||
<input type="number" step="0.01" min="0" wizard_field="CPU" id="CPU" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<div class="large-12 columns">
|
||||
<label class="" for="CPU">
|
||||
{{tr "CPU"}}
|
||||
{{{tip (tr "Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="large-10 medium-10 columns">
|
||||
<div id="cpu_slider" class="range-slider radius" data-slider data-options="start: 0; end: 1600; step: 50;">
|
||||
<span class="range-slider-handle"></span>
|
||||
<span class="range-slider-active-segment"></span>
|
||||
<input type="hidden">
|
||||
</div>
|
||||
</div>
|
||||
<div class="large-2 medium-2 columns">
|
||||
<input type="text" wizard_field="CPU" id="CPU" name="cpu"/>
|
||||
<div class="small-12 columns">
|
||||
<label class="" for="VCPU">
|
||||
{{tr "VCPU"}}
|
||||
{{{tip (tr "Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")}}}
|
||||
</label>
|
||||
<div class="vcpu_input">
|
||||
<input type="number" step="1" min="0" wizard_field="VCPU" id="VCPU" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<div class="large-12 columns">
|
||||
<label class="" for="VCPU">
|
||||
{{tr "VCPU"}}
|
||||
{{{tip (tr "Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")}}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="large-10 medium-10 columns">
|
||||
<div id="vcpu_slider" class="range-slider radius" data-slider data-options="start: 100; end: 1600; step: 100;">
|
||||
<span class="range-slider-handle"></span>
|
||||
<span class="range-slider-active-segment"></span>
|
||||
<input type="hidden">
|
||||
</div>
|
||||
</div>
|
||||
<div class="large-2 medium-2 columns">
|
||||
<input type="text" wizard_field="VCPU" id="VCPU" name="vcpu"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -81,11 +81,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-7 columns">
|
||||
{{{capacityInputsHTML}}}
|
||||
<div class="capacityCreate large-12 columns">
|
||||
{{{capacityCreateHTML}}}
|
||||
</div>
|
||||
<div class="large-5 columns">
|
||||
{{#isFeatureEnabled "showback"}}
|
||||
</div>
|
||||
{{#isFeatureEnabled "showback"}}
|
||||
<div class="row">
|
||||
<div class="medium-6 columns">
|
||||
<fieldset>
|
||||
<legend>{{tr "Cost"}}</legend>
|
||||
<div class="medium-6 columns">
|
||||
@ -110,9 +112,9 @@
|
||||
<input type="text" wizard_field="DISK_COST" id="DISK_COST" name="name"/>
|
||||
</div>
|
||||
</fieldset>
|
||||
{{/isFeatureEnabled}}
|
||||
</div>
|
||||
</div>
|
||||
{{/isFeatureEnabled}}
|
||||
<div class="row">
|
||||
<div class="large-6 columns">
|
||||
<input type="checkbox" id="sunstone_capacity_select" name="name"/>
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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(
|
||||
'<br>' +
|
||||
@ -152,33 +151,229 @@ define(function(require) {
|
||||
|
||||
div.append('<div class="instantiate_user_inputs"/>');
|
||||
|
||||
$.each(text_attrs, function(index, custom_attr) {
|
||||
var input;
|
||||
|
||||
switch (custom_attr.type) {
|
||||
case "text":
|
||||
input = '<textarea type="text" rows="1" wizard_field="' + custom_attr.name + '" required/>';
|
||||
break;
|
||||
case "text64":
|
||||
input = '<textarea type="text" rows="1" wizard_field_64="true" wizard_field="' + custom_attr.name + '" required/>';
|
||||
break;
|
||||
case "password":
|
||||
input = '<input type="password" wizard_field="' + custom_attr.name + '" required/>';
|
||||
break;
|
||||
}
|
||||
|
||||
$.each(input_attrs, function(index, custom_attr) {
|
||||
$(".instantiate_user_inputs", div).append(
|
||||
'<div class="row">' +
|
||||
'<div class="large-12 large-centered columns">' +
|
||||
'<label>' +
|
||||
TemplateUtils.htmlDecode(custom_attr.description) +
|
||||
input +
|
||||
_attributeInput(custom_attr) +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
'</div>');
|
||||
});
|
||||
}
|
||||
|
||||
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 <input> for the given user input attribute
|
||||
* @param {object} attr structure as returned by parse
|
||||
* @return {string} string containing an html <input> element
|
||||
*/
|
||||
function _attributeInput(attr) {
|
||||
var input;
|
||||
|
||||
switch (attr.type) {
|
||||
case "text":
|
||||
input = '<textarea type="text" rows="1" wizard_field="' + attr.name + '" required/>';
|
||||
break;
|
||||
case "text64":
|
||||
input = '<textarea type="text" rows="1" wizard_field_64="true" wizard_field="' + attr.name + '" required/>';
|
||||
break;
|
||||
case "password":
|
||||
input = '<input type="password" wizard_field="' + attr.name + '" required/>';
|
||||
break;
|
||||
case "number":
|
||||
case "number-float":
|
||||
input = '<input type="number" step="'+attr.step+'" value="'+attr.initial+'" wizard_field="' + attr.name + '" required/>';
|
||||
break;
|
||||
case "range":
|
||||
case "range-float":
|
||||
input =
|
||||
'<div class="row uinput-slider-container">'+
|
||||
'<div class="small-8 columns">'+
|
||||
'<input type="range" class="uinput-slider" style="width:100%"'+
|
||||
'min="'+attr.min+'" max="'+attr.max+'" step="'+attr.step+'" '+
|
||||
'value="'+attr.initial+'"/>'+
|
||||
'</div>'+
|
||||
'<div class="small-4 columns">'+
|
||||
'<input type="number" class="uinput-slider-val" '+
|
||||
'min="'+attr.min+'" max="'+attr.max+'" step="'+attr.step+'" '+
|
||||
'value="'+attr.initial+'" wizard_field="' + attr.name + '" required/>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
|
||||
$(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 = '<select wizard_field="' + attr.name + '" required>';
|
||||
|
||||
$.each(attr.options, function(){
|
||||
var selected = (attr.initial == this);
|
||||
|
||||
input += '<option value="'+this+'" '+
|
||||
(selected? 'selected' : '')+'>'+
|
||||
this+
|
||||
'</option>';
|
||||
});
|
||||
|
||||
input += '</select>';
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an html <input> 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 <input> element
|
||||
*/
|
||||
function _generateInputElement(name, value) {
|
||||
var attrs = _parse(name, value);
|
||||
|
||||
return _attributeInput(attrs);
|
||||
}
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user