Introduce form-field directive
The form-field directive abstracts the data, presentation, and operation of a form field into a reusable component. It is intended to improve maintainability and consistency. Form-field is currently being used to create and edit ports, however, the goal is to use it throughout the Ironic-UI. Componentizing form elements will also make it easier to move to other libraries such as SchemaForm should we decide to do that. Change-Id: I4cd84cd0840878b3dc34afe9def8e7f94be46fd0
This commit is contained in:
parent
4fa67ebfcd
commit
681d4744b1
@ -27,95 +27,44 @@
|
||||
'$uibModalInstance',
|
||||
'horizon.dashboard.admin.ironic.validMacAddressPattern',
|
||||
'horizon.dashboard.admin.ironic.validDatapathIdPattern',
|
||||
'horizon.dashboard.admin.ironic.form-field.service',
|
||||
'ctrl'
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Utility class for managing form fields
|
||||
*
|
||||
* @param {object} args - Valid properties are:
|
||||
* value - Initial value of the field
|
||||
* required - Does the field require a value
|
||||
* desc - Field description
|
||||
* pattern - Regular expression pattern used to match
|
||||
* valid input values
|
||||
* disabled - Is the field disabled
|
||||
* info - Additional information about the current state of
|
||||
* the field. It will be displayed in a tooltip associated
|
||||
* with the field.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function Field(args) {
|
||||
this.value = angular.isDefined(args.value) ? args.value : undefined;
|
||||
this.required = angular.isDefined(args.required) ? args.required : false;
|
||||
this.desc = angular.isDefined(args.desc) ? args.desc : undefined;
|
||||
this.pattern = angular.isDefined(args.pattern)
|
||||
? new RegExp(args.pattern) : undefined;
|
||||
this.disabled = angular.isDefined(args.disabled) ? args.disabled : false;
|
||||
this.info = angular.isDefined(args.info) ? args.info : undefined;
|
||||
|
||||
/**
|
||||
* Test whether the field has a non-empty value. Note that an
|
||||
* empty value can be either '' or undefined in the case of a
|
||||
* required field
|
||||
*
|
||||
* @return {boolean} Return true if the field has a value
|
||||
*/
|
||||
this.hasValue = function() {
|
||||
return angular.isDefined(this.value) && this.value !== '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the field has help-text
|
||||
*
|
||||
* @return {boolean} Return true if the field has help text
|
||||
*/
|
||||
this.hasHelpText = function() {
|
||||
return this.desc || this.info;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the help-text associated with this field
|
||||
*
|
||||
* @return {string} Return true if the field has help text
|
||||
*/
|
||||
this.getHelpText = function() {
|
||||
var text = angular.isDefined(this.desc) ? this.desc : '';
|
||||
if (angular.isDefined(this.info)) {
|
||||
if (text !== '') {
|
||||
text += '<br><br>';
|
||||
}
|
||||
text += this.info;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Utility class used to manage local-link-connection
|
||||
* form fields.
|
||||
*
|
||||
* @param {string} formFieldService - Provider service for creating
|
||||
* form fields.
|
||||
* @param {string} validMacAddressPattern - Regular expression
|
||||
* pattern used to test for valid mac addresses.
|
||||
* @param {string} validDatapathIdPattern - Regular expression
|
||||
* pattern used to test for valid datapath ids.
|
||||
* @return {void}
|
||||
*/
|
||||
function LocalLinkConnectionMgr(validMacAddressPattern,
|
||||
function LocalLinkConnectionMgr(formFieldService,
|
||||
validMacAddressPattern,
|
||||
validDatapathIdPattern) {
|
||||
this.port_id = new Field({});
|
||||
var mgr = this;
|
||||
|
||||
this.switch_id = new Field({
|
||||
mgr.port_id = new formFieldService.FormField(
|
||||
{id: 'port_id', title: 'port_id'});
|
||||
|
||||
mgr.switch_id = new formFieldService.FormField(
|
||||
{id: 'switch_id',
|
||||
title: 'switch_id',
|
||||
desc: gettext("MAC address or OpenFlow datapath ID"),
|
||||
pattern: validMacAddressPattern + '|' + validDatapathIdPattern});
|
||||
pattern: new RegExp(validMacAddressPattern + '|' +
|
||||
validDatapathIdPattern)});
|
||||
|
||||
this.switch_info = new Field({});
|
||||
mgr.switch_info = new formFieldService.FormField(
|
||||
{id: 'switch_info', title: 'switch_info'});
|
||||
|
||||
this.fields = {
|
||||
port_id: this.port_id,
|
||||
switch_id: this.switch_id,
|
||||
switch_info: this.switch_info
|
||||
mgr.fields = {
|
||||
port_id: mgr.port_id,
|
||||
switch_id: mgr.switch_id,
|
||||
switch_info: mgr.switch_info
|
||||
};
|
||||
|
||||
/**
|
||||
@ -123,13 +72,17 @@
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
this.update = function() {
|
||||
var required = this.port_id.hasValue() || this.switch_id.hasValue();
|
||||
|
||||
this.port_id.required = required;
|
||||
this.switch_id.required = required;
|
||||
mgr.update = function() {
|
||||
var required = mgr.port_id.hasValue() || mgr.switch_id.hasValue();
|
||||
mgr.port_id.required = required;
|
||||
mgr.switch_id.required = required;
|
||||
};
|
||||
|
||||
// Add form field value change handlers
|
||||
angular.forEach(mgr.fields, function(field) {
|
||||
field.change = mgr.update;
|
||||
});
|
||||
|
||||
/**
|
||||
* Generate an attribute object that conforms to the format
|
||||
* required for port creation using the Ironic client
|
||||
@ -138,33 +91,45 @@
|
||||
* A value of null is returned if the local-link-connection
|
||||
* information is incomplete.
|
||||
*/
|
||||
this.toPortAttr = function() {
|
||||
mgr.toPortAttr = function() {
|
||||
var attr = null;
|
||||
if (this.port_id.hasValue() &&
|
||||
this.switch_id.hasValue()) {
|
||||
if (mgr.port_id.hasValue() &&
|
||||
mgr.switch_id.hasValue()) {
|
||||
attr = {};
|
||||
attr.port_id = this.port_id.value;
|
||||
attr.switch_id = this.switch_id.value;
|
||||
attr.port_id = mgr.port_id.value;
|
||||
attr.switch_id = mgr.switch_id.value;
|
||||
|
||||
if (this.switch_info.hasValue()) {
|
||||
attr.switch_info = this.switch_info.value;
|
||||
if (mgr.switch_info.hasValue()) {
|
||||
attr.switch_info = mgr.switch_info.value;
|
||||
}
|
||||
}
|
||||
return attr;
|
||||
};
|
||||
|
||||
/**
|
||||
* dis/enable the local-link-connection form fields
|
||||
* @description Set values of form fields;
|
||||
*
|
||||
* @param {boolean} disabled - True if the local-link-connection form
|
||||
* fields should be disabled
|
||||
* @param {string} reason - Optional reason for the state change
|
||||
* @param {object} values - Dictionary of values indexed by
|
||||
* property-name
|
||||
* @return {void}
|
||||
*/
|
||||
this.setDisabled = function(disabled, reason) {
|
||||
angular.forEach(this.fields, function(field) {
|
||||
field.disabled = disabled;
|
||||
field.info = reason;
|
||||
mgr.setValues = function(values) {
|
||||
angular.forEach(mgr.fields, function(field, propertyName) {
|
||||
if (angular.isDefined(values[propertyName])) {
|
||||
field.value = values[propertyName];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Disable the local-link-connection form fields.
|
||||
*
|
||||
* @param {string} reason - Optional reason for disabling fields.
|
||||
* @return {void}
|
||||
*/
|
||||
mgr.disable = function(reason) {
|
||||
angular.forEach(mgr.fields, function(item) {
|
||||
item.disable(reason);
|
||||
});
|
||||
};
|
||||
}
|
||||
@ -172,17 +137,35 @@
|
||||
function BasePortController($uibModalInstance,
|
||||
validMacAddressPattern,
|
||||
validDatapathIdPattern,
|
||||
formFieldService,
|
||||
ctrl) {
|
||||
ctrl.port = {
|
||||
address: null,
|
||||
extra: {}
|
||||
};
|
||||
|
||||
ctrl.pxeEnabled = new Field({value: 'True'});
|
||||
ctrl.address = new formFieldService.FormField({
|
||||
id: "macAddress",
|
||||
title: gettext("MAC address"),
|
||||
desc: gettext("MAC address for this port. Required."),
|
||||
pattern: new RegExp(validMacAddressPattern),
|
||||
value: null,
|
||||
required: true,
|
||||
autoFocus: true
|
||||
});
|
||||
|
||||
ctrl.pxeEnabled = new formFieldService.FormField({
|
||||
type: "radio",
|
||||
id: "pxeEnabled",
|
||||
title: gettext("PXE enabled"),
|
||||
desc: gettext(
|
||||
"Indicates whether this port should be used when PXE booting this node"),
|
||||
options: ['True', 'False'],
|
||||
value: 'True'});
|
||||
|
||||
// Object used to manage local-link-connection form fields
|
||||
ctrl.localLinkConnection =
|
||||
new LocalLinkConnectionMgr(validMacAddressPattern,
|
||||
new LocalLinkConnectionMgr(formFieldService,
|
||||
validMacAddressPattern,
|
||||
validDatapathIdPattern);
|
||||
|
||||
/**
|
||||
|
@ -10,50 +10,8 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="CreatePortForm" name="CreatePortForm">
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': CreatePortForm.macAddress.$invalid &&
|
||||
CreatePortForm.macAddress.$dirty}">
|
||||
<label for="macAddress"
|
||||
class="control-label"
|
||||
translate>MAC address</label>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
<div>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
ng-model="ctrl.port.address"
|
||||
id="macAddress"
|
||||
name="macAddress"
|
||||
ng-required="true"
|
||||
ng-pattern="'([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})'"
|
||||
auto-focus
|
||||
placeholder="{$ ::'MAC address for this port. Required.' | translate $}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<label for="pxeEnabled"
|
||||
class="control-label"
|
||||
translate>
|
||||
PXE enabled
|
||||
</label>
|
||||
<span ng-if="ctrl.pxeEnabled.hasHelpText()"
|
||||
class="help-icon"
|
||||
data-container="body"
|
||||
data-html="true"
|
||||
title=""
|
||||
data-toggle="tooltip"
|
||||
data-original-title="{$ ctrl.pxeEnabled.getHelpText() $}">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="btn-group" id="pxeEnabled">
|
||||
<label class="btn btn-default"
|
||||
ng-model="ctrl.pxeEnabled.value"
|
||||
ng-repeat="opt in ['True', 'False']"
|
||||
ng-disabled="ctrl.pxeEnabled.disabled"
|
||||
uib-btn-radio="opt">{$ opt $}</label>
|
||||
</div>
|
||||
</div>
|
||||
<form-field field="ctrl.address" form="CreatePortForm"></form-field>
|
||||
<form-field field="ctrl.pxeEnabled" form="CreatePortForm"></form-field>
|
||||
</form>
|
||||
|
||||
<form id="LocalLinkConnectionForm"
|
||||
@ -61,34 +19,9 @@
|
||||
class="well well-sm">
|
||||
<h4 translate>Local link connection</h4>
|
||||
<div class="form-group"
|
||||
ng-repeat="(propertyName, propertyObj) in
|
||||
ctrl.localLinkConnection.fields"
|
||||
ng-class="{'has-error': LocalLinkConnectionForm.{$ propertyName $}.$invalid &&
|
||||
LocalLinkConnectionForm.{$ propertyName $}.$dirty}">
|
||||
<label class="control-label"
|
||||
for="{$ propertyName $}">{$ propertyName $}
|
||||
<span ng-if="propertyObj.required"
|
||||
class="hz-icon-required fa fa-asterisk"></span>
|
||||
<span ng-if="propertyObj.hasHelpText()"
|
||||
class="help-icon"
|
||||
data-container="body"
|
||||
title=""
|
||||
data-toggle="tooltip"
|
||||
data-html="true"
|
||||
data-original-title="{$ propertyObj.getHelpText() $}">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
</span>
|
||||
</label>
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
id="{$ propertyName $}"
|
||||
name="{$ propertyName $}"
|
||||
ng-model="propertyObj.value"
|
||||
ng-required="propertyObj.required"
|
||||
placeholder="{$ propertyObj.desc $}"
|
||||
ng-pattern="propertyObj.pattern"
|
||||
ng-disabled="propertyObj.disabled"
|
||||
ng-change="ctrl.localLinkConnection.update()"/>
|
||||
ng-repeat="(propertyName, propertyField) in
|
||||
ctrl.localLinkConnection.fields">
|
||||
<form-field field="propertyField" form="LocalLinkConnectionForm"></form-field>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
var port = angular.copy(ctrl.port);
|
||||
port.node_uuid = node.id;
|
||||
|
||||
port.address = ctrl.address.value;
|
||||
|
||||
var attr = ctrl.localLinkConnection.toPortAttr();
|
||||
if (attr) {
|
||||
port.local_link_connection = attr;
|
||||
|
@ -62,26 +62,22 @@
|
||||
node.provision_state === "manageable"));
|
||||
|
||||
// Initialize form fields
|
||||
ctrl.port.address = port.address;
|
||||
ctrl.address.value = port.address;
|
||||
if ((node.provision_state === "active" || node.instance_uuid) &&
|
||||
!node.maintenance) {
|
||||
ctrl.address.disable();
|
||||
}
|
||||
|
||||
ctrl.pxeEnabled.value = port.pxe_enabled ? 'True' : 'False';
|
||||
if (cannotEditConnectivityAttr) {
|
||||
ctrl.pxeEnabled.disabled = true;
|
||||
ctrl.pxeEnabled.info = UNABLE_TO_UPDATE_CONNECTIVITY_ATTR_MSG;
|
||||
ctrl.pxeEnabled.disable(UNABLE_TO_UPDATE_CONNECTIVITY_ATTR_MSG);
|
||||
}
|
||||
|
||||
angular.forEach(
|
||||
['port_id', 'switch_id', 'switch_info'],
|
||||
function(prop) {
|
||||
if (angular.isDefined(port.local_link_connection[prop])) {
|
||||
ctrl.localLinkConnection[prop].value =
|
||||
port.local_link_connection[prop];
|
||||
}
|
||||
});
|
||||
ctrl.localLinkConnection.setValues(
|
||||
port.local_link_connection);
|
||||
|
||||
if (cannotEditConnectivityAttr) {
|
||||
ctrl.localLinkConnection.setDisabled(
|
||||
true,
|
||||
ctrl.localLinkConnection.disable(
|
||||
UNABLE_TO_UPDATE_CONNECTIVITY_ATTR_MSG);
|
||||
}
|
||||
|
||||
@ -97,7 +93,7 @@
|
||||
|
||||
$log.info("Updating port " + JSON.stringify(port));
|
||||
|
||||
patcher.buildPatch(port.address, ctrl.port.address, "/address");
|
||||
patcher.buildPatch(port.address, ctrl.address.value, "/address");
|
||||
patcher.buildPatch(port.pxe_enabled ? 'True' : 'False',
|
||||
ctrl.pxeEnabled.value,
|
||||
"/pxe_enabled");
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2017 Cray Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.admin.ironic')
|
||||
.directive('formField', FormField);
|
||||
|
||||
FormField.$inject = [
|
||||
'$timeout',
|
||||
'$compile',
|
||||
'horizon.dashboard.admin.ironic.basePath'
|
||||
];
|
||||
|
||||
function FormField($timeout, $compile, basePath) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
field: '=',
|
||||
form: '='
|
||||
},
|
||||
templateUrl: basePath + '/form-field.html',
|
||||
link: function(scope, element) {
|
||||
// Process the auto-focus attribute
|
||||
if (scope.field.autoFocus) {
|
||||
// Need to defer processing until the DOM is fully instantiated
|
||||
$timeout(function() {
|
||||
var inputs = element.find('input');
|
||||
if (inputs[0]) {
|
||||
inputs.attr('auto-focus', '');
|
||||
$compile(element.contents())(scope);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
47
ironic_ui/static/dashboard/admin/ironic/form-field.html
Normal file
47
ironic_ui/static/dashboard/admin/ironic/form-field.html
Normal file
@ -0,0 +1,47 @@
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': form[field.id].$invalid &&
|
||||
form[field.id].$dirty}">
|
||||
<label for="{$ field.id $}"
|
||||
class="control-label">{$ field.title $}</label>
|
||||
<span ng-if="field.getHelpText()"
|
||||
class="help-icon"
|
||||
data-container="body"
|
||||
data-html="true"
|
||||
title=""
|
||||
data-toggle="tooltip"
|
||||
data-original-title="{$ field.getHelpText() $}">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
</span>
|
||||
<span ng-if="field.required"
|
||||
class="hz-icon-required fa fa-asterisk"></span>
|
||||
<div ng-switch="field.type">
|
||||
<input ng-switch-when="input"
|
||||
type="text"
|
||||
class="form-control"
|
||||
ng-model="field.value"
|
||||
id="{$ field.id $}"
|
||||
name="{$ field.id $}"
|
||||
ng-required="field.required"
|
||||
ng-disabled="field.disabled"
|
||||
ng-pattern="field.pattern"
|
||||
ng-change="field.change()"
|
||||
placeholder="{$ field.getHelpText() $}"/>
|
||||
<div ng-switch-when="radio"
|
||||
class="btn-group"
|
||||
id="{$ field.id $}">
|
||||
<label class="btn btn-default"
|
||||
ng-model="field.value"
|
||||
ng-repeat="opt in field.options"
|
||||
ng-disabled="field.disabled"
|
||||
uib-btn-radio="opt">{$ opt $}</label>
|
||||
</div>
|
||||
<div ng-switch-when="select">
|
||||
<select id="field.id"
|
||||
class="form-control"
|
||||
ng-disabled="field.disabled"
|
||||
ng-options="{$ field.options $}"
|
||||
ng-model="field.value">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
128
ironic_ui/static/dashboard/admin/ironic/form-field.service.js
Normal file
128
ironic_ui/static/dashboard/admin/ironic/form-field.service.js
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2017 Cray Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.admin.ironic')
|
||||
.factory('horizon.dashboard.admin.ironic.form-field.service',
|
||||
formFieldService);
|
||||
|
||||
function formFieldService() {
|
||||
var service = {
|
||||
FormField: FormField
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Utility class for managing form fields.
|
||||
* Used is association with the form-field directive.
|
||||
*
|
||||
* @param {object} args - Base properties are:
|
||||
* type [string] - Field type. One of: 'input', 'radio', 'select'
|
||||
* id [string] - id/name of the DOM value element
|
||||
* title [string] - Label used to identify the field to the user
|
||||
* options - type == radio [array]:
|
||||
* List of options for a radio field
|
||||
* type == select [string]:
|
||||
* String expression that is passed to ng-options
|
||||
* value - Initial value of the field
|
||||
* required [boolean] - Does the field require a value
|
||||
* desc [string] - Field description
|
||||
* pattern [RegExp] - Regular expression pattern used to match
|
||||
* valid input values
|
||||
* disabled [boolean] - Is the field disabled
|
||||
* info [string] - Additional information about the current state of
|
||||
* the field. It will be displayed in a tooltip
|
||||
* associated with the field.
|
||||
* autoFocus [boolean] - True if the focus should be set to this field. Only
|
||||
* applies to fields of type input.
|
||||
* change [string] - Expression to be evaluated when the value of this
|
||||
* field changes. Only applies to fields of type input.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function FormField(args) {
|
||||
var field = this;
|
||||
field.type = 'input';
|
||||
field.id = undefined;
|
||||
field.title = undefined;
|
||||
field.options = undefined;
|
||||
field.value = undefined;
|
||||
field.required = false;
|
||||
field.desc = undefined;
|
||||
field.pattern = undefined;
|
||||
field.disabled = false;
|
||||
field.info = undefined;
|
||||
field.autoFocus = false;
|
||||
field.change = undefined;
|
||||
|
||||
angular.forEach(args, function(value, arg) {
|
||||
field[arg] = value;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description Test whether the field has a non-empty value.
|
||||
* Note that an empty value can be either '' or undefined in the
|
||||
* case of a required field
|
||||
*
|
||||
* @return {boolean} Return true if the field has a value
|
||||
*/
|
||||
this.hasValue = function() {
|
||||
return angular.isDefined(this.value) && this.value !== '';
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Test whether the field has help-text.
|
||||
*
|
||||
* @return {boolean} Return true if the field has help text.
|
||||
*/
|
||||
this.hasHelpText = function() {
|
||||
return angular.isDefined(this.desc) || angular.isDefined(this.info);
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Get the help-text associated with this field
|
||||
*
|
||||
* @return {string} Return true if the field has help text
|
||||
*/
|
||||
this.getHelpText = function() {
|
||||
var text = angular.isDefined(this.desc) ? this.desc : '';
|
||||
if (angular.isDefined(this.info)) {
|
||||
if (text !== '') {
|
||||
text += '<br><br>';
|
||||
}
|
||||
text += this.info;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Disable this field.
|
||||
*
|
||||
* @param {string} reason - Optional reason for disabling this field.
|
||||
* @return {void}
|
||||
*/
|
||||
this.disable = function(reason) {
|
||||
this.disabled = true;
|
||||
if (angular.isDefined(reason)) {
|
||||
this.info = reason;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
})();
|
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Copyright 2017 Cray Inc
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @description Unit tests for the form-field service
|
||||
*/
|
||||
|
||||
describe(
|
||||
'horizon.dashboard.admin.ironic.form-field.service',
|
||||
|
||||
function() {
|
||||
var formFieldService;
|
||||
|
||||
beforeEach(module('horizon.dashboard.admin.ironic'));
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
formFieldService =
|
||||
$injector.get('horizon.dashboard.admin.ironic.form-field.service');
|
||||
}));
|
||||
|
||||
it('defines the form-field service', function() {
|
||||
expect(formFieldService).toBeDefined();
|
||||
});
|
||||
|
||||
it('FormField - default construction', function() {
|
||||
var field = new formFieldService.FormField({});
|
||||
|
||||
expect(field.type).toEqual('input');
|
||||
expect(field.id).toBeUndefined();
|
||||
expect(field.title).toBeUndefined();
|
||||
expect(field.options).toBeUndefined();
|
||||
expect(field.value).toBeUndefined();
|
||||
expect(field.required).toBe(false);
|
||||
expect(field.desc).toBeUndefined();
|
||||
expect(field.pattern).toBeUndefined();
|
||||
expect(field.disabled).toBe(false);
|
||||
expect(field.info).toBeUndefined();
|
||||
expect(field.autoFocus).toBe(false);
|
||||
expect(field.change).toBeUndefined();
|
||||
expect(formFieldService).toBeDefined();
|
||||
});
|
||||
|
||||
it('FormField - local parameters', function() {
|
||||
var title = "title";
|
||||
var field = new formFieldService.FormField({
|
||||
title: title
|
||||
});
|
||||
|
||||
expect(field.title).toBe(title);
|
||||
});
|
||||
|
||||
it('hasValue', function() {
|
||||
var field = new formFieldService.FormField({});
|
||||
expect(field.hasValue()).toBe(false);
|
||||
|
||||
field.value = '';
|
||||
expect(field.hasValue()).toBe(false);
|
||||
|
||||
field.value = null;
|
||||
expect(field.hasValue()).toBe(true);
|
||||
|
||||
field.value = 'True';
|
||||
expect(field.hasValue()).toBe(true);
|
||||
});
|
||||
|
||||
it('hasHelpText', function() {
|
||||
var field = new formFieldService.FormField({});
|
||||
expect(field.hasHelpText()).toBe(false);
|
||||
expect(field.getHelpText()).toBe('');
|
||||
});
|
||||
|
||||
it('hasHelpText/getHelpText - desc', function() {
|
||||
var field = new formFieldService.FormField({
|
||||
desc: 'desc'
|
||||
});
|
||||
expect(field.hasHelpText()).toBe(true);
|
||||
expect(field.getHelpText()).toBe('desc');
|
||||
});
|
||||
|
||||
it('hasHelpText/getHelpText - info', function() {
|
||||
var field = new formFieldService.FormField({
|
||||
info: 'info'
|
||||
});
|
||||
expect(field.hasHelpText()).toBe(true);
|
||||
expect(field.getHelpText()).toBe('info');
|
||||
});
|
||||
|
||||
it('getHelpText - desc/info', function() {
|
||||
var field = new formFieldService.FormField({
|
||||
desc: 'desc',
|
||||
info: 'info'
|
||||
});
|
||||
expect(field.hasHelpText()).toBe(true);
|
||||
expect(field.getHelpText()).toBe('desc<br><br>info');
|
||||
});
|
||||
|
||||
it('disable', function() {
|
||||
var field = new formFieldService.FormField({});
|
||||
expect(field.disabled).toBe(false);
|
||||
field.disable();
|
||||
expect(field.disabled).toBe(true);
|
||||
});
|
||||
});
|
||||
})();
|
Loading…
Reference in New Issue
Block a user