In this document, we will define a license creation editor that allows the provider to create a license offering for customers.
In this document:
When creating a license APS resource, the provider should select one or more scopes to be assigned to that license.
All possible scopes are specified in the ui/newlicense.json
file created earlier.
The license-new
view will be called from the licenses
view when a user clicks the New button.
The view controls the license creation process.
A JavaScript code in ui/license-new.html
must perform the following operations:
It represents the scopes stored in the ui/newlicense.json
file as a full list of all scopes available
in this APS application.
When a user clicks Cancel, it directs the user back to the licenses
view. On Submit click, it
saves the new license and then proceeds to the licenses
view.
When creating the ui/license-new.html
file from the project template (as in our case),
keep in mind the Typical Structure of View File and follow these steps.
Ensure the require
list contains all JavaScript modules that the main callback function will need:
require([
"dijit/registry",
"dojo/when",
"dojox/mvc/getPlainValue",
"dojox/mvc/at",
"dojox/mvc/getStateful",
"aps/ResourceStore",
"aps/load",
"aps/CheckBox",
"aps/json!./newlicense.json",
"./displayError.js",
"aps/ready!"
], function (
registry,
when,
getPlainValue,
at,
getStateful,
Store,
load,
CheckBox,
newLicense,
displayError
) {
// .. To be continued in the next steps ..
});
In the main callback function, declare the license store that will interact with the APS controller and the license model that will interact with the widgets:
// License store to interact with licenses stored in the APS DB:
var licenseStore = new Store({
apsType: "http://aps-standard.org/samples/github/license/1.0",
target: "/aps/2/resources/"
});
// License model to interact with UI widgets when configuring a new license:
var licenseModel = new getStateful(newLicense);
Key:
We will need the license store to save the new license after the user submits the editing.
The license model is created with the properties pre-filled from the ui/newlicense
file.
Split the view into two widget groups: one contains the license name and description, and the other dynamically builds a list of scopes to be chosen for the new license:
var widgets = ["aps/PageContainer", {id: "page"}, [
["aps/Panel", [
["aps/FieldSet", {id: "licenseNew_general", title: true}, [
["aps/TextBox", {
id: "licenseNew_licenseName",
label: "License Name",
value: at(licenseModel, "name"),
required: true
}],
["aps/TextBox", {
id: "licenseNew_description",
label: "Description",
value: at(licenseModel, "description")
}]
]]
]],
["aps/Panel", [
["aps/FieldSet", {id: "licenseNew_props", title: true}]
]]
]];
Key:
The general properties are displayed by text boxes synced with the license model. The at()
function
implements the synchronization with the model.
The second widget group will be filled out dynamically in the next step after the whole widget structure is loaded.
Use the asynchronous load->then->otherwise
chain to load the widgets and then fill out the second widget group
dynamically with checkboxes, each corresponding to a scope specified in the license model.
load(widgets).then(function() {
/* Add checkboxes, one per each scope defined in the newLicense default model */
var scopes = licenseModel.get("scopes");
var fieldSet = registry.byId("licenseNew_props");
scopes.forEach(function(scope) {
fieldSet.addChild( new CheckBox({
checked: true,
value: scope,
label: scope
}));
});
/* Create here handlers for the navigation buttons .. in the next steps*/
// ... handlers ...
}).otherwise(displayError);
The navigation buttons “Cancel” and “Submit” for the view are declared in APP-meta.xml
.
Continue the definition of the load->then->otherwise
chain with the definition of the handlers
of those navigation buttons:
aps.app.onCancel = function() {
aps.apsc.gotoView("licenses");
});
aps.app.onSubmit = function() {
var page = registry.byId("page");
if (!page.validate()) {
aps.apsc.cancelProcessing();
return;
}
var boxes = registry.byId("licenseNew_props").getChildren();
var scopes = [];
boxes.forEach(function(box) {
if (box.checked) scopes.push(box.value);
});
licenseModel.set("scopes", scopes);
var payload = getPlainValue(licenseModel);
when(licenseStore.put(payload),
function() {
aps.apsc.gotoView("licenses");
},
displayError
);
};
Key:
The onCancel
handler simply redirects the user back to the license landing page.
The onSubmit
handler first validates the entered values, then collects the selected checkboxes (scopes)
in the license model, and finally sends a request to save the license model as a new license APS resource.
At the end, the user is returned to the license landing page.
Following the instructions in this document you have created a simple resource creation editor, that the provider can use to create a list of licenses with every license presenting a list of scopes.
The view source HTML file you have created should be similar
to the sample license-new.html
file:
<!DOCTYPE html>
<html>
<head>
<script src="/aps/2/ui/runtime/client/aps/aps.js"></script>
<script>
require([
"dijit/registry",
"dojo/when",
"dojox/mvc/getPlainValue",
"dojox/mvc/at",
"dojox/mvc/getStateful",
"aps/ResourceStore",
"aps/load",
"aps/CheckBox",
"aps/json!./newlicense.json",
"./displayError.js",
"aps/ready!"
], function (
registry,
when,
getPlainValue,
at,
GetStateful,
Store,
load,
CheckBox,
newLicense,
displayError
) {
/* Define data source */
// License store to interact with licenses stored in the APS DB:
var licenseStore = new Store({
apsType: "http://aps-standard.org/samples/github/license/1.0",
target: "/aps/2/resources/"
});
// License model to interact with UI widgets to configure a new license:
var licenseModel = new GetStateful(newLicense);
/* Define and load the widgets */
var widgets = ["aps/PageContainer", {id: "page"}, [
["aps/Panel", [
["aps/FieldSet", {id: "licenseNew_general", title: true}, [
["aps/TextBox", {
id: "licenseNew_licenseName",
label: "License Name",
value: at(licenseModel, "name"),
required: true
}],
["aps/TextBox", {
id: "licenseNew_description",
label: "Description",
value: at(licenseModel, "description")
}]
]]
]],
["aps/Panel", [
["aps/FieldSet", {id: "licenseNew_props", title: true}]
]]
]];
load(widgets).then(function() {
/* Add checkboxes, one per each scope defined in the newLicense default model */
var scopes = licenseModel.get("scopes");
var fieldSet = registry.byId("licenseNew_props");
scopes.forEach(function(scope) {
fieldSet.addChild(new CheckBox({
checked: true,
value: scope,
label: scope
}));
});
aps.app.onCancel = function() {
aps.apsc.gotoView("licenses");
};
aps.app.onSubmit = function() {
var page = registry.byId("page");
if (!page.validate()) {
aps.apsc.cancelProcessing();
return;
}
var boxes = registry.byId("licenseNew_props").getChildren();
var scopes = [];
boxes.forEach(function(box) {
if (box.checked) scopes.push(box.value);
});
licenseModel.set("scopes", scopes);
var payload = getPlainValue(licenseModel);
when(licenseStore.put(payload),
function() {
aps.apsc.gotoView("licenses");
},
displayError
);
};
}).otherwise(displayError);
});
</script>
</head>
<body>
</body>
</html>