Build an Oracle Content Management VBCS Secure Form Component
You can build a local Oracle Content Management component that uses REST APIs exposed by business objects in VBCS to deliver a simple web form that requires user authentication.
VBCS Configuration
-
Allow Cross-Origin Resource Sharing (CORS):
-
Choose Visual Builder , then Settings, and then Allowed Origins.
-
Click New Origin and enter the URL of your Oracle Content Management server for Origin Address.
-
Click the check mark to save.
-
-
Create a new Application
. -
Configure the app to allow access for authenticated users.
-
Open Application Settings.
.
Description of the illustration vbcs_application_settings.png -
On the Settings page, choose User Roles.
-
Add roles to control access to the business object.
The values for Mapping are groups from Oracle Identity Cloud Service. To add groups, see Create Groups for Your Organization.
-
-
Create a business object.
-
Add fields.
Description of the illustration vbcs_add_fields.png -
Enable role-based security
-
Grant roles to Create permission.
Description of the illustration vbcs_grant_roles.png
-
Build an Oracle Content Management Local Component
Assumptions:
-
The VBCS app name is "RequestForm".
-
The business object name is "requestform" and it contains the following custom fields:
-
name (required)
-
email (required)
-
phone
-
subject
-
message
-
Modify assets/render.js
-
Define the component template as follows.
<!-- ko if: initialized --> <div class="form"> <!-- ko if: requestSuccessMsg --> <div class="request-msg green" data-bind="text: requestSuccessMsg"></div> <!-- /ko --> <!-- ko if: requestFailMsg --> <div class="request-msg red" data-bind="text: requestFailMsg"></div> <!-- /ko --> <label class="required-field" for="name">Name</label> <input type="text" id="name" name="name" required placeholder="Your name. . ." data-bind="value: name"/> <label class="required-field" for="email">Email</label> <input type="text" id="email" name="email" required placeholder="Your email. . ." data-bind="value: email"/> <label for="phone"></label>Phone</label> <input type="text" id="phone" name="phone" data-bind="value: phone"/> <label for="subject">Subject</label> <input type="text" id="subject" name="subject" data-bind="value: subject"/> <label for="message"></label>Message</label> <textarea id="message" name="message" rows="6" data-bind="value: message"/> <button data-bind="click: sendRequest, , enable: canSubmit">Send Request</button> </div> <!-- note that the component has completed rendering into the page --> <div class="scs-hidden" data-bind="scsRenderStatus: {'id': id, 'status': 'complete'}"></div> <!-- /ko -->
-
Create the observables for the fields in the Knockout ViewModel.
self.initialized = ko.observable(false); self.requestSuccessMsg = ko.observable(); self.requestFailMsg = ko.observable(); self.VBCSServerUrl = ko.observable(); self.name = ko.observable(); self.email = ko.observable(); self.phone = ko.observable(); self.subject = ko.observable(); self.message = ko.observable(); // Get VBCS server var serverPromise = getVBCSServerURL(); serverPromise.then(function (result) { self.VBCSServerUrl(result.url); self.initialized(true); });
self.canSubmit = ko.computed(function () { return self.name() && self.email(); }, self);
-
Handle required fields.
Enable the Submit button only after all required fields have values.
-
Obtain the VBCS connection
After configure VBCS connection, there are two ways to get the connection:
-
From siteinfo at site runtime
-
From Integrations in Site Builder
var getVBCSServerURL = function () { var serverPromise = new Promise(function (resolve, reject) { // First try to get from siteinfo var siteConnections = SCSRenderAPI.getSiteProperty('siteConnections' var serverUrl = siteConnections && siteConnections.VBCSConnection; if (serverUrl) { console.log('Get VBCS server from siteinfo: ' + serverUrl); resolve({'url': serverUrl}); } else { // Get from integrations var configUrl = '/documents/web?IdcService=AF_GET_APP_INFO_SIMPLE&dAppName=VBCS'; $.ajax({ type: 'GET', dataType: 'json', url: configUrl success: function (data) { var appInfo = data.ResultSets.AFApplicationInfo; var enabled; if (appInfo) { for (var i = 0; i < appInfo.fields.length; i += 1) { if (appInfo.fields[i].name === 'dAppEndPoint') { serverUrl = appInfo.rows[appInfo.currentRow][i]; } else if (appInfo.fields[i].name === 'dIsAppEnabled') { enabled = appInfo.rows[appInfo.currentRow][i]; } if (serverUrl && enabled) { break; } } console.log('Get VBCS server from Idc Service: ' + serverUrl); resolve({'url': serverUrl}); }, error: function (xhr, status, err) { console.log('Request failed: url:' + configUrl + ' status: ' + status + ' error: ' + err); resolve({'url': serverUrl}); } }); } }); return serverPromise; };
-
-
Get an authorization token.
Requirement: Oracle Content Management and VBCS are deployed in the same identity domain.
var getAuthToken = function (args) { // dummy function if callbacks not supplied var dummyCallback = function () {}; // extract the args and create the server URL var serverURL = (args.serverURL || '/').split('/ic/')[0], successCallback = args.successCallback || dummyCallback, errorCallback = args.errorCallback || dummyCallback, tokenURL = serverURL + ‘/ic/builder/resources/security/token’; // For VBCS to get the authtoken: // - make a POST call to /ic/builder/resources/security/token // - include scope=run-time form parameter var getToken = function (tokenURL, successCallback, errorCallback) { $.ajax({ 'type': 'POST', 'url': tokenURL, data: { scope: 'run-time' }, 'xhrFields': { withCredentials: true }, 'success': successCallback }).fail(errorCallback); }; // try to get the token normally getToken(tokenURL, function (resp, status, xhr) { var ct = xhr.getResponseHeader("content-type") || ""; // if the response was an HTML Form. . . if (ct.indexOf('html') > -1) { // parse the form and submit it var parser = new DOMParser(), htmlDoc = parser.parseFromString(resp, "text/html"), forms = htmlDoc.getElementsByTagName("form"); if (forms.length === 1) { var f = forms[0]; $.ajax({ 'type': 'POST', 'url': f.action, 'data': $(f).serialize(), 'xhrFields': { 'withCredentials': true 'success': function () { // retry getting the token now the form was auto-submitted getToken(tokenURL, successCallback, errorCallback); } }).fail(function () { // even if the form submit failed, retry getting the token getToken(tokenURL, successCallback, errorCallback); }); } } else { // already logged in return the token successCallback(resp); } }, errorCallback); };
-
Submit the request.
self.sendRequest = function (data, event) { var vbcsServer = self.VBCSServerUrl(); var authorization, token; var appName = 'securerequestform', mode = 'rt', appVersion = 'live', businessObject = 'Requestform'; var url = vbcsServer + '/' + mode + '/' + appName + '/' + appVersion + '/resources/data/' + businessObject; var payload = { "name": self.name(), "email": self.email(), "phone": self.phone(), "subject": self.subject(), "message": self.message() }; // get token first getAuthToken({ 'serverURL': self.VBCSServerUrl(), 'successCallback': function (data) { token = data; authorization = (token.token_type ? token.token_type : 'Bearer') + ' ' + token.access_token; $.ajax({ type: 'POST', url: url, beforeSend: function (xhr) { xhr.setRequestHeader('Content-type', 'application/vnd.oracle.adf.resourceitem+json'); xhr.setRequestHeader('Authorization', authorization); }, data: JSON.stringify(payload), dataType: 'json', success: function (data) { self.requestFailMsg(''); self.requestSuccessMsg('Request has been submitted successfully’); self.name(''); self.email(''); self.phone(''); self.subject(''); self.message(''); }, error: function (jqXhr, textStatus, errorThrown) { console.log('Error:'); console.log(jqXhr); self.requestSuccessMsg(''); self.requestFailMsg('Failed to submit the request'); } }); }, 'errorCallback': function (xhr, status, err) { if (xhr && xhr.status === 200) { token = xhr.responseText; console.log('Got token'); } else { console.error('getToken: xhr: ' + JSON.stringify(xhr) + ' status: ' + status + ' error: ' + err); self.requestSuccessMsg(''); self.requestFailMsg('Failed to get authorization token'); } } }); };
Modify styles/design.css
Add the following css to design.css
.
.form {
font-family: "Helvetica Neue", "Segoe UI", sans-serif-regular, Helvetica, Arial, sans-serif;
font-size: 14px;
}
.form input[type=text] {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.form textarea {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.form button {
width: 100%;
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
.form button:hover {
background-color: #45a049;
}
.form button:disabled {
background-color: #dddddd;
}
.required-field::after {
content: "*";
color: red;
margin-left:2px
}
.request-msg {
padding: 5px;
font-size: 18px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}
.green {
background-color: #81BA5E;
}
.red {
background-color: red;
}
Use the Form Component on Oracle Content Management
-
Configure the VBCS connection:
-
Choose Administration, then Integrations, and then Applications.
-
Click the Visual Builder Cloud Service Integration check box.
-
Enter the URL, and click Save.
-
-
Import the component:
-
Choose Developer and then Components.
-
Choose Create and then Import Component.
Description of the illustration vbcs_import_component.png
-
-
Add the component to a page
-
Edit a new or existing site.
-
In Site Builder, choose Components and then Custom.
Description of the illustration vbcs_components_custom.png -
Drag the component onto the page.
Note:
This VBCS secure form component works only on secure sites.
-