mirror of
https://github.com/nasa/openmct.git
synced 2025-05-02 08:43:17 +00:00
[Forms] Copy mct-form to mct-toolbar
Copy mct-form template and scripts to use as a basis for mct-toolbar. WTD-684.
This commit is contained in:
parent
244583b2f7
commit
aed6787f2c
@ -7,6 +7,10 @@
|
|||||||
"key": "mctForm",
|
"key": "mctForm",
|
||||||
"implementation": "MCTForm.js"
|
"implementation": "MCTForm.js"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "mctToolbar",
|
||||||
|
"implementation": "MCTToolbar.js"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "mctControl",
|
"key": "mctControl",
|
||||||
"implementation": "MCTControl.js",
|
"implementation": "MCTControl.js",
|
||||||
|
42
platform/forms/res/templates/toolbar.html
Normal file
42
platform/forms/res/templates/toolbar.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<form name="mctForm" novalidate>
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
<span ng-repeat="section in structure.sections">
|
||||||
|
<div class="section-header" ng-if="section.name">
|
||||||
|
{{section.name}}
|
||||||
|
</div>
|
||||||
|
<div class="form-section">
|
||||||
|
<ng-form name="mctFormInner" ng-repeat="row in section.rows">
|
||||||
|
<div class="form-row validates"
|
||||||
|
ng-class="{
|
||||||
|
req: row.required,
|
||||||
|
valid: mctFormInner.$dirty && mctFormInner.$valid,
|
||||||
|
invalid: mctFormInner.$dirty && !mctFormInner.$valid
|
||||||
|
}">
|
||||||
|
|
||||||
|
<div class='label' title="{{row.description}}">
|
||||||
|
{{row.name}}
|
||||||
|
<span ng-if="row.description"
|
||||||
|
class="ui-symbol">
|
||||||
|
i
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class='controls'>
|
||||||
|
<div class="wrapper" ng-if="row.control">
|
||||||
|
<mct-control key="row.control"
|
||||||
|
ng-model="ngModel"
|
||||||
|
ng-required="row.required"
|
||||||
|
ng-pattern="getRegExp(row.pattern)"
|
||||||
|
options="row.options"
|
||||||
|
structure="row"
|
||||||
|
field="row.key">
|
||||||
|
</mct-control>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-form>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
64
platform/forms/src/MCTToolbar.js
Normal file
64
platform/forms/src/MCTToolbar.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining MCTForm. Created by vwoeltje on 11/10/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
["./controllers/FormController"],
|
||||||
|
function (FormController) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mct-toolbar directive allows generation of displayable
|
||||||
|
* forms based on a declarative description of the form's
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* This directive accepts three attributes:
|
||||||
|
*
|
||||||
|
* * `ng-model`: The model for the form; where user input
|
||||||
|
* where be stored.
|
||||||
|
* * `structure`: The declarative structure of the toolbar.
|
||||||
|
* Describes what controls should be shown and where
|
||||||
|
* their values should be read/written in the model.
|
||||||
|
* * `name`: The name under which to expose the form's
|
||||||
|
* dirty/valid state. This is similar to ng-form's use
|
||||||
|
* of name, except this will be made available in the
|
||||||
|
* parent scope.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function MCTForm() {
|
||||||
|
var templatePath = [
|
||||||
|
"platform/forms", //MCTForm.bundle.path,
|
||||||
|
"res", //MCTForm.bundle.resources,
|
||||||
|
"templates/toolbar.html"
|
||||||
|
].join("/");
|
||||||
|
|
||||||
|
return {
|
||||||
|
// Only show at the element level
|
||||||
|
restrict: "E",
|
||||||
|
|
||||||
|
// Load the forms template
|
||||||
|
templateUrl: templatePath,
|
||||||
|
|
||||||
|
// Use FormController to populate/respond to changes in scope
|
||||||
|
controller: FormController,
|
||||||
|
|
||||||
|
// Initial an isolate scope
|
||||||
|
scope: {
|
||||||
|
|
||||||
|
// The model: Where form input will actually go
|
||||||
|
ngModel: "=",
|
||||||
|
|
||||||
|
// Form structure; what sections/rows to show
|
||||||
|
structure: "=",
|
||||||
|
|
||||||
|
// Name under which to publish the form
|
||||||
|
name: "@"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return MCTForm;
|
||||||
|
}
|
||||||
|
);
|
90
platform/forms/test/MCTToolbarSpec.js
Normal file
90
platform/forms/test/MCTToolbarSpec.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../src/MCTToolbar"],
|
||||||
|
function (MCTToolbar) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The mct-toolbar directive", function () {
|
||||||
|
var mockScope,
|
||||||
|
mctToolbar;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
mockScope = jasmine.createSpyObj("$scope", [ "$watch" ]);
|
||||||
|
mockScope.$parent = {};
|
||||||
|
mctToolbar = new MCTToolbar();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is restricted to elements", function () {
|
||||||
|
expect(mctToolbar.restrict).toEqual("E");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("watches for changes in form by name", function () {
|
||||||
|
// mct-form needs to watch for the form by name
|
||||||
|
// in order to convey changes in $valid, $dirty, etc
|
||||||
|
// up to the parent scope.
|
||||||
|
mctToolbar.controller(mockScope);
|
||||||
|
|
||||||
|
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||||
|
"mctForm",
|
||||||
|
jasmine.any(Function)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("conveys form status to parent scope", function () {
|
||||||
|
var someState = { someKey: "some value" };
|
||||||
|
mockScope.name = "someName";
|
||||||
|
|
||||||
|
mctToolbar.controller(mockScope);
|
||||||
|
|
||||||
|
mockScope.$watch.mostRecentCall.args[1](someState);
|
||||||
|
|
||||||
|
expect(mockScope.$parent.someName).toBe(someState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows strings to be converted to RegExps", function () {
|
||||||
|
// This is needed to support ng-pattern in the template
|
||||||
|
mctToolbar.controller(mockScope);
|
||||||
|
|
||||||
|
// Should have added getRegExp to the scope,
|
||||||
|
// to convert strings to regular expressions
|
||||||
|
expect(mockScope.getRegExp("^\\d+$")).toEqual(/^\d+$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns the same regexp instance for the same string", function () {
|
||||||
|
// Don't want new instances each digest cycle, for performance
|
||||||
|
var strRegExp = "^[a-z]\\d+$",
|
||||||
|
regExp;
|
||||||
|
|
||||||
|
// Add getRegExp to scope
|
||||||
|
mctToolbar.controller(mockScope);
|
||||||
|
regExp = mockScope.getRegExp(strRegExp);
|
||||||
|
|
||||||
|
// Same object instance each time...
|
||||||
|
expect(mockScope.getRegExp(strRegExp)).toBe(regExp);
|
||||||
|
expect(mockScope.getRegExp(strRegExp)).toBe(regExp);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes RegExp objects through untouched", function () {
|
||||||
|
// Permit using forms to simply provide their own RegExp object
|
||||||
|
var regExp = /^\d+[a-d]$/;
|
||||||
|
|
||||||
|
// Add getRegExp to scope
|
||||||
|
mctToolbar.controller(mockScope);
|
||||||
|
|
||||||
|
// Should have added getRegExp to the scope,
|
||||||
|
// to convert strings to regular expressions
|
||||||
|
expect(mockScope.getRegExp(regExp)).toBe(regExp);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes a non-whitespace regexp when no pattern is defined", function () {
|
||||||
|
// If no pattern is supplied, ng-pattern should match anything
|
||||||
|
mctToolbar.controller(mockScope);
|
||||||
|
expect(mockScope.getRegExp()).toEqual(/\S/);
|
||||||
|
expect(mockScope.getRegExp(undefined)).toEqual(/\S/);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
Loading…
x
Reference in New Issue
Block a user