X

The Visual Builder Cloud Service Blog

Recent Posts

Oracle Visual Builder Cloud Service

Consuming REST APIs in VB - application/x-www-form-urlencoded

Service Connections in Visual Builder support common payloads for REST APIs like application/json (default), application/x-www-form-urlencoded, multipart/form-data etc.  This series of blog posts will highlight how to integrate APIs with these payloads with Visual Builder. In this blog post, we will focus on the integration of a REST API that accepts application/x-www-form-urlencoded format.  This media type is less popular these days and is mostly replaced by multipart/form-data, which will be covered in a later post.  The form-urlencoded format can be visualized as a list of percent-encoded name-value pairs separated by the ampersand (&) character (much like the query string format).   For the purpose of demonstration of the various payloads I will be using the freely available REST client testing server https://postman-echo.com There are three broad tasks to create a full application that calls a REST API with application/x-www-form-urlencoded format  Defining the Service Connection  Creating a simple form with two input text elements bound to a page variable Passing the page variable to the Service Connection on click of a Button Each of these tasks are described below (If some of these are new to you, check out the Visual Builder learning path, especially the one on Service Connections) Define the Service Connection Create the Service Connection using “Define by Endpoint” flow.   Method = POST URL = https://postman-echo.com/post Action Hint = Create         Next, in the Authentication tab, give the following Enable Authentication/Proxy - checked Authentication = “None” (In a real world case, you will need to select appropriate authentication as per your service needs)     In the Request tab, change the default Media Type (application/json)  to application/x-www-form-urlencoded using the pencil icon .  As soon as you change this, the Body part will be greyed out (but we will still be able to test the Service)   Navigate to the Test tab.  Now, we will generate a sample Response by testing the Service  Request Body – lets have a string of simple key-value pairs as below(if you are using your own data, make sure these are Percent Encoded if they contain non-alphanumeric characters) firstValue=star&secondValue=wars  Click on the Send button.  You should be able to see the example response as below:       Click on the “Copy to Response Body” to store this as an example response, and finally click on “Create” to save the Service Connection Created This completes the definition of a Service Connection which is ready to be used in a Web or Mobile application. Create the form page Let us now create a simple web application which will accept the form parameters and pass them to the Service.  Create a web application with a logical name (mine is called “FormUrlEncodedTest”) From the main-start page, create a new Variable called “inputData” of type Object.  Add two fields to it “firstValue” and “secondValue”     On the main-start page, add two “Input text” components from the Component palette.  Change their labels to “First Value” and “Second Value” respectively. Click on the first input text, and in the Property inspector, click on Data sub tab.  Click on the "fx" icon to bind the and bind the input text data to "inputData.firstValue"   Repeat for the second input text field and bind it to secondValue attribute Finally add a button that will call the REST API and pass the values of both input elements.  Select the button and go to the Events tab and add a new Event.  Use the “ojAction” Quick Start to automatically create an Action chain for the event as well.     Add the Action Chain Next we add the Action chain elements.  In the Action chain, first we will prepare the body for the /post REST API using a custom JavaScript function and then call the /post  REST API and fire an appropriate notification if success or failure.     Create a page level function that takes care of Percent Encoding and forming the body of the request from the variable.  A sample function is as follows:     PageModule.prototype.prepareRestBody = function(details) {     var formBody = [];     for (var property in details) {       var encodedKey = encodeURIComponent(property);       var encodedValue = encodeURIComponent(details[property]);       formBody.push(encodedKey + "=" + encodedValue);     }     formBody = formBody.join("&");     return formBody;   }; In the Action chain, use the action “Call Module function” to use prepareRestBody, and we pass the variable we created ("inputData") to the input parameter "details"       Next, add the “Call Rest Endpoint action” to the action Chain and select the appropriate endpoint correspond to your API.  In our case it is the /post endpoint   We also need to map the body of the REST Action call with whatever was returned from the prepareRestbody module function Finally we add “Fire notification” actions to both the success and the failure nodes of the “Call Rest endpoint”.  For the success notification, we have a Notification type of “info” and we have also added the values retrieved from the response of the REST API to Summary as below: {{ $chain.results.callRestEndpoint1.body.form.firstValue + chain.results.callRestEndpoint1.body.form.secondValue}}         This completes our web application.  On adding input values and clicking on the button, you should now see a successful response like this:      

Service Connections in Visual Builder support common payloads for REST APIs like application/json (default), application/x-www-form-urlencoded, multipart/form-data etc.  This series of blog...

Importing and Updating Apps Between Visual Builder Instances

Visual Builder has built in lifecycle for applications that supports hosting the development, test, and production instances of an app on a single server. But many companies prefer to separate their dev instances from their production instances - this allows them to separate the users accessing each instance, separate the backends that they are accessing, and guarantee that there is no development load on the production server. If that is the approach taken, you'll need to promote the app from the development VB instance to the production VB instance, and also take care of subsequent changes to the app. The solution for this need is the use of a shared code repository - which is available for you for free in the Oracle Developer Cloud. If you haven't yet watched the video that explains how to setup Visual Builder to work with the Git repository in Developer Cloud - you should watch that video first. This is an essential thing to do if multiple developers are working on your project. It is also the thing that will enable you to promote code between environments. Once your app code is inside the Git repo - you can leverage Visual Builder's "Import from Git" option in any other instance of VB - this will create your initial version of the app on your new instance. When someone changes the code in the repository (for example by checking in the latest changes from the development instance), you can pick up those changes in your production VB instance by connecting your app back to that git repository (and the specific branch you want to use) and doing a Reset Head operation - this will overwrite your local app definition on the production instance with the latest updates from your dev instance.  Note that if you already have a published application which is live, you would first need to create a new version of this app, so you could make changes to the code. Then you reset the code from head, and then you re-stage and re-publish the app. Your changes will be reflected in the running app as soon as you do this. And don't worry - as part of the re-publish step we will ask you what to do with the existing data in your business objects - just choose the option to "Keep existing data in live" and your data will stay as is while the rest of the app gets updated. In the video below you can see the full process: Note that in the video the process is done manually, if you are adopting DevOps automation approach you should look into the ability to use the build jobs in Developer Cloud to automate the process of staging and publishing apps each time code changes in a specific branch. This blog entry can get you started on your way to DevOps Visual Builder.  

Visual Builder has built in lifecycle for applications that supports hosting the development, test, and production instances of an app on a single server. But many companies prefer to separate their...

Charts in Oracle Visual Builder - Data Structure and Performance Tips

One of the key ways to make your application drive better user results is to use charts. Chart makes it easier for users to turn raw data into useful information. As they say "A picture is worth a thousands words". Oracle Visual Builder's quick starts makes it very simple to create basic charts leveraging the data visualization components of Oracle JET. But if you require more complex charts and if you want to improve the performance of your application, you might want to go beyond the quick-start. This blog covers two topics: Reducing network traffic - the "add data" quick-start creates separate variables for each chart, which results in separate DB queries and separate sets of data. If you are sharing population between charts - you can extend one of the queries and eliminate another. In addition, if you need to further manipulate the returned data to show a third type of chart - switch the ADP instead of SDP. This way a single fetch can be used by multiple charts even if the data structure is different. Creating the needed data structure - different charts require different structures of data, and your REST calls don't always return the needed structure. You can use simple JavaScript methods to massage the data a REST service provides into the format your chart requires. Here is what you'll learn in the video (time stamps will help you skip parts you already know): 0:00-1:15 Creating charts with the "add data" quick start 1:15-3:15 Merging two charts to work with a single REST call, and using calculation on multiple columns in a chart 3:15-4:15 Explaining the data structure for a chart with more than one series 4:15- 7:15 Switching from ServiceDataProvider (SDP) to an ArrayDataProvider (ADP) - so the data will be available for further manipulation 7:15-8:45 Defining a new type and a new ADP with the needed structure for the new type of chart 8:45-11:00 Use a JavaScript method to transform the data structure.  11:00-End Bind a dual series chart to an ADP  Resources  An example of the data structure for the second chart is in the Oracle JET cookbook. Here is the JavaScript used to create this structure from the data structure returned from the BO REST service. It creates two series entries for each record returned from the BO - one for salary and the other for the computed bonus. PageModule.prototype.transform = function(result) { var newID = 1; if (result && result.length > 0) { var items = []; for (var i = 0; i < result.length; i++) { items.push({ id: newID++, group: result[i].name, series: "Salary", value: result[i].salary }); items.push({ id: newID++, group: result[i].name, series: "Bonus", value: result[i].bonus * result[i].salary }); } return items; } };

One of the key ways to make your application drive better user results is to use charts. Chart makes it easier for users to turn raw data into useful information. As they say "A picture is worth...

Oracle Visual Builder Cloud Service

Complex Queries in Visual Builder

Often, you have to filter a data set based on multiple search criteria like in the above image. In this case, you want to only create filterCriterion items for fields that have a value. Any field with null/undefined/empty string you want to skip. To accomplish this, create an object to hold your filter criteria with each of the fields named exactly as the parameters you need to pass in. In our case it's SrNumber and StatusCdMeaning. For Business Objects and Fusion Apps REST endpoints, you can define this filterCriteria variable using a Type from Endpoint to make sure the field names match exactly. Then add a page function that looks like this: PageModule.prototype.getQueryCriteria = function(filterObject) { var filterProps = Object.keys(filterObject); var criteria = []; filterProps.forEach(key => { var value = filterObject[key]; if (value !== undefined && value !== null && value !== '') { criteria.push({ attribute: key, op: "$co", value: value }); } }); return { criteria: criteria }; }; Finally, hook up the filter button's ojAction chain to contain an Assign Variables action. In the Assign Variables, map the SDP's filterCriterion as follows. Make sure it's set to be an expression and not static text. $page.functions.getQueryCriteria($page.variables.filterCriteria) Note that we don't specify a top-level operand on the filterCriteria so it will automatically use $and for SrNumber and SrStatus.

Often, you have to filter a data set based on multiple search criteria like in the above image. In this case, you want to only create filterCriterion items for fields that have a value. Any field with...

Storing Image Files in Your Database from a Visual Builder App

The business objects in Oracle Visual Builder let you store textual data, but what if you need to store some binary data such as images? You'll need to find a separate location to store those. Oracle has various solutions for this including the storage cloud and the content and experience cloud, in this blog we'll show you how to do this using Oracle ATP Database (or any other Oracle DB). The concept is simple, you create a table with a Blob type column in your DB, in that column you are going to store the images. You now need to expose that table through a REST service - and call that REST service from your Visual Builder app to load the images. In your Visual Builder app you can have a business object where one of the fields will contain the URL that is used to fetch the image back. In the video demo below I show you how to build this solution. The Database Part - ATP+ORDS I'm using an ORDS based module that exposes the get and post methods on the table. Blain Carter pointed me to this tutorial that covers creating the table and the ORDS interfaces. A couple of tips as you work through the tutorial: You need to first complete the method for getting a specific image by ID, before you can test the POST method (which depends on that GET method for the return value). The PL/SQL code I used is: declare image_id integer; begin insert into gallery (title,content_type,image) values (:title,:content_type,:body) returning id into image_id; commit; :status := 201; :location := image_id; end; And the parameters are: Note that I also needed to whitelist my VB instance on the ORDS side - so I'll be allowed to access that end point. Now that you have the backend services, it's a simple matter of building the VB based UI. The Visual Builder Part In VB you'll define service connections to work with the ORDS endpoints. Note that you'll need to switch the MediaType of the endpoints to accept image/png instead of the regular application/json. Then we use the take picture action to allow us to pick an image either from the hard-drive when running as a web app, or from the device when running as a mobile app. We then pass the file to the REST endpoint which creates a record in the DB storing the image. The REST service returns a URL address for the image location as the text value we store in the VB business object. The value is returned as part of the header - so we use this expression to get it: $chain.results.callRestEndpoint1.headers.get('location') Check out the video below to see the development process in VB: 0:00-1:30 Review the Database and ORDS structure 1:30-3:30 Define REST service connections in Visual Builder 3:30-5:30 Create Business Object and basic UI for mobile app 5:30-7:40 Creating an action chain to take a picture and load to DB 7:30-8:45 Test run in emulator 8:45-end PWA enable the app and test on device

The business objects in Oracle Visual Builder let you store textual data, but what if you need to store some binary data such as images? You'll need to find a separate location to store those. Oracle...

Adding Offline Capabilities to an Oracle Visual Builder App

Visual Builder allows you to create applications that can continue to function even when your device is disconnected from the network. To do that Visual Builder leverages the Oracle JET offline persistence toolkit. This toolkit enables your application to cache data on the client and serves it back from the cache when you are issuing the same REST call but your device doesn't have access to the server. It also allows you to "execute" operations such as adding records while offline - storing those requests on the client again - and then automate replaying them back when you are connected. In the demo video below I show how to add some of these capabilities to your application. It's important to note that adding offline capabilities requires knowledge in JavaScript coding and an understanding of the offline toolkit. This is not a simple drag and drop operation - so approach carefully. Leverage the extensive logging that the offline persistence can do and monitor it's messages in the browser's dev tools console to see what is happening when. In the video you'll also see how to clear the cache on the client which is sometimes needed to see the real functionality. The Visual Builder developer guide has a section that explains the concepts of offline persistence, and provides a basic starting point code sample. In the video below, I start from that code sample, then I modify it to change the cache strategy and implement support for POST operations and synch data changes on demand. Here is a breakdown of things you'll see in the video (allowing you to skip to the section you need): 0:00-1:30 - Exposing Oracle Database Table (Oracle ATP) with REST Services using ORDS and SQLDeveloper 1:30-4:45 - Building a simple Read/Create Visual Builder App Accessing above ORDS services 4:45-8:00 - Adding caching based on the book's sample 8:00-10:30 - Switching to use cache data only when offline 10:30- End - Adding handling of POST(Create) operations As you can see the interaction with the offline persistence layer is managed in the application's JavaScript area. Below is the code used in my app, with the parts that I change from the doc sample explained below. define([ 'vbsw/helpers/serviceWorkerHelpers', /** * Add the following entries to include the toolkit classes that you'll use. More information about these * classes can be found in the toolkit's API doc. See the link to the API doc in the paragraph before * this sample file. * */ 'persist/persistenceManager', 'persist/defaultResponseProxy', 'persist/persistenceUtils', 'persist/fetchStrategies', /** * Add the following entry to enable console logging while you develop your app with the toolkit. */ 'persist/impl/logger' ], function(ServiceWorkerHelpers, PersistenceManager, DefaultResponseProxy, PersistenceUtils, FetchStrategies, Logger) { 'use strict'; function AppModule() {} function OfflineHandler() { /** * Enable console logging of the toolkit for development testing */ Logger.option('level', Logger.LEVEL_LOG); Logger.option('writer', console); var options = { /** * The following code snippets implements the toolkit's CacheFirstStrategy. This strategy * checks the application's cache for the requested data before it makes a request to cache * data. The code snippet also disables the background fetch of data. */ requestHandlerOverride: { handlePost: handlePost }, fetchStrategy: FetchStrategies.getCacheIfOfflineStrategy({ backgroundFetch: 'disabled' }) }; this._responseProxy = DefaultResponseProxy.getResponseProxy(options); } OfflineHandler.prototype.handleRequest = function(request, scope) { /** * (Optional). Write output from the OfflineHandler to your browser's console. Useful to help * you understand the code that follows. */ console.log('OfflineHandler.handleRequest() url = ' + request.url + ' cache = ' + request.cache + ' mode = ' + request.mode); /** * Cache requests where the URL matches the scope for which you want data cached. */ if (request.url.match( 'https://yourserver.oraclecloudapps.com/ords/shay' )) { return this._responseProxy.processRequest(request); } return PersistenceManager.browserFetch(request); }; OfflineHandler.prototype.beforeSyncRequestListener = function(event) { return Promise.resolve(); }; OfflineHandler.prototype.afterSyncRequestListener = function(event) { return Promise.resolve(); }; AppModule.prototype.createOfflineHandler = function() { /** Create the OfflineHandler that makes the toolkit cache data URLs */ return Promise.resolve(new OfflineHandler()); }; AppModule.prototype.isOnline = function() { return ServiceWorkerHelpers.isOnline(); }; AppModule.prototype.forceOffline = function(flag) { return ServiceWorkerHelpers.forceOffline(flag).then(function() { /** if online, perform a data sync */ if (!flag) { return ServiceWorkerHelpers.syncOfflineData(); } return Promise.resolve(); }).catch(function(error) { console.error(error); }); }; AppModule.prototype.dataSynch = function() { return ServiceWorkerHelpers.syncOfflineData(); }; // custom implementation to handle the POST request var handlePost = function(request) { if (ServiceWorkerHelpers.isOnline()) {} return PersistenceUtils.requestToJSON(request).then(function( requestData) { console.log('Inside PersistenceUtils'); console.log(requestData); requestData.status = 202; requestData.statusText = 'OK'; requestData.headers['content-type'] = 'application/json'; requestData.headers['x-oracle-jscpt-cache-expiration-date'] = ''; // if the request contains an ETag then we have to generate a new one var ifMatch = requestData.headers['if-match']; var ifNoneMatch = requestData.headers['if-none-match']; if (ifMatch || ifNoneMatch) { var randomInt = Math.floor(Math.random() * 1000000); requestData.headers['etag'] = (Date.now() + randomInt).toString(); requestData.headers['x-oracle-jscpt-etag-generated'] = requestData.headers['etag']; delete requestData.headers['if-match']; delete requestData.headers['if-none-match']; } return PersistenceUtils.responseFromJSON(requestData); }); }; return AppModule; });   To highlight the major changes in the code done in the video: Line 40 - changed the fetch strategy to fetch data from the cache only when offline - doc  Line 37-39 - define a new method that will be used to handle POST operations Lines 98-125 - the custom method that handles POST operations (line 11,19 contain the extra needed library reference) Lines 93-95 - AppModule function to force synchronization of offline changes Keep in mind that offline caching should be used with an understanding of the risks involved. For example, your cached data can get stale and not match the real situation in the server.So while caching can be a nice performance boost, you should probably use it for data that is not frequently changing. Also since data is cached on the client, other people could access it if they get access to the client. Don't cache sensitive data that you don't want falling into the wrong hands if you loose your device.  

Visual Builder allows you to create applications that can continue to function even when your device is disconnected from the network. To do that Visual Builder leverages the Oracle JET offline persist...

Visual Builder - Prompting for User Input in an Action Chain

From time to time you may find it necessary to prompt for user input during the course of a Visual Builder Action Chain execution.  For example, as shown here, you might want to confirm that the user really wants to navigate somewhere, or check to see if they want to really delete that row, that kind of thing. Of course you can use the Oracle JET dialog component to provide the user interface for this, but how do you incorporate that into the flow of an Action Chain?  Well there are two approaches: You break the logical action chain into multiple chains, the first opens the required dialog using the Call Component Method Action, and then the various buttons on the dialog kick off separate action chains of their own. You effectively do everything from a single action chain and simply wait for the user input before carrying out the logic.  The first approach works well, but because the before-user-input and post-user-input actions are split into separate chains it can be hard to manage the code, so let's look at the second approach.  As an example I've implemented a vbBeforeExit Action Chain to always prompt the user before they navigate, so no matter how navigation is triggered this will always pop up.  You can see here that the chain is very simple, we call a page module function (checkWithUser) which will display the dialog followed by an If action which branches on the user decision to either continue with the navigation operation or will cancel it.  So the question is - how does this wait for the user to make the selection? The answer is using a Promise. If a module function returns a Promise then action chain processing will wait until that Promise is resolved before continuing to the next step and we'll be taking advantage of that here.   So let's look at the implementation of the Page Module function being called:   PageModule.prototype.checkWithUser = function() {     var self = this;     var checkPromise = new Promise(function(resolve) {       // save away the reference to the promise resolvling function       self.userInputComplete = resolve;       // Show the dialog      document.getElementById('confirmDialog').open();     });     return checkPromise;   }; In this function a couple of things are happening. First of all you can see that a Promise is created and the reference to it's resolve function is stashed into the Page Module (via self.userInputComplete), we'll call this from another function later.  Next the dialog is opened.  I've manually created the dialog in the page source view (remembering to add the import for ojs/ojdialog to the page JSON (See: Adding New Oracle JET UI Component to Visual Builder Cloud Service). Here's the code for this simple example: <div>   <oj-dialog style="display:none" id="confirmDialog" dialog-title="Navigate to the Next Page" cancel-behavior="none">     <div slot="body">       <p>Are you sure you want to navigate?</p>     </div>     <div slot="footer">       <oj-button id="confirmYes" on-oj-action="[[$listeners.confirmYesOjAction]]">Yes</oj-button>       <oj-button id="confirmNo" on-oj-action="[[$listeners.confirmNoOjAction]]">No</oj-button>     </div>   </oj-dialog> </div> And each of the on-oj-action listeners just calls the same action chain with different parameters: "confirmYesOjAction": {     "chains": [         {             "chainId": "dialogResponseChain",             "parameters": {                 "detail": "{{ $event.detail }}",                 "response":"YES"             }         }     ] }, "confirmNoOjAction": {     "chains": [         {             "chainId": "dialogResponseChain",             "parameters": {                 "detail": "{{ $event.detail }}",                 "response":"NO"             }         }     ] }  The dialogResponseChain action chain that they both call is very simple, all it does is call another Page Module method: And here's the implementation of that function: PageModule.prototype.userResponse = function(response) { var self = this; // close the dialog var dialog = document.getElementById('confirmDialog'); if (dialog.isOpen()) { dialog.close(); } if (self.userInputComplete) { self.userInputComplete(response); delete self.userInputComplete; } }; So this function first of all closes the dialog and then calls the saved promise resolver function (self.userInputComplete) passing it the requested response which, in this case, will either be the string YES or NO depending on which button the user pressed. This response will then be taken as the response of the original Module Method call that we made in the first chain and as soon as the resolve function is called that chain will free up and this response used by the if statement that follows as the next action. And that's it.  Of course this is a very simple example.  You could pop up a dialog to make simple yes/no decisions like I have here, or you could even gather user input, you can pass that back to the main action chain using the resolve function in the same way that we passed the Yes/No value. 

From time to time you may find it necessary to prompt for user input during the course of a Visual Builder Action Chain execution.  For example, as shown here, you might want to confirm that the user...

Oracle Visual Builder Cloud Service

Adventures in Mutation - Adding Rows to a Table or ListView in Oracle Visual Builder

Recently there have been a lots of questions from the Visual Builder community relating to how to display both a collection based UI such as a Table or ListView  and a data entry form for that collection on the same screen.  Something like the simple To-Do list application shown here: How such a screen can be implemented, depends on the Data Provider being used by the table or ListView. If an ArrayDataProvider is used then the add action chain would usually have three steps: Call the rest endpoint (usually a POST) to add the new row at the back end  Call a page function that takes the new todo task and the array backing the ArrayDataProvider, pushes the new task to the array and returns the updated array as the result of the function Call an assign variable acton to copy this result back on top of the backing array.  This will have the side effect of updating the Array Data Provider and in turn the table will be refreshed. If the Data Provider for the table is a ServiceDataProvider though, we'll often see a pattern like this for the Add button action chain:   So here, there are just two steps: the first to call the relevant POST to update the backend with the new task data, the second is  a Refresh Data Provider Event Action.  You'll find that this works just fine, however, there is a catch relating to the possible performance cost this this approach and other side effects, so let's learn some more: Lesson 1 - Refresh does not actually "Re-Query" the Data Provider It's a common misconception that the refresh data provider causes a provider to "re-query" its data by calling the associated endpoint on the REST service, this is not strictly true. All refresh is is an event associated with the Data Provider object but which as no direct effect on the DataProvider itself.  What actually happens is that components such as the <oj-table> that are bound to the Data Provider will be internally listening out for Data Provider refresh and mutation events. When they see a refresh event they will generally grab an iterator over the Data Provider data set to get all the data again (including any updates, inserts and deletes).  Now, because the Service Data Provider does not actually cache any data itself, it will need to go back to the service with a GET call to get the data from scratch. So it appears that the refresh event caused a re-GET of the data, but in reality this is just a side effect of the event. You might also run into secondary side effects such as the component resetting its scroll point or forgetting it's current selection - all because it's doing what you told it to do.  So, why is this interesting?  Well in the case of a table backed with a Service Data Provider we can see that the simple two step action chain used to add the new task is actually quite expensive. We have one roundtrip to POST the new to-do task to the  backend and then we throw all of the task data we already have away and get it again from the back end with a fresh GET request.  In some cases this can be desirable because you really want to have an up to date picture of the state of the dataset on the server, sometimes, however, there is really no need to refresh the data you already know about.  This is where the other mutation events come in.  In this article I'm concentrating on the add event only, but I'll cover update and remove events in a later article. Lesson 2 - The add event is Purely Local  Another misconception we see is that the add (or update or remove) Data Provider event somehow should update the back end service with changes.  This is not the case.  These events are just like the refresh event, the only effect they have is on components that are bound to the Data Provider in question. So really you can think of  a Data Provider add event as being a message to any component that is interested to tell them that there is a new row and the information that is in it.  These components can then react by internally adding the new row without having to go back to the server to get it.  This of course is much more efficient! Reworking the Example  So we have a minor change to make to the action chain, rather than selecting the refresh option on the radio buttons for the Data Provider event we choose Mutate and then it's all about the payload for the add event.  You can find the documentation for the event payload in the Oracle JET documentation for DataProviderAddOperationEventDetail. But I'll explain what the elements of the payload are here in context.  If you define a Mutation Data Provider event and then click assign and expand Add, this is what you will see: I'll start with the simplest of these, the data element.  This simply needs to be set to the record that you are "adding". In most cases (such as when using the built-in business objects layer) this will actually be contained within the information returned from the POST call you used to create the new row in the first place.  The data will be an array because you can add multiple rows in one go should you wish to. The twist to watch out for is, in the typical case, this data object should actually be an items array inside of the data element - this matches itemsPath defined for the Service Data Provider. If your Service Data Provider has a different value for itemsPath then you should use that.  In this case, I'm using a standard Visual Builder Business Object and my REST POST action was called callPOSTNewTask, and so the data element of the add payload is: {"items":[ $chain.results.callPOSTNewTask.body ]} Make sure that the Expression radio button is selected when entering this, not Static Content. Next we have to map the keys element. This again is an array containing the keys of the row(s) we are trying to add, in the same order as the contents of the data.items[] array if there is more than one. As before, we can get the correct key ID for the POSTed row from the return payload of the POST REST action: [ $chain.results.callPOSTNewTask.body.id ] Again, make sure that the Expression radio button is selected when entering this. Finally we need to tell the Table or ListView where to add the new row.  This can be specified in one of two ways - either using the indexes element to indicate an absolute position or, in the next version of Visual Builder, using the addBeforeKeys element to indicate an insertion position which is relative to a particular existing row. Again, both of these elements are arrays so that you can add multiple rows in one go.  In this case I just want to add  the new task to the bottom of the table and I can use the special value of -1 for the index to achieve this (using 0 would insert at the top): [ -1 ] This time its OK if Static Content is selected. If you switch to JSON code view for the Data Provider Event action it then looks like this: "dataProviderAddMutationEvent": { "module": "vb/action/builtin/fireDataProviderEventAction", "label": "Add Mutation Event", "parameters": { "target": "{{ $page.variables.tasksListSDP }}", "add": { "data": "{{ {\"items\":[ $chain.results.callPOSTNewTask.body]} }}", "keys": "{{ [\n $chain.results.callPOSTNewTask.body.id\n] }}", "indexes": [ -1 ] } } } And visually the action chain looks like this: One nice side effect that you'll see of using this add mutation event is that when it happens the Table or ListView will animate the addition of the new row, so as well as being more efficient, it also provides a better user experience.   

Recently there have been a lots of questions from the Visual Builder community relating to how to display both a collection based UI such as a Table or ListView  and a data entry form for that...

Oracle Visual Builder Cloud Service

Service Methods for Business Objects in Visual Builder

In a previous blog I showed you how to create an object function for a business object to allow you to expose specific functionality on a specific row. This blog is a little variation on this capability showing you how to create service methods in your data layer that are not related to a specific row.  This is based on a use case a customer had where they would get data for a record in a table, if the row already exists in the table they need to update it. If it doesn't exist they need to create a new row with the data. The REST API provided by the Visual Builder business objects supports this use case as long as you have the id of the record you want to update. This is done with the upsert option for a POST call - see the information about this combined insert/update operation here. But the data that the customer got didn't have the id of the record they would need to update. Instead they had the information about another field in the object. To resolve this we can create a function in the BO layer that will search the set of records for a specific value in a specific field, and then update that record if the value is found, or insert a record if it doesn't exist. The tricky part is that object functions work on a specific record in a BO (the id of that record is part of the path to that REST endpoint). In our case, we don't have a row to work on. Instead, we are going to create a dummy business object, with a single row in it. Then we'll create the function on this business object, always invoking it with the id of the row that is in there. This technique could be useful for any generic function you need in you BO layer that doesn't directly relate to a specific row. The function itself is written in Groovy, the programming language used by the Visual Builder business objects layer. In the video you'll see how we use various methods available on BOs in groovy (such as methods to query, add filter condition, and insert new records). You can learn more about these and other methods in our new Groovy for Visual Builder Reference Book. In the video below you'll see how to add such a function and how to call it from the VB user interface. Note that these functions are also callable from other tools through simple REST calls.   For those interested in the specific code used in the sample it is: def vo = newView('Department') vo.appendViewCriteria("department = '"+dname+"'") vo.executeQuery() if (!vo.hasNext()){   r = vo.createRow()   r.maxSalary=salary;   r.department=dname;   vo.insertRow(r) } while (vo.hasNext()) {   def r = vo.next();   r.maxSalary = salary; }   Line 1 gets us a pointer to our business object Line 2 adds a "where" clause to the query associated with our instance Line 3 execute the query with this where clause in the If section starting at line 4 we take the case where no records where found, create a new row, populate the data in the fields in that row, and then insert it into the business object. In the while loop we handle the case where a record (or more) were found, and update that row with the new value.

In a previous blog I showed you how to create an object function for a business object to allow you to expose specific functionality on a specific row. This blog is a little variation on this...

Oracle Visual Builder Cloud Service

May the 4th be with you: 4 reasons to use Visual Builder for your next app and other bad star wars puns

    1) Use the source, Luke We had a saying back in my early days of developer support at Borland. If a challenging issue came in a senior engineer would tell us "Use the source, Luke" and we would dutifully follow the logic with a breakpoint debugger until the bug/issue revealed itself. Of course, most declarative tools like Visual Builder generate code but oftentimes these types of tools choose to hide the implementation from the app developer. All of the HTML 5, CSS, and Javascript (as well as required JSON metadata files) are provided for your editing and management.  However, the power of the declarative, drag and drop approach has not been compromised. In fact, Visual Builder contains even more visual tools than ever for not just UI layout and flow, but also creating custom logic, mapping variables and parameters, managing data and object relationships, and more.  An example action chain of complex, conditional logic from a button press action Having access to the source code is important, not just for troubleshooting and customization, but also for dev ops. Managing the code in a shared code repository makes the code easily versioned but also gives access for professional developers from whom you may need some custom code. You can also take advantage the advanced features of a dev ops environment, like Oracle Developer Cloud Service (a provided entitlement when you use the Oracle Platform), to manage builds and testing on check-in (push to Git)  for example.   2) I find your lack of REST disturbing REST has become the lingua franca of connectivity to services and Oracle PaaS and SaaS services have quickly adopted it. Visual Builder is all about REST and makes it easy to connect to other services whether they are well described or not. Well described services publish a format, such as Swagger, that describes the API and allows tools like Visual Builder to generate programmatic access to those connections. Visual Builder goes one step further and makes it super simple to select the right API to data bind to a visual control for the proper operation. Visual Builder also connect to the Oracle API catalog as well as your internal catalog to automate the visibility of Oracle services that are readily available to you. Figure 1: Easily add services into your application from a Catalog, Specification, or Endpoint mapping Once imported, binding a UI control to your service call is as simple as selecting the right endpoint for your intended operation. Those operations can be generally described as Create, Read, Update, Delete (CRUD) and the typical HTTP request type corresponds as such: Create = POST Read = GET Update = PATCH Delete = DELETE Shown below is the declarative approach within Visual Builder to bind a control to some service data.  1) Add data or create the page for the CRUD action 2) Select the endpoint for the CRUD action 3) Select the fields you want to retrieve or update Done. Both external service and local business objects present REST interfaces so there is a consistent approach to working with data.    3) These are not the devices you're looking for The line between mobile apps and web apps have become more blurred over these last few years. It used to be that in order to deliver a "native" mobile experience, you would have to build platform packages (IPA/APK) and deploy through the platform app store. With the "progress" in Progressive Web Apps (PWA), you can deliver apps to your devices without going through an App Store yet still providing a native experience. In this case, a native experience is defined as: Fullscreen app (no browser chrome like URL bar and back/forward buttons) Installed icon on device home screen to launch app Local assets "installed" to improve performance (no need to fetch pages/images initially) Platform specific look and feel Visual Builder now supports delivering your apps as PWA with the simple selection of the option in your app settings. Within your PWA steins you can add icon sets (Application Image Archive_ and specify which files you want cached when your PWA gets installed on the home screen.    4) Now, witness the firepower of this fully operational app platform Visual Builder delivers a modern and fresh approach to app development and its encouraging to see rapid application development (now called low-code) techniques being applied to web development with HTML and Javascript industry wide. Whether you are creating extensions to SaaS applications, modernizing existing on-premises systems, or building new web and mobile apps, we hope you'll give Visual Builder a go. And let us know what you think?

    1) Use the source, Luke We had a saying back in my early days of developer support at Borland. If a challenging issue came in a senior engineer would tell us "Use the source, Luke" and we would...

Oracle Visual Builder Cloud Service

Secure Static Headers for Visual Builder Service Connections

In Visual Builder 19.1.3 we introduced a new feature for Service connections – Secure Static Headers.  With this, we can now add header parameters to the Service connections which will only be applied securely from the VB server side and never be brought to the browser/client end. In a previous blog post , we discussed about the two broad strategies to connect to external Services from Visual Builder – Direct or Proxy.  In the Proxy method, we rely on the VB server side proxy to pass on our request to the external service with the appropriate authentication applied.  The credentials (client id/secret etc.) or the final Authorization header that is applied are never brought to the browser/client end.   What if there were other headers that we needed to pass to the service in this fashion?  For example – take the case of a service that has a special header called X-System-API-Key which needs to be transmitted securely.  In this case, the header can be added as a Secure Static Header. Another case could be systems where the Authorization header is given as a long lived Bearer token or a special key.  For example, Oracle Mobile Hub REST API has one such authentication option called the Anonymous key (shown in the below figure) which needs to be passed to the calling service as “Basic <AnonymousKey>” (See OMH documentation for more details).  We require two things to connect to an OMH backend REST API in this manner - the Anonymous key and the Backend ID. We can configure this in Visual Builder with Secure Static Headers.  You might have noted that Visual Builder gives you the flexibility of defining headers either at the Service level, or at individual Endpoint level.  If a particular header parameter is defined at Service level, it is applicable to all the Endpoints that are added to the Service (and saves you from the hassle of repeating this configuration for all endpoints).  The option of defining Secure Static Headers is only at the Service level for now. Below are the steps for connecting to an Oracle Mobile Hub Backend API with the Anonymous key using Visual Builder’s Secure Static headers functionality: Create a Service Connection by using “Define by Endpoint” flow.  For authentication, we are not given a username and password by Oracle Mobile Hub, but rather a string (“Basic <AnonymousKey>”), hence we would choose “Enable authentication/proxy” and choose “None” (and later add the Authorization as a secure static header).  Note we will not be able to add secure static headers just right now, because the options displayed in this flow are only to add headers at endpoint level Navigate to Response tab and provide an empty response body “{}” for now Create the Service Connection Open the newly created Service Connection, navigate to the Headers tab.  This now shows you a list of the Service level headers (which is empty in our case).  Add the following: Authorization header as a Secure Static header with the value “Basic <AnonymousKey>” obtained from OMH settings.   Oracle-mobile-backend-id as a Static header with the value of the <BackendId> obtained from the OMH settings. Now navigate to Endpoints, choose the required endpoint (/dummy in this example).  Navigate to the Test tab corresponding to this endpoint and test the service.  This should now give a successful result. Use the test response as an example by clicking on “Copy to Response Body”   Now this Service Connection is ready to be used in applications.  For adding another endpoint, simply go to the Service Connection -> Endpoints and add another Endpoint.  You will not need to add any Authorization / Oracle-Mobile-Backend-Id headers now, as they were already defined at the Service level.   Some additional points to note: The example of Oracle Mobile Hub using Anonymous key is only used as an illustration for Secure Static headers.  You can very well configure an Oracle Mobile Hub REST API with Basic Auth/Client Credentials/Resource Owner Password authentication as well “None” is the only authentication mechanism that allows you to define a static Authorization header.  If you try to use this with “Basic” for example, the hardcoded static Authorization header will be ignored, and whatever is set in the Authentication tab (Username / Password) will take precedence.    

In Visual Builder 19.1.3 we introduced a new feature for Service connections – Secure Static Headers.  With this, we can now add header parameters to the Service connections which will only be applied...

Oracle Visual Builder Cloud Service

Running Visual Builder Apps On Other Servers (and On-Premises)

Ever since we released Oracle Visual Builder a frequent request has been "can I take the app and run it anywhere I want?". With the latest version of Visual Builder the answer is Yes! This means that you can take apps you built in the Oracle Cloud and host it in other web servers. (Development is still cloud based only). Note that if you decide to take the visual builder server out of the picture, you are going to lose some of the functionality that runs on the Visual Builder Cloud Server, specifically: Business Objects - these run on the VB backend - so if you are not going to use our backend - you won't have a place to run them. (You could still run that part on the VB backend, and have your app UI served from another server). Identity Cloud - Visual Builder leverages Oracle's Identity Cloud to manage users and roles as well as authentication and authorization. If you are not using the VB Cloud hosting platform, it is up to you to manage these aspects of your app. Visual Builder proxy - On the Visual Builder server we have a piece of software (called the authentication proxy) that manages connections to REST services. The proxy handles things like passing in credentials and eliminating CORS (you can read more about the roles of the proxy and when to use it in this blog entry). If you don't want to use this piece of software you need to switch the connection of the services you define in VB to "Direct (bypass proxy)" and then the calls are being done directly from the browser to the remote REST service. If you are fine with these limitations, or if you have other solutions for these requirements, you can host your Oracle Visual Builder app on another web server without needing to access the VB server. (Remember that you can still choose to host your VB app somewhere else, but use the VB server for the above functionality - although if this is what you are doing, you are probably better off just hosting directly on VB). Here is a quick demo showing how to take an app and move it to run completely on your own machine (including accessing REST services and a database that is running on that machine). As you can see there are a couple of adjustments we did to our app to remove the dependency on the services that the Visual Builder server provides. We switch to use the direct access to the REST services, and we allowed anonymous access to our app (since we don't have IDCS to manage authentication). Then we used the grunt vb_build step (more on this in the blog entry about app optimization and CI/CD) to create the zip file that contains the app ready to be deployed - leveraging the archive artifact step in Developer cloud to save those files. We took the optimized version of the app and hosted it as a regular collection of HTML/JavaScript resources on a web server (Apache in the video). Then we showed how you can switch the set of services that the app is accessing by doing a "global search and replace" to replace the address of the server hosting the REST services that provides our app the data we use - this will allow you to also move your backend to be on-premise. (In the video we are using WebLogic to host ADF based REST services, accessing an Oracle XE database running in a docker image). With these simple steps you can easily host your VB applications anywhere.

Ever since we released Oracle Visual Builder a frequent request has been "can I take the app and run it anywhere I want?". With the latest version of Visual Builder the answer is Yes! This means that...

Oracle Visual Builder Cloud Service

Automating CI/CD and App Optimization for Visual Builder Apps with Developer Cloud

The latest version of Visual Builder added support for app optimization as well as the ability to automate the staging and publishing of Visual Builder apps. To achieve this we use Grunt - a JavaScript task runner - and a set of grunt tasks specifically built for Visual Builder. A key thing that you can achieve with these commands is optimization of your delivered application - which can improve your runtime performance. We do this by minimizing the size of the resources that are downloaded to your clients. So this approach is recommended for use not just in cases where you want to automate delivery, but also in any application deployment process. The Visual Builder developer guide contains a section about the various grunt tasks you can use. While there are multiple tasks available, we'll focus on a couple of top level tasks that simplify the build process by executing a collection of other tasks in the correct order. The two main ones are vb_build and vb_publish. The vb_build command will take your application all the way to the staging stage (in the process executing the vb-clean, vb-process, vb-optimize, and vb-stage tasks). As you can see in the doc there are a bunch of parameters you can pass to the task the important ones are: id  the id of the app (see the VB app list home page) version the app's version (see the VB app list home page) username Your username password Your password - for better security choose a password type for this param in DevCS url the URL to your VB instance (including the ic/builder part) optimize The type of optimization you want (uglify, uglify2 or none) schema What to do with the DB schema - values can be dev/stage/live/new In the video below I'm defining a build job in DevCS and define these parameters with default values that match my app. Then I define a build step that uses a shell script that refers to those parameters like this: npm install   ./node_modules/.bin/grunt vb-build \   --url=${url} \   --username=${username} \   --password=${password} \   --id=${id} --ver=${ver} \   --optimize=${optimize} \   --schema=dev This command, for example, will take our source, optimize it, and stage it copying the data from the development database to the stage one. The second task, vb_publish, publishes the application - so it becomes accessible to the users. It has a similar set of parameter to the vb_build command. In the video I used: npm install   ./node_modules/.bin/grunt vb-publish \   --url=${serviceURL} \   --username=${username} \   --password=${password} \   --id=${id} --ver=${ver} \   --optimize=${optimize} \   --schema=new These tasks can be run on your own local machine, but a simpler way is to leverage Oracle Developer Cloud to automate the process. Leveraging DevCS lets you hook up this continuous delivery functionality directly to your Git code repository so you can, for example, automate staging a new version of the app after every code change. Note that you'll be using the build functionality of Developer Cloud, which means that your DevCS admin will need to define a build VM. Since we are using npm in our build steps, make sure that the build template used in your build job contains node.js as one of the software components. One other to watch out for is the version parameter in the build. Remember that you can't stage an app with the same version as a published app, so you would want to increase it the next time that you run a staging task after you ran a publish task.      

The latest version of Visual Builder added support for app optimization as well as the ability to automate the staging and publishing of Visual Builder apps. To achieve this we use Grunt - a...

Oracle Visual Builder Cloud Service

Accessing DB objects through Oracle Integration Cloud for a Visual Builder App

[This is a guest post by Cosmin Manole from the Oracle Solution Hub Team] Visual Builder can quickly access data originating from Business Objects and external data sources that can be consumed through REST service endpoints. But what if a simple database connection is available with no REST endpoints exposed? In past blog entries we covered accessing the database with Java code (using ADF BC), and using PL/SQL based ORDS is another option, one additional possible solution is to leverage Oracle Integration Cloud, which allows CRUD operations to be implemented through Basic Routing integrations leveraging built-in database connections and queries. For this example we assume a connection to database is available and can be tested from OIC’s Integration service. The two main parts for this solution are: Exposing Data Through Integrations: This step creates REST endpoints for database actions In order for Integration Cloud to fulfill its role, a few actions are required: Create a database connection. This action is available from the Basic Routing configuration view, as well as from the Connections entry. In this example the connection is setup starting from the Integration configuration view. (part of the first video below) Create and configure the Basic Routing integrations required for each of the desired service actions (GET and PUT are showcased in the videos below (video 1 & 3) ) The available REST services will be consumed by VBCS (depicted in video 2 & video 3 for GET and PUT respectively) <video 1: create GET REST endpoint & required DBCS connection> The REST endpoint can now be used by VBCS. First, a Service Connection is created: <video 2: VBCS service connection – GET> The following video shows the creation of a new REST endpoint for updating a list item on the database. The action is registered with VBCS as a new service connection <video 3: create Integration update REST service & VBCS service connection PUT> Similarly, a POST action is added to the VBCS service connections. *Integration setup not part of the video for this scenario. <video 4: vbcs service connection POST> Consuming the REST services with Visual Builder Once the REST endpoints are available and tested they can be consumed by VBCS: Creating lists and managing information is easy through service connections and the underlying implementation is transparent to the UI developer. Developers can quickly display data and associate update, insert, or delete actions to buttons found in list items.  

[This is a guest post by Cosmin Manole from the Oracle Solution Hub Team] Visual Builder can quickly access data originating from Business Objects and external data sources that can be consumed...

Oracle Visual Builder Cloud Service

Oracle ERP Extension with Visual Builder Cloud Service

In this tutorial we're going to create a an extension to Oracle ERP that serves as a staging area for invoices and allows you to apply discounts to the line items on the invoice. Once the discount has been approved, there will be an action to create the invoice in ERP.  The app is based on Visual Builder Cloud Service business objects. Certain data, like customer and product info, is replicated from ERP into the VBCS business objects. In a real production setup, you would use Integration Cloud to schedule a data extract from ERP and into the VBCS on a regular basis. Here's what the data model looks like: Setting up the Project Import this file to your computer. In the VBCS home page, click Import > Import from File, and upload the ZIP there. Adding the List of Invoices Drag a table component into main-start. In the Quickstarts tab of the Property Inspector, click Add Data. Select Business Objects > Invoice and click Next. Select the following fields and click Next: BillToCustomerNumber BusinessUnit totalAmount discount discountedAmount Click Finish. Drag a Currency component onto the Discounted Amount column. The number changes from a regular number to a currency. Do the same for Total Amount. Drag a Percentage component onto the Discount column. Your finished table should look like this: Adding the Create Page By the end of this chapter, you will have: Added a Create page to your list of invoices Added an action chain on the Customer drop-down to populate the rest of the customer information Hard-coded the default value of fields like Transaction Type and others. Let's get started! Select the table in the Page Designer. Click the Quickstarts tab of the Property Inspector and click Add Create Page. Select Business Objects > Invoice and click Next. Select the following fields: customer (automatically added) BillToCustomer BusinessUnit InternalCurrencyCode PaymentTerms TransactionDate TransactionSource TransactionType status Change the Button Label to Create. Click Finish. Command-click the Create button to open the Create page in the Page Designer. Delete the Status field. Reorder the remaining fields so they look like this: Select the containing form-component and in the Property Inspector set Max Columns to 2. Set the following components to be read-only by selecting them and clicking Readonly in the Property Inspector: Bill To Customer Business Unit Internal Currency Code Payment Terms Transaction Source Transaction Type Select the Customer drop-down. In the Property Inspector, click the Events tab. Then click New Event > Quick Start: "value" Drag a Call REST Endpoint into the action chain. Click Select Endpoint and choose Business Objects > Customer > GET /Customer/{Customer_Id} In the Property Inspector, click Input Parameters > Customer_Id. Map value to Customer_Id. Drag an Assign Variables action to the success path below the Call REST Endpoint action. Click Assign in the right panel to open the mapper dialog. Map the fields from the response body of the REST call to your invoice page variable as shown below: businessUnit -> BusinessUnit customerNumber -> BillToCustomerNumber invoiceCurrencyCode -> InternalCurrencyCode Click Save and close the editor tab for the Action Chain. With main-create-invoice tab open in the Page Designer, click the Variables button in the sidebar. Expand {} invoice and set the default values for the following fields: TransactionSource -> Manual TransactionType -> Invoice status -> Requested PaymentTerms -> Net 15 Use the Run button to preview the app and to create a new record. Adding an Edit Page Our create page just fills in the general overview information of the invoice. Now we will create an edit page that allows us to enter line items, set the discount, and recalculate the total based on the discount and line items. Go back to main-start and select the table in the Page Designer. In the Quickstarts tab of the Property Inspector, click Add Edit Page. Select Invoice for the Read Endpoint and click Next. Then select Invoice for the Update Endpoint and click Next. On the final page of the wizard, select the following fields for inclusion: BillToCustomerNumber BusinessUnit InternalCurrencyCode PaymentTerms TransactionDate TransactionSource TransactionType customer discount discountedAmount totalAmount Rename the button label Edit. Click Finish. Open the Edit Page with Live Mode by selecting Live in the upper-right of the Page Designer, then selecting a row in the table and clicking the Edit Invoice button. This opens up the Edit page with the context of a row to edit. If no context is available, you'll get an error message in the Page Designer. Any time this happens, simply switch back to the main-start page, go into Live Mode, then open a record to edit. Don't forget to switch the Page Designer back to Design Mode once you've opened the Edit Page. Rearrange the fields so they look like this: Select the Form Layout (select anywhere around the fields in the Edit Page or open up the Structure View and click the Form Layout component there). In the Property Inspector, set Max Columns to 3 and Label Edge to top.  Set all of the fields except Customer, Transaction Date, and Discount to be read-only. Set up the Customer drop-down to populate the customer fields like you did in the Create page. (If you are short on time you can skip this part.) Select the Customer drop-down. In the Property Inspector, click the Events tab. Then click New Event > Quick Start: "value" Drag a Call REST Endpoint into the action chain. Click Select Endpoint and choose Business Objects > Customer > GET /Customer/{Customer_Id} In the Property Inspector, click Input Parameters > Customer_Id. Map value to Customer_Id. Drag an Assign Variables action to the success path below the Call REST Endpoint action. Map the fields from the response body of the REST call to your invoice page variable as shown below: businessUnit -> BusinessUnit customerNumber -> BillToCustomerNumber invoiceCurrencyCode -> InternalCurrencyCode Click Save and close the editor tab for the Action Chain. Select Total Amount and in the Property Inspector set the converter to $ and the Currency Code to USD. Your page should now look like this: Now let's update Discounted Amount so that it changes when we update the discount. Select Discounted Amount and in the Property Inspector click the Data tab. Set the value to: {{ $variables.invoice && $variables.invoice.discount !== undefined ? $variables.invoice.totalAmount * (1-$variables.invoice.discount) : $variables.invoice.totalAmount }} The basic information is now set up. However, if you run the page and try to save it, you'll get an error. This is because the app is trying to send all of the parameters that it fetched in the GET back to the PATCH endpoint, including two read-only fields (discountedAmount and totalAmount). These fields are read-only because we set them in the data model to be calculated from formulas/aggregations. We need to create a new payload variable that will store all of the read-write properties from the page and use that.  Click the Variables tab in the left sidebar of the Page Designer. Click the Types tab > + Type > From Endpoint. Select Invoice > PATCH /Invoice/{Invoice_Id}. Click Next. Name the type updatePayload and add the following fields from the Request node (not the Response node): BillToCustomerNumber BusinessUnit InternalCurrencyCode PaymentTerms TransactionDate TransactionSource TransactionType discount customer status Click Finish. Click the Actions tab in the left sidebar of the Page Designer. Click the SaveInvoiceChain action chain. Click the Variables tab in the left sidebar of the Action Chain Editor. Click + Variable and add a variable called payload of type updatePayload. Click the Action Chain tab in the left sidebar of the Action Chain Editor. Drag an Assign Variables action directly below the Start action. Click Variables -> Assign in the right sidebar of the Action Chain Designer. Map Page > Invoice to Action Chain > payload. Click Save.  Scroll down and select the Call REST Endpoint action. In the right sidebar, click Parameters > body. Delete the existing mapping and map Action Chain > payload to Parameters > body. Click Save. Adding the Line Item Child Table Now it's time for adding the UI to manage the line items for the invoices. Note that in the data model, each line item has a mandatory reference field to its parent invoice. Also, each line item has a lineTotal field which we will calculate based on the unit price, quantity, and discount. In this chapter you will: Add a table to the Edit Page and bind it to ReceivablesLineInvoice Set a filter on the table to only show line items for the current invoice Add a column with a line total calculated on the fly as the discount changes Add a Create page for the line item (in the interest of time we won't do an Edit page) Default the invoice reference in the newly created line item to point to the current invoice So let's get started! Open the Edit page in the Page Designer. Drag a Heading component between the Form Component and the Toolbar containing the Save and Cancel buttons. In the Property Inspector, set the Text to Line Items and the Level to H3. Drag a Table component below the Heading. In the Quickstarts tab of the Property Inspector, click Add Data. Select ReceivablesInvoiceLine in the wizard. (Hover over each node to see the full name of the business object.) Click Next. Add the following fields: Description Quantity UnitSellingPrice lineTotal Click Next. In the Define Query page, expand filterCriterion > criteria > item[0]. Select attribute and type invoice in the Expression field. Make sure it's set to Static Content and not Expression. Select op and type $eq in the Expression field.  Map Page > InvoiceId to the value field of the filterCriterion. Click Finish. Notice the Unit Selling Price and Line Total were entered as numbers and not currency. Drag a Currency component into each of the columns to change them to display as currencies.  Now let's add another column which will automatically update based on the discount amount. Drag a Text component to the slot at the end of the table. In the Property Inspector with the Text component selected, change the value to  {{ ($variables.invoice.discount !== undefined) ? (($current.row.Quantity * $current.row.UnitSellingPrice) * (1 - $variables.invoice.discount)) : ($current.row.Quantity * $current.row.UnitSellingPrice) }} Now let's fix the column header. In the Page Designer, select the table. In the Property Inspector, click Data and change the cellTemplate to Discounted Total. Now let's add the create page for the invoice. In the Page Designer, select the table and go to the Quickstarts tab of the Property Inspector. Click Add Create Page. Leave ReceivablesInvoiceLine selected as the endpoint and click Next. Add the following fields: Description LineNumber Quantity TaxClassificationCode UnitSellingPrice invoice lineTotal product Change the Button Label to Create. Click Finish. Open the Create page by switching to Live Mode and clicking the Create button that you just added. Delete the Description, Tax Classification Code, and Invoice fields, as we will default these. Rearrange the fields so your form looks like this: Make Unit Selling Price and Line Total read-only. Now let's update the fields in the page based on which product is selected, like we did with the Customer field on the main Invoice pages. Select the Product field, go to the Events tab of the Property Inspector, and click + New Event > Quick Start: value. Drag a Call REST Endpoint under the Start node. Click Select Endpoint in the right sidebar and choose Product > GET /Product/{Product_Id}. Click Select.  In the right sidebar, click Input Parameters > Product_Id. Map Action Chain > value to Parameters > Product_Id. Click Save. Drag an Assign Variables action into the success path. In the right sidebar, click Variables > Assign. Map description and unitSellingPrice from the REST response body to receivablesInvoiceLine > Description and receivablesInvoiceLine > UnitSellingPrice. Click Save and close the Action Chain editor tab. Back in the Line Item Create Page, select the Variables tab on the left and select receivablesInvoiceLine > TaxClassificationCode. Set the default value to FR VAT STD DEF RATE AP. Switch back to the Page Designer. Select Unit Selling Price, and in the Property Inspector, switch the Converter to $ and set the Currency Code to USD.  Do the same for Line Total. With Line Total still selected, click the Data tab of the Property Inspector and change the Value field to: {{ ($variables.receivablesInvoiceLine.Quantity && $variables.receivablesInvoiceLine.UnitSellingPrice) ? $variables.receivablesInvoiceLine.Quantity * $variables.receivablesInvoiceLine.UnitSellingPrice : 0 }} Now we need to change the Save action chain to calculate the lineTotal before sending the payload to the PUT endpoint. Select the Actions tab on the left and click createReceivablesInvoiceLineChain. Drag an Assign Variables action below the Start action. In the right sidebar, click Variables > Assign. Select Page > receivablesInvoiceLine > lineTotal and change the value to: $page.variables.receivablesInvoiceLine.Quantity * $page.variables.receivablesInvoiceLine.UnitSellingPrice Make sure that it's still set as an Expression and doesn't change to Static Content. Click Save. One last step! We need to pass in the Invoice Number when we navigate to the Create Line Item page and default the invoice reference to this value. Go back to the main-create-invoice-line page and click the Variables tab on the left. Click + Variable and add a String called InvoiceId. In the Property Inspector, make the string as a required input parameter that's passed on the URL. Go back to the main-edit-invoice page. Click the Actions tab in the left of the page and click navigateToCreateReceivablesInvoiceLineChain. Select the Navigate action and in the Property Inspector, click InvoiceId. Map Page > InvoiceId to Parameters > InvoiceId. Click Save. Go back to the main-create-receivables-invoice-line page and click the Variables tab on the left. Expand receivablesInvoiceLine and select invoice. Set the Default Value to {{$page.variables.InvoiceId}}. Adding a Custom Component Now let's add a custom Oracle JET Web Component to display a timeline of invoices.  Download this component to your computer. Open main-start in the editor. In the list of components, scroll down to the bottom and click the + sign in the Custom category. Drag the ZIP file into the dialog and click Import. The component gets added to the Palette. Update your SDP definition to include the fields that the custom component requires. Go to the Variables tab for main-start, click Types, and click Edit from Endpoint for getallInvoiceResponse. Select the status and TransactionDate fields (and leave all of the previously selected fields selected) and click Finish. Drag the component onto the page. In the Property Inspector for the my-timeline component, enter {{ $variables.invoiceListSDP }} for the items property. Building the ERP Integration So we've got our staging area for our invoices and for calculating our discounts all ready. Now we need to create an integration into ERP so we can create the invoices in ERP cloud. We will create a service connection to the POST receivablesInvoice REST API then use a custom JS function to prepare the payload. In the main application navigator, click Service Connections. Click + Service Connection. If your VB instance already has a registered SaaS API Catalog, then use the Select from Catalog functionality and skip to step 5 below. If not, select Define by Specification. Enter the following information: API Type: ADF Describe Service Specification: Web Address -  https://ERP_Base_URL/fscmRestApi/resources/11.13.18.05/receivablesInvoices/describe Service ID: invoices Authentication: Basic Username: CAROLINE.VALENCE (or some user that can call this service) Password: your password Click Next. Select receivablesInvoices > POST /receivablesInvoices and click Finish. Open main-edit-invoice and click the JS tab in the left sidebar. Enter the following code in bold in the JavaScript. var PageModule = function PageModule() {}; PageModule.prototype.getCreateInvoicePayload = function(invoice, invoiceLines) { var invoiceLineNumber = 1; return { BillToCustomerNumber : invoice.BillToCustomerNumber, BusinessUnit : invoice.BusinessUnit, InvoiceCurrencyCode : invoice.InternalCurrencyCode, PaymentTerms : invoice.PaymentTerms, TransactionDate : invoice.TransactionDate, TransactionSource : invoice.TransactionSource, TransactionType : invoice.TransactionType, receivablesInvoiceLines : invoiceLines.map(i => { return { Description : i.Description, LineNumber : invoiceLineNumber++, Quantity : i.Quantity, UnitSellingPrice : i.UnitSellingPrice * (1-invoice.discount), TaxClassificationCode : i.TaxClassificationCode }}) }; } return PageModule; Go back to the Page Designer tab and drag a new Button component next to the Save and Cancel buttons at the bottom of the page. Change the display text to Submit. Switch to the Events tab of the Property Inspector and click + New Event > Quick Start: 'ojAction' Drag a Call REST Endpoint action to the chain. Select Endpoint and select Business Objects > ReceivableInvoiceLine > GET /ReceivableInvoiceLine and click Select. With the Call REST Endpoint action selected, click Parameters > requestTransformOptions in the right sidebar. Expand Parameters > requestTransformOptions > filter > criteria > item. Set the following values: attribute: invoice (Static Content) operator: $eq (Static Content) value: $page.variables.invoiceId (Expression) Drag a Call Module Function action to the success path of the Call REST Endpoint. Click Select Module Function, select the getCreateInvoicePayload function, and click Select. Click Input Parameters > Assign and map Page > invoice to Parameters > invoice and Action Chain > Results > callRestEndpoint1 > body > items to Parameters > invoiceLines. Click Save. Drag a Call REST Endpoint action below the Call Module Function action. Click Select Endpoint and select the POST /receivablesInvoices endpoint. Click Parameters > body and map the output of the getCreateInvoicePayload function to the body. Click Save. Drag a Fire Notification action to the success path of the Call REST Endpoint action. Set the Summary to "Invoice created!", Notification Type to confirmation, and Display Mode to transient. Drag a Fire Notification action to the failure path of the Call REST Endpoint action. Set the summary to "Something went wrong!" and leave the rest of the fields at their defaults. Drag a Navigate action below the success Fire Notification action. Click Select target > Root Page > shell. This will navigate back home. Test out your app. You did it!  

In this tutorial we're going to create a an extension to Oracle ERP that serves as a staging area for invoices and allows you to apply discounts to the line items on the invoice. Once the discount has...

Say Cheese! Take Photo action improvements in Visual Builder 19.1.3 release

    Take Photo is a very useful action, especially on Mobile, as it provides access to the device camera. Take Photo is used to capture images, like personal photographs, as well as other uses, like scanning QR or bar codes. Depending on your use, you may need to just access the image on device or you may need to send it to another service, like a storage service.  Previous to the 19.1.3 release, Take Photo returned a file patch to the image on the local device. This path could easily be assigned directly to a JET image or avatar component in the next step of the action chain. However, if you needed to send it to a storage service, some preprocessing needed to be done on device to prepare it for delivery.  Vijaykumar Yenen has written an excellent article that details this previous behavior. It shows some of the custom code needed to prepare the image for upload to a service. Each storage service has different requirements for uploading images but generally you need to create a Base64 encoded string to send to the service. In some cases, the storage service has a POST operation that requires a pointer to the file. In those case, tools like Postman would provide a filepicker to select the file, and now in 19.1.3, Take Photo provides similar functionality by default. This behavior is seen in the new Media Type property in the Take Photo action, if set (by default) to "image."   However, what is you want the old behavior, i.e. assigning the file location to a JET image or avatar component. Well, there are a a couple of options. The easiest is to  remove "image" from the Media Type property and set it to nothing. In that case, the Take Photo action reverts to returning the file path. You can also write some custom code to convert the Blob stream to a URL which you can set to the src property of the image component. See the code sample below:   PageModule.prototype.showPic = function(fileBlob) {     const blobURL = URL.createObjectURL(fileBlob);     // Release the BLOB after it loads.     document.getElementById("mypic").onload = function() {       URL.revokeObjectURL(blobURL);     };     return blobURL;   }

    Take Photo is a very useful action, especially on Mobile, as it provides access to the device camera. Take Photo is used to capture images, like personal photographs, as well as other uses,...

Visual Builder Service Connections - Advanced topics

Service Connections are Visual Builder objects to represent REST API calls.  They are pretty much intuitive, and if you have used Postman or SOAP UI like tools to test web services, they will seem familiar, and yet there are some differences from these tools.  The aim of this blog post is to lay down some of the more advanced concepts around Service Connections.  For an introduction to Service Connections, refer to this blog If you have created a Visual Builder application that makes REST calls, you might have used a Service Connection by passing on an endpoint in a “Call Rest Endpoints action” in an action chain, or used them implicitly in a List or a Table that internally uses the same action.  When such an action is performed, there are two broad strategies to connect to REST APIs via Service Connections: Using the browser/client JavaScript to connect to the API Using the out-of-the-box VB Proxy to connect to the API Using the browser/client JavaScript to connect to the API In this, the request goes directly from the browser/mobile device to the External service as shown in the below figure:  It is similar to having Fetch API call from within your application’s client side JavaScript code as below: For simplicity we will call this browser JavaScript based method as “Direct” in the remainder of this post. Using the VB Proxy to connect to the API The VB Proxy is a server component of Visual Builder that can facilitate REST calls.  In this method, for every call, the request first goes to the Proxy, and then to the actual service being called.    What to choose : Direct or Proxy? Now, you may wonder which method to choose when calling a specific external service from Visual Builder.  There are some detriments to using the Proxy; namely it proxies each and every request, hence adding some extra latency. However there are cases, where Direct might not be the appropriate way to call your service as governed by the following three factors: Authentication method CORS support HTTPS support 1. Choice of Authentication method Some authentication methods are not suitable for directly calling the server from the browser, because the credentials used by these can be exposed in JavaScript.  For example. if you want to call an external service using Basic authentication, Direct wouldn’t be the right way at all, because the credentials to the service will be exposed to the client side JavaScript.  A quick look at the Network tab will also enable the users of your app get a hold of your external service credentials!       In general, Visual Builder doesn’t allow such combinations, thus protecting your application from any misconfiguration on part of the developer that could inadvertently leak credentials.  If you choose “Basic” in the authentication method of a Service Connection, the requests always go via the proxy (as shown below) and the Basic Auth credentials are applied at the proxy only, never being exposed to the client.  Authentication methods suitable for Direct For OAuth 2.0 based mechanisms (Client Credentials, Resource Owner Password, User Assertion OAuth) and for Oracle Cloud Account, you have an additional checkbox “Enable token relay” that specifies if the call is to made directly.    Unlike Basic Auth, these methods are safe to be called directly, because the credentials required for creating the token (username, password, client id, client secret) never travel to the client.  This is facilitated by another VB server side component called the Token Relay, which is in knowledge of these credentials, and creates the appropriate token, but only passes the final token to the client side and never the credentials that were used.  What if you have some custom JavaScript code that gets a bearer token through some process, and your requirement is only to pass the bearer token as-obtained to the Service Connection? In such cases of DIY authorization, you cannot use the VB Proxy as the it is designed strip off any Authorization header that is coming from the client, and re-insert the proxy configured Authorization headers.  To achieve this case, you can use “Direct” and give a dynamic “Authorization” header to the Service Connection endpoint as shown in the figure below.  Here an accessToken is obtained from some custom JavaScript code and then passed in via the dynamic header "Authorization" to the REST API.  Note that in this case the responsibility of maintaining the secrecy of the credentials procuring the token falls on you.     2. Available CORS support Further, there is another complication of Cross-Origin requests when calling services directly as opposed to via a proxy.  The browser is considered as an insecure environment, hence it blocks any external services that are being called with a domain that is different from the calling domain.  For example, if your app is running on domain vb.oraclecloud.com and your service is running on domain service.example.com, the browser first checks if the service.example.com domain has deemed JavaScript code served from vb.oraclecloud.com as allowed to call these services.  This is formally known as a CORS pre-flight request and consists of an OPTIONS call from the application to the service which returns several Access-Control-Allow-* headers.  From the value of these headers, the browser draws the conclusion whether or not the call to the external service is allowed (See wikipedia for a full description of CORS).  For such Cross-Origin requests to be allowed, you should have set the domain vb.oraclecloud.com in the CORS whitelist of service.example.com.  Note that this is a setting purely to be done on the remote server and not on Visual Builder.  If you have not set the Visual Builder domain (vb.oraclecloud.com for our example) in the CORS whitelist of the external service, you would get a pre-flight error in the browser console as follows “Access to fetch at 'https://service.example.com/service' from origin 'https://vb.oraclecloud.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource”.  The behavior of such a Service in the Test tab and the full CORS preflight error in the JavaScript console are shown below   Most modern resource servers support some sort of CORS configuration, or you could also set them programmatically.   However, in the case your external service doesn’t support CORS (or if you are unable to do this for some reason), you would need to call the service via a proxy. As an example, the Oracle Content and Experience Cloud have a facility in which an administrator can configure Allowed Origins.  In the example below, the Visual Builder domain is vb.oraclecloud.com, and that it is allowed to call REST APIs belonging to this Content and Experience Cloud Instance servers directly.  You should consult the documentation for the API being called to know it supports CORS.   This is one of the differences between calling a Service via Postman or SOAP UI and via VB Service connections.  You will never get a CORS pre-flight error from Postman, as you are not calling from one domain to another.  Mobile apps (native/hybrid) installed on a device are also exempt from CORS,   3. HTTPS Support Another requirement of direct calls is that they must be strictly HTTPS.  Though Visual Builder recommends HTTPS based Service connections only, for development purposes it is possible to use HTTP connections if their authentication mechanism that can be proxied.   Direct calls using HTTP will result in errors. If your external service has an HTTPS certificate that doesn’t have a fully valid CA (like a self-signed certificate), it will reject requests, results in errors.  This is a common scenario during development.   In case of direct connections, the browser will give out an error, and the resolution requires the browser to trust the certificate (import certificate into every browser where you test this app).  If the connection is via a proxy, you can import the certificate into Visual Builder.  An example scenario is shown here.   Configuring Direct/Proxy Configuring either of these two alternatives is not really a direct setting on the Service Connections, but actually a function of the selected authentication mechanism and some other bits, as shown below: * On the table below, “May have CORS issues” refers to the CORS-related scenarios explained above - i.e., when JavaScript code running on the browser makes a Rest call to a server that is not configured to allow such calls.   Service Connection Authentication settings Direct / Proxy Typical Scenario No defined authentication Direct No Authentication May have CORS issues Requires HTTPS None Proxy No Authentication Avoids CORS issues Allows HTTP Basic Proxy Basic Authentication Avoids CORS issues Allows HTTP Oracle Cloud Account, Token relay unchecked Proxy Authentication for calling services from the Service Catalog Avoids CORS issues Allows HTTP Oracle Cloud Account, Token relay checked Direct Authentication for calling services from the Service Catalog May have CORS issues Requires HTTPS Any OAuth 2.0 methods, Token relay unchecked Proxy OAuth 2.0 Authentication Avoids CORS issues Allows HTTP Any OAuth 2.0 methods, Token relay checked Direct OAuth 2.0 Authentication May have CORS issues Requires HTTPS Direct – Bypass proxy Direct No Authentication or authentication handled by the client code May have CORS issues Requires HTTPS Propagate Current User identity Direct Authentication for calling services from the from the pre-defined catalog, using the OAuth Implicit flow May have CORS issues Requires HTTPS

Service Connections are Visual Builder objects to represent REST API calls.  They are pretty much intuitive, and if you have used Postman or SOAP UI like tools to test web services, they will seem...

Oracle Visual Builder Cloud Service

Creating Progressive Web Apps with Oracle Visual Builder

Progressive Web Apps (or PWA for short) combine the advantages of on-device mobile app experience with the distribution simplicity offered by regular web applications. The latest version of Oracle Visual Builder offers a very easy way to create and distribute your PWAs in a visual cloud development environment. PWA apps can work offline, leverage device features such as access to the camera, photo gallery, and location information. The app is downloaded to the device, represented as an icon on the device list of apps, and when it is invoked you don't see a browser wrapper (no address bar and browser navigation buttons). As such the user experience of working with such application is very close to applications that you get from the app store. A key difference between PWA and on-device mobile apps is the distribution mechanism. To first "install" the application the user will navigate to a URL using their browser, this will pop-up an option for them to "add the application to home screen". Once they do this the app is now part of their "apps list" on the device. When a new version of the app is published, the end user doesn't need to go to the app store to download it. The application will automatically update on the device the next time you'll open it. Pulling the new UI from the server and caching it for future use. One more point to mention is that PWA can also install on your laptop, for example as a chrome app. This means that unlike the on-device mobile apps in VB that are limited to just iOS or Android devices, PWA apps are able to also run on windows, macs and other OSs. As you'll see in the demo video below, developing a PWA app is no different then developing regular mobile apps in Visual Builder, there is a configuration tab that allows you to turn on the PWA packaging for any mobile app. Once you do this, when you stage the app, you'll get a URL (and a QR code) that customers can access to invoke/install the app. Check out this demo A couple of notes about the app in the demo While we enabled unauthenticated access to the app, you can of course limit application access to specific users The data caching shown in the demo is the result of the REST service specifying a caching mechanism in the header. For more complete caching control and capabilities VB PWA apps can leverage the Oracle JET offline toolkit. The take a picture action also works when running on your laptop, it will open the local file selection dialog.      

Progressive Web Apps (or PWA for short) combine the advantages of on-device mobile app experience with the distribution simplicity offered by regular web applications. The latest version of...

Oracle Visual Builder Cloud Service

Conditional Formatting Row Values in a Table in Visual Builder

Color can help highlight important data in your application, calling out specific information you want the user to pay attention to. For example, if you have values that need special attention in a table of data, you might want to highlight them with a different color. Formatting an individual field is quite trivial, but when trying to do this for rows in a table you might need a bit of help. Here is the recipe: Assuming the decision of which format to show is a bit more complex than what can be represented as a simple EL, you'll want to use a pagemodule function that determine the format you want to show. Something like this:   PageModule.prototype.color = function(salary){     if (salary > 2000) {       return "red";     }     return "blue";   }    Then in your table, you'll want to have the specific field represented as a separate column template, which will then let you define the format for this field. To get this - drag and drop a Text component onto the existing field (see this "table tips" blog for a video about this approach). You'll then surround the field with a span component that you will format like this:         <template slot="Salary">         <span :style.color="{{$page.functions.color($current.data)}}">           <oj-bind-text value="[[$current.data]]">           </oj-bind-text>          </span>         </template> The result will be something like this:    

Color can help highlight important data in your application, calling out specific information you want the user to pay attention to. For example, if you have values that need special attention in a...

Oracle Visual Builder Cloud Service

Managing Visual Builder Development and Deployment Automation with Developer Cloud

The combination of Visual Builder and Oracle Developer Cloud Service (DevCS) gives your team a complete platform for managing and automating your application's development to deployment lifecycle. In the video below you can see an example development project and see how you can achieve a faster release cycle by leveraging this combination. Developer Cloud Service contains feature that include: Git version management repositories Issue tracking system with Agile dashboard to manage and track development sprint execution Merge request & peer code review system Build and deploy automation through pipelines Team collaboration tools such as an activity stream and wiki Note that Developer Cloud Service can be used to manage all your development artifacts, and is not limited to just Visual Builder apps. For example you can use the same platform to manage the REST services you create for accessing other sources of information regardless of the language they are built in. In a previous blog we showed you how to connect your Visual Builder instance to a new project in DevCS and push your code into the Git repository. Now we extend the scenario further showing the deeper integration you can have now. In the video below we look at a sample development flow of a Visual Builder team that include: Tracking issues in your application and assigning them to developers Managing code branches with Git Executing a code review process Automating build and deploy of applications Check out this powerful combination:

The combination of Visual Builder and Oracle Developer Cloud Service (DevCS) gives your team a complete platform for managing and automating your application's development to deployment lifecycle. In...

Oracle Visual Builder Cloud Service

New Features in Oracle Visual Builder - March 2019

The new version of Oracle Visual Builder released this month features several key features for developers looking to build mobile applications including support for Progressive Web Apps (PWA) development, pluggable Cordova Plug-ins, and improved device integration capabilities. This release also includes the initial release of our component exchange integration. Here is a quick rundown of the key new features released this month. PWA Packaging Progressive Web Apps (PWA) aim to merge the benefits of on-device mobile applications with the ease of distribution that web applications provide. When you create a PWA you get the benefits of on-device mobile apps such as:  native platform look and feel, icon for app invocation on the phone, device integration, and the ability to work offline. But the application doesn't need to be distributed through the app store, and when there is an update to the application, users don't need to download a new version. Instead, you provide a URL to the app and users who access the URL are given an option to add the app to their "homepage". When an update to the application is deployed, the new version will automatically download to the users phone the next time they access the app. Creating a PWA app in Visual Builder is easy, just pick up any mobile app that you created and switch the PWA enable switch on the setting tab, fill out some setup data and you are done. Now when you build your app we create the PWA packaging for you.   Custom Cordova Plug-in For on-device mobile applications Visual Builder uses a hybrid approach leveraging Apache Cordova to allow you to leverage device features. Visual Builder comes with built-in support for leveraging features such as the device's camera and location, but in some cases you might want to leverage other device capabilities.  The new pluggable Cordova plugin support will let you do just that. You can add Cordova plugins to your app and leverage them from our code. Find this under the application setting tab in the "Custom Plugins" section. (P.S. This updated functionality was actually in our February release). Take Photo Action Take photo is one of the built-in device interactions that Visual Builder offers. In the new version this action has been extended from just on-device mobile app support to work also in PWA apps as well as regular web apps. In mobile and PWA apps you'll have access to device camera and to photos in the device gallery. In web apps you'll be able to select images from your client hard-drive and upload them to the app. New Mobile App Template We added support for a new app template for your mobile apps. This one implements a collapsible left side navigation panel that allows you to navigate between flows easily without constantly occupying space on the screen. Application Optimization for Runtime A new feature in Visual Builder supports optimization of the application for runtime. Using a grunt based build job - that you can invoke as part of a Developer Cloud Service build pipeline, or on your own machine - you can optimize your application and publish it in one step. This enables you to further support a complete CI/CD flow with the combination of Visual Builder and DevCS. Oracle's Components Exchange With this release we are also releasing the first iteration of Oracle's Component Exchange - a place where we'll be publishing reusable components that you can easily add to your applications. These components are based on the Oracle JET Web Components architecture and can be further customized in your application. The exchange will also include new templates for applications. This is just the first step in our approach to helping you create and use reusable components in Visual Builder, expect more components to show up frequently, and future version are planned to also allow you to publish your own component exchange. That's Not All There are many other enhancements and additions to visual builder in this release. Read about them in the "What's New" document. Keep an eye on our blog for more detailed blog entries that will show you how to use each one of the new features. If you have any further questions, let us know on our community forum.

The new version of Oracle Visual Builder released this month features several key features for developers looking to build mobile applications including support for Progressive Web Apps (PWA)...

Oracle Visual Builder Cloud Service

Creating & Invoking Business Object Functions from Visual Builder UI

The business object layer in Visual Builder allows you to add business logic that can implement functionality on your data layer. In this blog we are going to show you how to use such a function to iterate over a set of records in a parent/child relationship, and update a set of records in a single REST call, as well as how to invoke that function from your visual builder UI. It's worth mentioning here that these functions can also be invoked from other applications that need access to your business services. Our example is a master/detail Departments/Employees scenario, where we want to build an interface that will let us update the salary of all the employees in a specific department with a bonus increase. While you can do this by calling a REST Patch operation on each employee independently, a more efficient way to do this would be to expose a single function that can update all the employees. Business Object Functions come to the rescue. We are going to define an object function that can be invoked on a specific department, accepts the bonus as a parameter, and then loops over all the employees working in this department and updates their salary with the new bonus. The groovy code for such a function is: def collection1 = Employees; while (collection1.hasNext()) {   def record1 = collection1.next();   record1.salary=record1.salary+bonus; } Note that the "Employees" in the first row is the name of the accessor that connects the two objects. In the video we show you how to define this accessor through the business object diagram in Visual Builder. We can mark this function to be "callable from external system" - which will then expose a REST endpoint on our business objects that will allow you to invoke the function from the Visual Builder pages (or other external systems). Now we are just left with the task of creating the UI to invoke this POST endpoint, passing in the needed parameters. Important note - if you want to invoke this function from outside VB you need to set the Content-Type header to application/vnd.oracle.adf.action+json . In the video below you can see how to: Create a master/detail UI - fetching employees for a specific department Add an accessor to a relationship between objects (to allow access to the employees from a specific department) Add an object function, provide parameters, and use code templates to loop over children Add an action chain that calls the REST POST endpoint passing in the parameters to the method

The business object layer in Visual Builder allows you to add business logic that can implement functionality on your data layer. In this blog we are going to show you how to use such a function...

Oracle Visual Builder Cloud Service

Navigating Between Pages and Flows

Flows are a feature in Visual Builder that can provide encapsulation that is smaller that the whole app but bigger than a page. A visual builder app has one or more root pages that define the shell and navigation for your app. These root pages load one or more flows in the main content area, and each flow has a default entry page that gets displayed when it is loaded. Flows do impose certain limitations on your app, and the most important one regards navigation. Currently the Visual Builder design time only allows you to navigate between pages inside a flow or back up to a root page. It does not allow you to navigate directly to a different flow, or to deep link to a page inside that flow. For example, if you have Customers in on flow, and Orders in another, and you want to link from a particular Order's page to the related Customer's page, you can't do it through the UI yet.  For this reason, we recommend that you put all of the related pages that need to link to each other inside a flow. Unfortunately, sometimes you can't. For example the Mobile Application template requires you to have one flow for each navigation button. The navigation pattern recommended in the Learning Path also assumes each nav link goes to a separate flow.  So let's take a look at how we can navigate from one flow to another using custom events: Download the sample for the Role-Based Security lesson, since it has the navigation bar already implemented. Import the app into VB and call it something like ExpenseReport_NavigateBetweenPages. Under the admin flow, create a new page called newpage. Add a paragraph tag to the page and change the text to "You made it!" Open main > main-start and add a hyperlink at the top of the page. Now we're ready to wire up the navigation. Open up root pages > shell. We're going to create a custom event on the shell page that will call the navigateToPage action and pass in the required parameters. Then we'll set up the hyperlink on main-start to fire this event and pass in the page it wants to navigate to. Click the Events tab and click + Event Listener. Click the + sign next to Other Events and name your event customNavEvent. Then click Select. Select navigateToPage action chain and click Finish. In the list of events, select customNavEvent > navigateToPage. In the Property Inspector, click Assign above Input Parameters. Set navigate to true and page to $event. Make sure both are set as Expression and not Static Text. Click Save. Now go back to main-start, select the hyperlink, and in the Events tab of the Property Inspector, use the quickstart to generate an action for the the click event. Drag a Fire Custom Event action onto the chain. Set the name to customNavEvent and set the payload to admin/admin-newpage. Run the app and click the hyperlink. admin/admin-newpage opens. Passing a Parameter But what about if the page we're navigating to has a mandatory input parameter? How do I pass that in when navigating via the custom event. Never fear - payload is an object so we can pass in anything we like.  Go to admin/newpage and create a new variable called name. Mark it as a required input parameter that gets passed in the URL. Change the text in your Paragraph to {{ "You made it, " + $page.variables.name }} Go back to the main-start/HyperlinkClickChain editor and click the {} Change the fireCustomEvent1 action to: "actions": { "fireCustomEvent1": { "module": "vb/action/builtin/fireCustomEventAction", "parameters": { "name": "customNavEvent", "payload": { "name": "john", "page": "admin/admin-newpage" } } } } Go to the shell page and open the Actions tab. Open the navigateToPage action chain. Click the variables tab and enter a new variable called name. Mark it as a required input parameter in the Property Inspector. Switch to the code view by clicking the {} button in the Action Chain Editor. Change the navigateToPage1 action to the following: "navigateToPage1": { "module": "vb/action/builtin/navigateToPageAction", "parameters": { "history": "push", "page": "[[ $variables.page ]]", "params": { "name": "{{ $variables.name }}" } } } Go back to the shell page and open the Events tab. Select customNavAction > navigateToPage and in the Property Inspector click the Assign link for the Input Parameters. Map name to $event.name and page to $event.page. Again, mark each as an Expression, not Static content. Run the app again. When you navigate to the page, it should say "You made it john".  

Flows are a feature in Visual Builder that can provide encapsulation that is smaller that the whole app but bigger than a page. A visual builder app has one or more root pages that define the shell...

Oracle Visual Builder Cloud Service

Debugging Visual Builder Mobile Apps on Android

Oracle Visual Builder lets you create mobile apps that install and run on your mobile device. In the development stages you can use our live emulator to see the apps running and test them. But how do you debug them once they are running on an actual mobile device? where can you find the log console to debug them? How do you get to the browser console when your app is running on a remote device? Here is the solution for Android apps (shown to me by Laura our VB Mobile PM): 1. First install the chrome ADB extension into your Chrome browser. The extension is available here. Once installed it will add a little green Android icon to your browser's menu. 2. Connect your Android device to your computer using a USB cable, and make sure that your phone is set to support USB debugging. On most devices this will be off by default, if you haven't configured your phone already you'll need to do this probably under the "Developer Options". Google and you'll find the specific steps based on your specific device. 3. In order to debug your application you'll need to configure a build profile that is set to Debug in the "Build Type" drop down. Then use that build profile to Run your application in the emulator, build it, and then deploy it to your mobile device. Once deployed with this profile you can run your app on your mobile device. 4. Now from the chrome browser click the little green Android icon, and choose View Inspection Target. You'll see a list of connected devices and running apps - including your Visual Builder mobile app. 5. Click the inspect link below it and you'll get a nice interface replicating the UI you see on the device and the browser's console. Need more tips on how to debug an app? I wrote a previous blog that covers techniques for debugging Visual Builder apps, and these techniques are still relevant for mobile apps. You'll see the same console and network tabs above for your on-device app.

Oracle Visual Builder lets you create mobile apps that install and run on your mobile device. In the development stages you can use our live emulator to see the apps running and test them. But how do...

Oracle Visual Builder Cloud Service

Introduction to Nested Flows in Oracle Visual Builder

One of the new features in the December release of Oracle Visual Builder Cloud Service is the new Nested Flows concept. Nested flows (also known as sub-flows) provide another level of encapsulation for your application. You define sub-flows inside another flow, and then you can include these flows in the pages that make up your master flow. Sub-flows are included inside your page leveraging a new flow container layout component. The idea is to allow you to break down specific functionality in your application into a unit that you can work on as an independent flow. This is quite useful in Single Page Applications, as it allows you to stay in the context of a page and still present context related information in a section of the page. It also allows a level of reusability since the same sub-flow can be included in multiple pages in the "master" flow. In the demo video below you can see the basics of creating nested flows, defining the page properties and containing area, designing the UI for the sub-flows, and adding navigation inside the sub-flows. Then we show how to add navigation from a containing page to dynamically decide which flow would be shown in the flow container area.

One of the new features in the December release of Oracle Visual Builder Cloud Service is the new Nested Flowsconcept. Nested flows (also known as sub-flows) provide another level of encapsulation for...

Oracle Visual Builder Cloud Service

Connecting VBCS to ORDS with self-signed certificates for Development

From Visual Builder 18.4.1 onwards, there is a facility for uploading trusted SSL certificates including self-signed certificates, which is normally needed during development. We have had a number of customers asking about how to use a self-signed certificate to connect to ORDS (Oracle Rest Data Services), which is a tool to create REST interfaces on top of relational data. ORDS exposes its REST APIs over an IP address, and when ORDS is installed, it simply creates a self-signed certificate for localhost.  This will not be trusted by Visual Builder when one tries to build a Service Connection to an ORDS API.  You might get an error like the one below:   If you have an ORDS URL like https://<IPAddress>/ords/pdb1/myworkspace/myhandler/my_ords_service, and are looking for a quick way to use the Service in VBCS with a self-signed certificate, here are steps that you might find handy.  However a bit of caution - these steps involve self-signed certificates in VB and only should be used in case of development not production!   Step 1 – Get the hostname for ORDS First find the ‘proper’ hostname for your ORDS IP address using the below: nslookup <ip address> This will give you the proper hostname to use for your service connections.  So instead of https://<IP address> use https://<hostname> Step 2 – Generate a self-signed certificate Create a self-signed certificate with openssl utility the above hostname as the CName and modify other attributes according to your need For e.g. openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj '/CN=<hostname>' This will yield two files key.pem and cert.pem Convert the key.pem to its der file as below: openssl pkcs8 -topk8 -inform PEM -outform DER -in key.pem -out key.der -nocrypt Similarly convert cert.pem to its crt file   openssl x509 -outform der -in cert.pem -out cert.crt Once you have these two, they need to be updated in the ORDS standalone.properties (More details can be found in the ORDS documentation) ssl.cert=/u01/app/oracle/product/ords/cert.crt ssl.cert.key=/u01/app/oracle/product/ords/key.der ssl.host=<hostname> Restart the ORDS server after making these changes. Step 3 – Upload the self-signed certificate to VB Go to Visual Builder -> Certificates (You require administrator privileges to do this).  Upload the cert.pem (or cert.crt) giving some alias.    Step 4 – Create the Service Connection Create the service connection in Visual Builder for the ORDS endpoint as you would create normally by using "Define by Endpoint" flow but remember to give the URL with the hostname instead of the IP address i.e. https://<hostname>/ords/pdb1/myworkspace/myhandler/my_ords_service.  (A detailed tutorial for creating and consuming  Service Connections is available here)   The Service Connection should now work.  Do remember that we have made Visual Builder trust all requests signed via this certificate, so it is imperative to keep this key secure, and as a best practice, never use self-signed certificates in production. EDIT : Corrected the command to convert to key.der          

From Visual Builder 18.4.1 onwards, there is a facility for uploading trusted SSL certificates including self-signed certificates, which is normally needed during development. We have had a number of...

Oracle Visual Builder Cloud Service

Editable Tables in Visual Builder - The Oracle JET 6 Way

A while back I blogged a solution to creating editable tables in Oracle Visual Builder, that was based on the approach that was used in the Oracle JET 5 cookbook - using a row template that you switch to show an editable version of each row. Now that Visual Builder 18.4.5 got released, we support using Oracle JET 6 in your application, and this provides a simpler way to create these type of editable tables with a column template. In the video below I show you how to leverage this approach, which also results in elimination of coding any JavaScript code. As you'll see you simply drag new UI components onto the column in the table that you want to edit. Then you make sure they point to the right values, and that they allow you to edit the value in them. Then when your table is in editMode you can simply edit the data using different types of input UI components. In the demo I also show how to add a save button that will save the data into your backend. As I mention in the video, the save approach I use is not the most efficient one. You would get better performance if you'll only save records you changed, and if you'll leverage the ability of the business objects in Visual Builder to execute multiple transactions in one go. In any case - this demo should get you started on your way to having editable tables: If you need more info on how to create the type and variables shown at the beginning of the video - check my previous blog entry on editable tables.    

A while back I blogged a solution to creating editable tables in Oracle Visual Builder, that was based on the approach that was used in the Oracle JET 5 cookbook - using a row template that you...

Oracle Visual Builder Cloud Service

New Features in Oracle Visual Builder December Release

We are happy to announce the December 2018 release of Oracle Visual Builder (known as 18.4.5). This version adds several key new features, and in addition implements many enhancements to the overall development experience in Oracle's high-productivity JavaScript development platform. Here are some of the new features you can now leverage: Integration Cloud Service Catalog If you are using Oracle Integration Cloud to connect and access data from various sources, Visual Builder now makes it even simpler to leverage those integrations. The new integrations service catalog will list integrations that are defined in your Oracle Integration Cloud, and allow you to add them as sources of data and operation easily to your VB application. This is a nice addition to the existing Oracle SaaS service catalog already available in Oracle VB. iPad/Tablet Support for Mobile Apps We extended our mobile packaging capabilities to support specific packaging for iPads in addition to iPhones. In addition, in the UI emulator VB now supports an iPad/Tablet size preview as another option in the screen sizes menu. Nested Flows To help you further encapsulate flows, Visual Builder now supports the concept of nested flows. Nested flows allow you to create sub-flows that are contained inside another flow and can be used by various pages in that "master" flow. These sub-flows are then embedded into a flow-container region on a page. At runtime you can switch the sub-flow that is shown in such a region giving you a more dynamic interface. This encapsulation also helps with scenarios of multiple developers that need to work on various sections of an application - eliminating potential conflicts. Visual Builder Add In for Excel Sometimes neither web nor mobile are the right UI for your customer, maybe they want to work with your data directly from spreadsheets - well now they can. With the Visual Builder Add in for Excel plug-in you can directly access Business Objects you created in Visual Builder from Excel spreadsheet and query and manipulate the data. The plug-in gives you a complete development environment embedded in Excel to create interactions with your business objects. JET 6 Support Visual Builder now supports the latest Oracle JET 6.0 set of components and capabilities. This applies for both design-time and run-time. Note that existing applications will continue to use their current JET version, unless you open them with the new version to do modifications - when you do open them, we'll automatically upgrade them to use JET 6. Vanity URL Visual Builder lets you define a specific URL that will be used for your published web applications. This means that if you own the URL to www.yourname.com for example - you can specify that your apps will show up using this URL. Check out the application settings for more information on this capability. But Wait There's More... There are many many other enhancements in every area of Oracle Visual Builder - you can read about them in our what's new book, or even better - just try out Visual Builder and experience it on your own!    

We are happy to announce the December 2018 release of Oracle Visual Builder (known as 18.4.5). This version adds several key new features, and in addition implements many enhancements to the overall...

Oracle Visual Builder Cloud Service

3 Tips for Using Imported Javascript with Visual Builder

In a previous article, I discussed how to import and use Javascript libraries. This has been a popular article and as such has generated a bunch of questions. In this article I am going to provide 3 tips that should address those questions and make it super easy to regularly import and use Javascript within your Visual Builder app.  1) Place your imported Javascript in the resources folder When you import your Javascript file, you select the folder for install at the time of import. In the previous article, I had imported the file into a flows folder and as such I had used a absolute path from the root of the instance to provide the location of the file. However, if you import into the resources folder you can now just reference your file by prepending "resources/" to the name of the JS file (you don't need the .js extension).   2) Use Code Insight to find the path the file Even better, you can use Code Insight to help you find the file. You invoke Code Insight with the Ctrl + Space bar. If you invoke Code Insight within the "" of the define in your custom code module you will see a Select URL... option pop up. Double click that menu option and you be presented with a empty text box to start typing the name of your file. Select the filename when it is found and hit Enter. The path will be added automatically for you and it will also remove the .js extension for you.   Don't forget to name your import in the function() of the require syntax. This is the name you will use to access your imported functions from that file. I named mine "importedjs" and as shown in the below code example I access my function using that scope - importedjs.callExternalAction define(["resources/importedjs"], function(importedjs) {   'use strict';   var PageModule = function PageModule() {};      PageModule.prototype.callImportedJSFunction = function(param)   {     return importedjs.callExternalAction(param);   }   return PageModule; }); 3) Export your custom code using AMD export syntax The last tip is the most important as I have received this question numerous times. If you are using 3rd party libraries, they likely already export their functions correctly. However if you are creating your own functions file, you need to export your functions using the AMD format. In this case AMD doesn't stand for Advanced Micro Devices but rather Asynchronous Module Definition (see Feature Image for this article). There is plenty of good material that describes the ins and outs of AMD format but I will use a simple example for this article with code shown below.  define([], function() { var exports = {}; function callExternalAction(param) {    return 'Processed value from external js: ' + param;  }; exports.callExternalAction = callExternalAction; return exports; }); The code above is setting up function(s) for export and assigning them to exported symbols. These are the names you will see when you use Code Insight on that filename as shown below. This is the basics of exporting in AMD format so if you follow this example you should be good to go.  You can download an example project at my GitHub. 

In a previous article, I discussed how to import and use Javascript libraries. This has been a popular article and as such has generated a bunch of questions. In this article I am going to provide 3...

Advanced Business Object Validation with Groovy

One of the powerful aspects of  Visual Builder's business objects is the ability to leverage Groovy code to implement complex logic for them. You can leverage Groovy in triggers, validators, and object functions - all residing under the "Business Rules" tab in Visual Builder design time. Groovy is quite a simple language, but when coding with the business objects in VB it is helpful to be aware of some unique methods that you can leverage to manipulate your business objects. We now have a book that provide a reference for Groovy usage in Visual Builder - check out the "Groovy Scripting Reference". One section that is specifically useful is the one titled "Accessing the View Object for Programmatic Access to Business Objects" as it shows you how to work with the data in a business object. Here is an example of how this can be useful. Example Suppose that we have a business object called Emp with two fields in it - name and salary. We want to verify that there are no records that have the exact same values for both name and salary. To do this we can add an object level validator (we called it checkUnique):   In this validator we add a piece of groovy code that will try and fetch existing records that have the same values as the current record we are working on (adding or modifying the record). The code needs to return true if the changes/addition are ok, and false if we want to fail the validation. The code used in our example is: def vo = newView('Emp'); vo.appendViewCriteria("name ='"+name+"' and salary = "+salary); vo.executeQuery(); def cnt = 0 while (vo.hasNext()) { vo.next() cnt = cnt + 1 } if (cnt > 1) { return false } else { return true } In line 1 we create a new instance of a view for the Emp object. In line 2 we add a criteria to the view, and in it we use the values from the current record for name and salary. Note that in the condition we use ' to surround character values. In line 3 we execute a query with this condition. In the rest of the code we are counting how many records are returned - and if it is more than 1 record we fail the validation. That's it - quite simple but powerful. P.S. If you are planning to do groovy coding, you'll want to quickly review the tips I provided in this blog entry on debugging the code using the log window in Visual Builder.    

One of the powerful aspects of  Visual Builder's business objects is the ability to leverage Groovy code to implement complex logic for them. You can leverage Groovy in triggers, validators, and...

Oracle Visual Builder Cloud Service

Managing Aggregation for Business Objects with Triggers

If you have data stored in business objects in Visual Builder you might want to present some information that requires aggregating data from multiple records. For example, if you have a list of employees and their salary, you might want to know the total number of employees and the total of the salaries. If you have a parent/child relationship you can do these type of calculations using the aggregated field functionality. For example if you have a departments table and each employee belongs to one department you can do the department level totals using aggregated fields. (You can see how to define this type of fields in this video around minute 3:45). Doing aggregations when there is no direct parent/child relationship is a bit trickier. Below I'm going to show you an approach to handling this using triggers on business objects that keep your totals always up to date. Note that one advantage of this approach is that the totals are not calculated on the fly each time you query them - rather they are kept already calculated in a dedicated business object. In the sample, I created a business object specifically for this tracking called "stats". This business objects has one record that contains the totals I need to track. I then use triggers to catch insert/update/delete operations on the employee object and update the stats object accordingly. As you'll see, we needed to resort to a bit of Groovy coding to achieve this type of updates to none related objects. You can get the base groovy code needed to update an object and a field in it by looking at the code that the visual "update record" operation creates. You can then modify this code to the exact logic you require. In the video you'll also see how you can access not just the current value of a field but also the old value of that field using the getOriginalAttributeValue(‘fieldName’)  groovy function. The code used in my update trigger is: def view1 = newView('Stats'); while (view1.hasNext()) { record1 = view1.next(); record1.totalSalary = { record1.totalSalary+salary-getOriginalAttributeValue('salary'); }.call(); } Note that in the video I didn't add the trigger for a delete event - but you can easily add this and simply have the following code in there: def view1 = newView('Stats'); while (view1.hasNext()) { record1 = view1.next(); record1.totalSalary = { record1.totalSalary-salary }.call(); record1.empCount = { record1.empCount-1 }.call(); }

If you have data stored in business objects in Visual Builder you might want to present some information that requires aggregating data from multiple records. For example, if you have a list of...

Oracle Visual Builder Cloud Service

Adding Off Canvas Layout to a Visual Builder Application

Off Canvas layout is a common UI pattern for modern applications, especially on mobile devices. The concept is aimed at saving space on your page, allowing you to pop out a "drawer" of additional information. This helps reduce clatter on the main page but still provide access to important data when needed without leaving the page context. You can see an example of the runtime behavior at the top of this post.  Oracle JET provides this type of "off-canvas" behavior as a built in component, and they have a demo of it working as part of the cookbook here. In the video below I show you how to add this to a Visual Builder application. As always - you can mostly just copy and paste code from the JET cookbook, but you need to handle some of the importing of resources a little different, and use the Visual Builder approach for adding your JavaScript function. The code used in the video is: Page source: <div class="oj-offcanvas-outer-wrapper">   <div class="oj-offcanvas-start oj-panel oj-panel-alt5 oj-offcanvas-overlay-shadow"     id="startDrawer" style="width: 200px">     <div class="oj-flex">       <h2 class="oj-flex-item oj-sm-12 oj-md-12" id="h1-1660298733-2">Menu</h2>     </div>     <div class="oj-flex">       <oj-label class="oj-flex-item oj-sm-12 oj-md-3" id="oj-label-1660298733-1">List</oj-label>     </div>     <div class="oj-flex">       <oj-label class="oj-flex-item oj-sm-12 oj-md-3" id="oj-label-1660298733-2">chart</oj-label>     </div>   </div>   <div class="demo-main-content" id="mainContent">     <div class="oj-flex">       <h2 class="oj-flex-item oj-sm-12 oj-md-10" id="h1-1660298733-1">Gifts</h2>     </div>     <div class="oj-flex">       <hr class="oj-flex-item oj-sm-12 oj-md-12" id="hr-1660298733-1" />     </div>     <div class="oj-flex">       <oj-list-view class="oj-flex-item oj-sm-12 oj-md-12" data="[[$page.variables.giftsListSDP]]"         id="oj-list-view-1660298733-1"> <template slot="itemTemplate"> <oj-vb-list-item> <img :src="[[$current.data.picture]]" height="32" slot="image" width="32" /> <p slot="title1"><oj-bind-text value="[[$current.data.product]]"></oj-bind-text></p> <p slot="value1"><oj-bind-text value="[[$current.data.cost]]"></oj-bind-text></p> <p slot="title2"><oj-bind-text value="[[$current.data.sKU]]"></oj-bind-text></p> </oj-vb-list-item> </template> </oj-list-view>     </div>   </div> </div> JavaScript Function in the page: define(['ojs/ojcore'], function(oj) { 'use strict'; var PageModule = function PageModule() {}; PageModule.prototype.showSide = function() { var offcanvas = { "selector": "#startDrawer", "content": "#mainContent", "edge": "start", "displayMode": "push", "size": "200px" }; oj.OffcanvasUtils.open(offcanvas); } return PageModule; }); and in your page Json file add this import: "oj-offCanvas": { "path": "ojs/ojoffcanvas" }

Off Canvas layout is a common UI pattern for modern applications, especially on mobile devices. The concept is aimed at saving space on your page, allowing you to pop out a "drawer" of additional...

Oracle Visual Builder Cloud Service

Debugging and Troubleshooting Visual Builder Logic

In every development cycle, developers are going to run into situations where things are not working as expected - this is where the debugging step comes into play. Oracle Visual Builder Cloud Service  uses a multi-tier architecture - so it is likely that you'll end up with the need to debug code in each one of the layers. In this short demo we give you some tips on how to debug your applications. At its core, VBCS is a web UI tool, so for most of the UI layer debugging you are going to rely on the development tools offered to your by your browser. In the video below I'm using the Chrome browser and its development tools - but similar tools exists in other browsers too. These tools allow you to see the network traffic between your client's browser and the REST sources of data. They also provide a console that shows you error messages and notifications sent from your application. One of the things we added to VBCS is a verbose mode of output that gives you full details on what's going on in your app at every step. Another layer that you might need to debug is the business object layer that exposes the REST services. If you are developing your business objects using VBCS, then you can use the built in logging mechanism for those. In the demonstration video below you'll see how to: Monitor REST calls Show notifications with variable values in the UI Track activity and variable values in the console Log messages in the console from custom JavaScript code - with console.log() Log messages from Groovy code in your business objects - with println() Track the log of your business object layer With these tools, understanding what is happening in your application should be quite easy - and fixing errors simpler. If you are still running into problems or questions with your development process - try posting on our VBCS community forum and some of your peers might be able to help.

In every development cycle, developers are going to run into situations where things are not working as expected - this is where the debugging step comes into play. Oracle Visual Builder Cloud Service...

Advanced Capabilities for the Table Components in Visual Builder - Tips

In this blog we'll show you how to turn-on some more advanced capabilities in table components you add to your web pages in Visual Builder Cloud Service. Specifically we'll cover, column content formatting, column resizing & reordering, line wrapping, scroll policies, and adding more columns. One thing that is worth mentioning first is that our UI gurus are not fans of tables. In general, they would recommend you'll use the list component to show collections of records. It's not just us, if you look at the UI of your facebook, twitter, instagram and even amazon product search results - all of those are not displayed as table - they show up as lists. So before you go down the table route - consider whether using lists will get you the functionality you need. If you picked up a table component, then after you used the initial quick start to bind data to it, there are a set of table and column attributes that you can use to add functionality to your table. See the following video to learn how to: Turn on Grid look and feel Reformat columns content to show in different ways (dates, pictures, gauges) Turn on column drag-and-drop reordering  Allow resizing columns Line-wrap long content in a column Control fetch size and data loading Add missing columns after you already ran the quick start Add row level actions  In the video I'm using the following values for the following attributes: Attribute Value column style white-space:normal column resizable enabled table scroll-policy-options {"fetchSize":3}   You can learn more about the table components in the JET cookbook section for the table component. And if you are interested in even more advanced capabilities you might want to check out this blog about creating editable tables in VBCS.

In this blog we'll show you how to turn-on some more advanced capabilities in table components you add to your web pages in Visual Builder Cloud Service. Specifically we'll cover, column content...

Oracle Visual Builder Cloud Service

Integrating Chatbots into VBCS Applications

Chatbots are integrated into VBCS using the Chatbot Web SDK. The hardest part is that you need to "configure" the SDK libraries to hardcode the URL of where the libraries will be deployed into the library JavaScript itself. This means you can't just add the libraries to the /resources directory of your application, since that URL changes depending on whether the application is in development, staging, or live mode. You also can't add it to another VB project, since its /resources directories are generated into randomly named directories when they are published. You therefore need to configure and stage your SDK to some other external location then point to it from the VBCS pro Note that there is no HTML component for the chatbot that you drag and drop from the component palette. You just add the JavaScript to the pages where you want the chatbot to appear and the libraries inject the elements into the DOM at runtime. Creating a Channel for the Bot We won't get into how to create a bot here. There are plenty of resources on that. Once it's created, you need to create a web channel for the bot. Open the chatbot in your Mobile Cloud/Digital Assistant UI Click the Settings tab on the left. Click Channels at the top and click New Channel Name the channel, set the type to Web Channel, and make it enabled. Copy the App Id property for the channel. Configuring and Staging the Chatbot Web SDK Download the OMCe Bots Client SDK for JavaScript from OTN and unzip it in a directory. Follow the instructions in the readme to configure and host it on a publicly available location. Embedding the Chatbot in Your Application Like we said, there is no HTML code or CCA to drop into a page. Instead you add the JavaScript to the PageModule and AppModule Javascript for your app. If you wanted the chatbot to only be available in one flow of your application, you would add the code to the FlowModule instead of the AppModule. Create an application called ChatbotClient and in that Web App called i.e. FlowerStore. (My chatbot allows you to order flowers; that's why I called it FlowerStore.) Open the application editor of FlowerStore by clicking the top-level FlowerStore node in the Web Apps tab. Open the JS tab of the editor and enter the following code in the the AppModule function - Make sure to replace XXX at the last line with your actual bot-sdk project URL: define([], function() { 'use strict'; var AppModule = function AppModule() { ! function(e, t, n, r) { function s() { try { var e; if ((e = "string" == typeof this.response ? JSON.parse(this.response) : this.response).url) { var n = t.getElementsByTagName("script")[0], r = t.createElement("script"); r.async = !0, r.src = e.url, n.parentNode.insertBefore(r, n) } } catch (e) {} } var o, p, a, i = [], c = []; e[n] = { init: function() { o = arguments; var e = { then: function(t) { return c.push({ type: "t", next: t }), e }, catch: function(t) { return c.push({ type: "c", next: t }), e } }; return e }, on: function() { i.push(arguments) }, render: function() { p = arguments }, destroy: function() { a = arguments } }, e.__onWebMessengerHostReady__ = function(t) { if (delete e.__onWebMessengerHostReady__, e[n] = t, o) for (var r = t.init.apply(t, o), s = 0; s < c.length; s++) { var u = c[s]; r = "t" === u.type ? r.then(u.next) : r.catch(u.next) } p && t.render.apply(t, p), a && t.destroy.apply(t, a); for (s = 0; s < i.length; s++) t.on.apply(t, i[s]) }; var u = new XMLHttpRequest; u.addEventListener("load", s), u.open("GET", r + "/loader.json", !0), u.responseType = "json", u.send() }(window, document, "Bots", "XXX"); }; return AppModule; }); Open the page editor for main-start. Open the JS tab of the editor and enter the following code in the PageModule function, replacing your-app-id with the App Id of your bot: define([], function() { 'use strict'; var PageModule = function PageModule() { Bots.init({ appId: 'your-app-id' }); }; return PageModule; }); Run your app and click the chatbot icon that appears on the page.  

Chatbots are integrated into VBCS using the Chatbot Web SDK. The hardest part is that you need to "configure" the SDK libraries to hardcode the URL of where the libraries will be deployed into...

Multi-Language Translations and Locale Switching in Visual Builder Applications

Oracle Visual Builder Cloud Service enables you to build applications that supports multiple languages - with an easy way to extract hard-coded strings in your app into a file that can be translated into other languages. This enables you to use the same running app to serve customers working in multiple languages. In the demo video below we'll show you some of the key features you'll be using to make your application multilingual. Replacing hard-coded strings with pointers to the translatable source Exporting and importing arb translation files Setting the default locale of your application in the app-flow.json file Dynamically switching locale at runtime (and storing the locale on the client for future use). One correction to the video - instead of passing the locale as just "en" you should pass a complete locale with the country too - so en-US or he-IL. In the video I'm using two pieces of code (that I got from Duncan Mills) : Adding the following to the app-flow.json file to define localization: "localization": { "locale": "{{ window.localStorage.getItem('vbcs.languageSwitcherApplication.locale') || 'en' }}" } A JavaScript method used to set the variable we keep on the machine to store default locale: PageModule.prototype.setAppLanguage = function(selectedLocale){ if (selectedLocale) { window.localStorage.setItem('vbcs.languageSwitcherApplication.locale',selectedLocale); } } By the way, VBCS (and Oracle JET) also supports right-to-left languages - so for example if you add translations to Hebrew and add a button that sets the locale variable to "he" you'll get Hebrew titles. But you'll need to do one more switch which is to modify the index.html file to have dir="rtl" add to the HTML tag. Then you can get the same app to looks like this:  

Oracle Visual Builder Cloud Service enables you to build applications that supports multiple languages - with an easy way to extract hard-coded strings in your app into a file that can be translated...

Defining Multiple REST End Points in Visual Builder - A Best Practice

Visual Builder Cloud Service makes it very easy to add REST services to your application - through the "new service connection" wizard you specify the URL to any REST service and a new entry is created for you. However, here is a small tip that will make your application management and performance better when you are leveraging multiple services from the same source - gather them into a single service. A service connection in VBCS can have multiple end-point defined in it. If you just run through the wizard for adding a service - each end point will create a new service definition. The best practice is to add new endpoint definition into the same service definition when possible.  Let's work through an example: We'll use a set of services about countries available here:  https://restcountries.eu/#api-endpoints-code You'll see for example these services there: https://restcountries.eu/rest/v2/name/{name}?fullText=true https://restcountries.eu/rest/v2/alpha/{code} The right way to add both to your project is: 1. Use the "Create Service" wizard to add the first end point: Going through the wizard will end up with a place for you to define the specific end point: And once you finish this section of the wizard your service will have one end point defined: Notice that in this page there is a big blue button "+Endpoint" - and you should click that one to add the next service/endpoint: Which will bring you into a similar flow for defining the second end point: That's it quite simple - now you have a single service definition with multiple end-points. One of the advantages of this approach is that if your source server changes an address - you just have one point to update, and this will take care of all the end points. Another advantage is runtime performances - VBCS doesn't need to upload and parse multiple service defintions - rather it does it only once, and leverages the information for all the end points.    

Visual Builder Cloud Service makes it very easy to add REST services to your application - through the "new service connection" wizard you specify the URL to any REST service and a new entry...

Creating Editable Tables in Oracle Visual Builder Cloud Service

[Note - since publishing this entry, Visual Builder upgraded to use JET 6 which makes creating editables simpler - check out the new approach here.] A common request I've been getting from customers of Visual Builder is to be able to edit multiple records that are shown in a table. Oracle JET has an editable table sample that shows how to do this in their cookbook, but the translation from the JET approach to the VBCS way of doing things was a bit tricky for some. I recorded a video and included basic instructions showing you how to implement the JET sample in your VBCS application below.  Beyond just implementing the UI aspect of the editable table, you also need to define a strategy of when and how you want to save the data from the table back to the data source. In the video below I'm using an approach that is easy to implement, but is probably not the best way to implement this. I loop through all the records and update them back to the data source one-by-one. A better approach will be to keep a list of rows that were changed and only send them to be updated. Also - I'm using a button that saves the data all at once, you can alternatively use other events in the UI to save individual records - for example - maybe you'll want to save the data immediately when someone leaves a field. The point is that this demo is not a "Best practice" but rather an explanation of the basic mechanisms - you should adopt it to your use case. After this long intro, lets get into the details of what you need to do and what the video shows: Creating ArrayDataProvider variable (0:50) Populating the Array on page load with data (1:55) Basing a table on an ArrayDataProvider (3:15) How to add columns in a declarative way Adding row templates to the page - one for read and one for update row (4:04) Also shows how to manually add JET components to the page's definition Adding a function to decide which row template to show (5:55) Show how to add references to JQuery and Knockout to the function Show how to modify the function definition to be regular pagemodule function Adding a save operation (8:44) & Using a for loop in an action flow  I use the $current.index value to get to the right variable   As you can see - at the end of the day this is not too complex. It is also just scratching the surface of what you can do with the table - as the JET sample shows you can have different field types, validators and more. Some code from the sample I created: Page HTML source   Celebrities Save Page JavaScript define(['ojs/ojcore', 'knockout', 'jquery'], function(oj, ko, $) { 'use strict'; var PageModule = function PageModule() { var self = this; self._editRowRenderer = oj.KnockoutTemplateUtils.getRenderer( 'editRowTemplate', true); self._navRowRenderer = oj.KnockoutTemplateUtils.getRenderer( 'rowTemplate', true); PageModule.prototype.rowRenderer = function(context) { var mode = context['rowContext']['mode']; var renderer; if (mode === 'edit') { self._editRowRenderer(context); } else if (mode === 'navigation') { self._navRowRenderer(context); } }; }; return PageModule; });

[Note - since publishing this entry, Visual Builder upgraded to use JET 6 which makes creating editables simpler - check out the new approach here.] A common request I've been getting from customers...

Oracle Visual Builder Cloud Service

Processes in VBCS Applications - Adding Task Buttons to a Business Object Edit Page

This blog is part of the series Visual Builder Cloud Service Learning Path. In a previous lesson, we designed the process we will use in our application. If you don't have it, you can download the process and the VBCS application and import them into your environments. We assume that you've named the process Expense Approvals and have already started the process in Test mode as described in the first chapter. In this chapter, we will add buttons to the bottom of the page for each of the task actions that are available to the current user for the current expense report record.  Getting the List of Tasks The first thing we will do is add an action to the loadExpenseReport action chain that fetches the list of tasks for processDefId that is stored with this Expense Report record. We will use a Type from Endpoint to create a type and variable that match the REST payload response for storing the information in the page's model. When designing this functionality, it's best to load a record in the Page Designer that has current tasks. To do this, create a new Expense Report (this will also launch an ExpenseApproval process), then edit this record in the Page Designer by switching to Live Mode and clicking it in either the list of Expense Reports or the Task List. With EditExpenseReport open in the Page Designer, click the Variables tab. Then click Types.  Click the button to add a new type from endpoint. Select Process Objects > tasks > GET tasks and click Next. Select the top-level Response to select the entire response. You can omit the []links if you like. Click Finish. Switch the Variables tab. Add a new variable called tasks of type getTaskCollection. Switch to the Actions panel and open loadExpenseReportChain. Drag a Get Task Collection action under Assign Variables expenseReportRecord. In the Property Inspector, click alias under Input Parameters.  Enter "ExpenseApproval" for the alias. Map Page > expenseReportRecord > processDefId on the left to processInstanceId on the right. Click Save. Drag an AssignVariables action below the Get Task Collection. In the Property Inspector, click Assign next to Variables. Map getTaskCollection1 > content on the left to Page > tasks on the right.  Close the action chain editor tab. Adding the Task Buttons To dynamically bind the buttons, we're going to do the following: Add an oj-bind-if that checks that the number of tasks is greater than zero. We're going to assume that the user will always only have one task assigned and so just hard-code the first result in the array of tasks that the REST service returns. Add a for-each loop to loop over all of the tasks. We will filter out system tasks Add a button in the template of the for-each loop for performing the task. Note that for the sake of simplicity we're leaving out some things we'd probably want to do, like save the record before executing the task. Switch back to the Page Designer for the EditExpenseReport page. Drop an If component in the toolbar next to the Save and Cancel buttons. In the Property Inspector, set Test to [[ $page.variables.tasks.items.length > 0]] Drop a For Each component inside the Bind-If component. Note it may be easier for you to select the right drop target by dragging and dropping into the Structure pane rather than into the Page Designer. In the Property Inspector, set Data to [[$page.variables.tasks.items[0].actions.filter(a => a.type === 'Custom')]] and As to task. Switch to the Source View and manually enter an oj-button in the template for the oj-bind-for-each element. (A bug prevents you from dropping the button using the Design view.) Switch back to the Design view. In the Page Structure view select the button so that you can see its properties in the Property Inspector. In the Property Inspector, set the Text to {{task.data.label}} Still with the Button selected, open the Events tab of the Property Inspector and click New Event -> Quick Start: 'click'. The tab with the new action chain opens. But before we can configure the action chain, we have to configure our input variables to hold the information we need. In the Action Chain editor, switch to the Variables view and create two string variables named actionId and taskId. Mark both as input variables in the Property Inspector Now let's pass in the info from the button as part of the click event. Open the EditExpenseReport page again, click the Events tab, and select the button click action that you generated with the quickstart. In the Property Inspector, click Assign for the Input Parameters. Map actionId to {{ $current.data.id }} and taskId to {{ $current.data.taskId }}. Click Save. Go back to the action chain editor for the ButtonClickAction1 and drop a Perform Task action onto the action chain. In the Property Inspector for the Perform Task action, click Assign for Parameters. Assign actionId on the left to id on the right. Assign taskId on the left to taskId on the right. Click Save. Drop a Navigate action under the Perform Task action. In the Property Inspector, click Select Target > Peer Page > main-start. Test the application by creating a new expense report, checking for the Approve task in the task list, then going to its Edit screen and performing the action with the buttons.  

This blog is part of the series Visual Builder Cloud Service Learning Path. In a previous lesson, we designed the process we will use in our application. If you don't have it, you can download the...

Oracle Visual Builder Cloud Service

Processes in VBCS Applications - Adding a Task List

This blog is part of the series Visual Builder Cloud Service Learning Path. In a previous lesson, we designed the process we will use in our application. If you don't have it, you can download the process and the VBCS application and import them into your environments. We assume that you've named the process Expense Approvals and have already started the process in Test mode as described in the first chapter. In this chapter, we will add a Task List that shows all of the currently active tasks for the logged in user. VBCS contains a quickstart to populate a table with a list of tasks for the current user and drop-down of available actions for each given task. The tricky part is hooking up the task list to the correctly list information from the business object, like the expense request name, and to link to the correct Edit page for the business object record. We do this by storing the information we pass into the PCS business object in the properties of the tasks. Configuring Tasks to Propagate Business Data We're going to highjack some of the standard properties of the tasks to pass business object informaiton.  (Note, in an upcoming release of PCS you'll be able to get fetch any PCS business object field with the list of tasks.) In PCS, open the ExpenseApproval process in the editor. Select the Approve Request task. Then click the menu icon and select Data Association. Map name and id from ExpenseApproval > Data Object > expenseReport on the left to title and longSummary from execData on the right. Then click Apply. Do the same for the Resubmit action. Save, publish, and test the process.  Adding the Task List to the Application We will add the task list by just dropping a table in the mytasks page and hooking it up to a ProcessDataProvider. Then we'll use the quickstart to add the Task Actions buttons. In VBCS, open the Web Apps tab and click the mytasks page to open it in the Editor. Drop a table component on the page.  In the Property Inspector for the table, choose the quickstarts tab and click Add Data. Choose Process Objects > task > GET tasks as the endpoint and click Next. Select the following columns:  label creationDate creationUser state Expand the query parameters and select the alias parameter. In the field at the bottom of the editor, type in "ExpenseApproval". Make sure to include the quotation marks. Click Finish. Preview the application and create a few records. Your task list table will look something like this: Select the table in the Page Designer and switch to the Data tab in the Property Inspector. Reorder and rename the columns so that they say: Expense Report Created By  Created On  Status Drag and drop an Input Date component onto the Created On column in the Page Designer. The display switches to correctly display as a date. Linking a Task to an Edit Page Now we'll link the values in the Expense Report column to the correct Edit page for the expense report record. In the Page Designer, drag and drop a Hyperlink component onto the Expense Report column in the table. The values turn into links. Click any of the column hyperlinks to select them in the Property Inspector. In the Events tab click New Event > Quick Start: 'click'. Before you can hook up the action chain, we have to pass in the ID of the expense report. Remember in PCS we mapped that into the longSummary field of the tasks. The REST call to the GET /tasks returns a payload with a field called description, which contains the longSummary field from the task. Go back to the my-tasks page and click the Events tab. In the Property Inspector, click key under Input Parameters. Select the key parameter in the right side of the dialog. In the field at the bottom of the type in $current.row.description. Click Save. Switch back to the HyperlinkClickAction tab. If you've closed it, you can find it in the Actions tab of the mytasks page. Drag a Navigate action onto the action chain. Click Select Target > Peer Page > EditExpenseReport. In the Property Inspector, click expenseReportId under Input Parameters. Map key to expenseReportId and click Save. Preview the mytasks page again. Click any of the links in the task list. The application navigates to the correct page. Adding a Task Actions Button Select the task list table in the Page Designer.  Open the Quick Starts panel of the Property Inspector and click Add Task Actions. Accept the default information and click OK. The Task Actions button is added above the list of tasks. Preview the page and select any task, then open the menu to choose from a list of actions to perform on the task. In the next section, we look at how to add Task buttons to the Edit page itself.

This blog is part of the series Visual Builder Cloud Service Learning Path. In a previous lesson, we designed the process we will use in our application. If you don't have it, you can download the...

Processes in VBCS Applications - Starting a Process from a VBCS Application

This blog is part of the series Visual Builder Cloud Service Learning Path. In the previous lesson, we designed the process we will use in our application. If you don't have it, you can download the process and the VBCS application and import them into your environments. We assume that you've named the process Expense Approvals and have already started the process in Test mode as described in the last chapter. In this tutorial, we'll look at how to start a process from our ExpenseReport VBCS application and pass in the required information as part of the REST call. This entails the following steps: Registering an Alias for the process in VBCS. This will allow us to reference the process without having to make changes to our code when we publish our application. Calling the Start Process REST API passing in the info that we marked as required on the Start message in the process. PCS needs to know the version and mode of the application so that it can correctly configure the REST URL to call back into VBCS business object REST endpoints. It also needs to have the name and id of the expense report item so we can correctly configure the Task List in VBCS. Storing the identifier of the the process we started back in the VBCS business object. This is so we can associate a specific expense report record with the correct instance of the approval process and show the right tasks for that record when we view its Edit screen. Registering the Process Alias In the Expense Report application in VBCS, click the Processes tab on the left. Then click the + sign at the top of the Processes tab. Select ExpenseApproval in the list, click Add, then click Close. If it doesn't appear, make sure Include test instances in selected and you have activated the process in Test mode in PCS as described in the last chapter. If it still doesn't show, try refreshing VBCS and opening the Register Deployed Process window again. Editing the CreateExpenseReport Action Chain to Start the Process Now we need to edit the create expense report action chain to do the following: Save the Expense Report record Save the record in a temporary action chain variable Call the Start Process REST endpoint, passing in the required attributes Store the processInstanceId from the response to the Start Process call into our temporary variable Call the PATCH REST endpoint for the Expense Report record we just created, passing in our temporary variable So let's do this now. In the Web Apps window, open expenses > flows > main > CreateExpenseReport.  Open the Actions tab, click the createExpenseReport action. Click the Variables tab in the left of the Action Chain Editor. Add a variable called patchPayload of type updateExpenseReportRequest. Click the Action Chain tab in the left of the Action Chain Editor to view the steps of the action chain again. Drag an Assign Variables action to the success path on the far left of the action chain. In the Property Inspector, click Assign next to Variables. Map Results > createExpenseReport > body to Action Chain > patchPayload. Click Save. Drag a Start Process action under the Assign Variables action you just added. In the Property Inspector, click Select Process.  Select Process Alias > ExpenseApproal > Receive Message In the Property Inspector, click startPayload under Input Parameters. Map id and name from Results > createExpenseReport > body on the left to id and name from Parameters > startPayload on the right. Click Save. Drag an Assign Variables action under the Start Process action that you just added. In the Property Inspector, click Assign next to Variables. Map Action Chain > Results > startProcess1 > content > id to Action Chain > patchPayload > processDefId on the right.  Drag a Call REST Endpoint action under the Assign Variables action that you just added. Click Select Endpoint. Select the PATCH /ExpenseReprort/{ExpenseReportId} endpoint. Under Input Parameters in the Property Inspector, click ExpenseReport_Id. Map Action Chain > Results > createExpenseReport > body > id on the left to Parameters > ExpenseReport_Id on the right. Click Save. Under Parameters in the Property Inspector, click body. Map Action Chain > patchPayload on the left to Parameters > body on the right. Click Save. Close the CreateExpenseReportChain tab. In the Page Designer for the CreateExpenseReport page, change the display text of the Save button to Submit. Test the application by entering a new expense report. In the PCS Test window, you will now see an instance in the Running Instances list. In the next chapter, we will add a Task List to the application.  

This blog is part of the series Visual Builder Cloud Service Learning Path. In the previous lesson, we designed the process we will use in our application. If you don't have it, you can download the...

Processes in VBCS Applications - Creating and Launching a Process

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll learn about how to back your VBCS application with an approval process in Process Cloud Service (PCS). PCS is included as part of Oracle Integration Cloud Enterprise, as is VBCS. In this tutorial, we'll look at how to create a process in PCS that can handle the approval process for your Expense Report application. Import this application to start the lesson. Creating the Process Here are a few key points about the process we are going to create: It is based on the Start With Message Approval template that is included in PCS. We will remove a few things to make it easier to work with. It contains a PCS Business Object called ExpenseReport that includes some key information that PCS needs to know in order to interact with the VBCS application We pass in this info by defining an ExpenseReport object as a parameter to the Start message and then mapping that data to the PCS ExpenseReport. The important thing to remember here is that the argument on the Start message only defines the shape of the data, while the Business Object in the process itself actually holds the data. Let's create our process. In the VBCS Expense Report application, open the Processes tab and click the menu button in the top right of the tab. Then click Design Processes. In the top-right corner of the Process Applications page, click Create > New Application. Name the application Expense Approvals and click Create. Click Start when a message is received. Then select Simple Message Approval Pattern, name the process ExpenseApproval, and click Create. Configuring the Process Let's remove a few things and do some basic setup.  Remove the Notify and Fulfill actions by selecting them then clicking the trash can icon above them. When you have exclusive gateways like the one after the Approve Request step, you set one path as being the default path and have to set a condition for all other paths. Let's set the condition for the No path. Select the No path then click the pencil icon. In the Property Inspector that opens at the bottom of the screen, click the pencil button next to the Condition field. Expand ExpenseApproval, select TaskOutcomeObject, and click the Insert Into Expression button.  Fill out the rest of the expression to say TaskOutcomeDataObject == "REJECT" Click OK. Creating the PCS Business Object Now let's create our ExpenseReport business object that will hold our data from the VBCS application In the left sidebar of the PCS window, click Business Types. In the top-right, click Create > New Business Object. Set ExpenseReport as the name and click Next. Insert the following fields, all strings, and click Finish. id​ name Note that id is an integer but because of some problems PCS has when dealing with integers we're just going to treat it as a string. Configuring the Start Message So above we created a business object shape. Now we have to: Use that shape to define the input parameter of the process Create an instance of the business object in the process Map the input parameter to the business object instance Let's do that now. Double-click the Receive Message node to open the property inspector. Click the pencil button next to Define Interface. Click the + button in the Arguments Definition list. Change the name to startPayload.  Click the down arrow next to string in the Type column. Expand Components and select BusinessData.ExpenseReport. Click OK. In the top-right of the Process window, click Data Objects. Click Add. In the dialog, set the name to expenseReport. Under Data Type, choose Business and select BusinessData.ExpenseReport. Click Create. Close the Data Objects dialog. Click the menu icon on the Start Message and choose Data Associations. Expand startPayload on the left and ExpenseApproval > Data Object > expenseReport on the right. Then map the id and name fields by dragging them onto the canvas in the middle. Click Apply. Running the Process in Test Mode Now let's save the project, publish our version, then run activate it in test mode. It's best to save and publish every time you make a change in the process and want to test it in VBCS. In the top-right of the Process window, click Save.  Click Publish at the top of the page. Add a comment in the Publish dialog and click Publish. Click Test in the top of the page. In the Test window, click the Activate button. Confirm the dialog that asks to add you to all roles.  Hopefully the validation window doesn't show any errors, but if so fix them in the process and save and publish again. The Running instances window will show you instances of the process that you launch from VBCS. We'll look at how to debug problems with the process in a later chapter. That's it! You're ready to hook this up to a VBCS Application, which we'll cover in the next chapter.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll learn about how to back your VBCS application with an approval process in Process Cloud Service (PCS)....

Oracle Visual Builder Cloud Service

Integrating Processes into Visual Builder Cloud Applications

If you got Visual Builder Cloud Service as part of the Oracle Integration Cloud, then you have access to a powerful process creation and management service. Process Cloud helps you to create processes that can involve multiple steps ,multiple users and roles, and run over long periods. VBCS has specific functionality built-in to allow you to integrate these type of processes into your applications. Once you configure your process cloud service connection, you'll be able to add processes that you created in process cloud to your application. Then you can invoke and interact with them from both your user interface or the logic of your business objects. In the video below you get a quick introduction to several techniques used to interact with processes from VBCS. In the video you'll see: How to add a process to your app How to invoke it from action chains How to add processes and tasks to your UI How to leverage the process integration code templates created by VBCS How to invoke processes from business objects triggers  For more on working with processes and VBCS see the Working with Business Processes documentation chapter. We also added a set of blog entries that walk you through integrating PCS with VBCS in our Visual Builder Learning Path series of blogs. For a more complete introduction to process cloud service see the process cloud getting started page .  

If you got Visual Builder Cloud Service as part of the Oracle Integration Cloud, then you have access to a powerful process creation and management service. Process Cloud helps you to create processes...

Oracle Visual Builder Cloud Service

Visual Builder Mobile App Native Build Configuration Tips

A few tips to get mobile app build configuration right.   Mobile App Configuration Mobile app native build configuration is exposed as part of app settings Android build configuration 1. Keystore Generation Use keytool utility available with Java (JDK) is used to generate the keystore needed for signing your Android app. keytool is typically be available in your path, it provides a very quick way to generate a public/private key pair and store them in keystore. Here is link to detailed keytool documentation. Below is the screenshot of cmd line used to generate a keystore for my sample application for your reference: 2. Build Profile Configuration Configure the keystore values from the above as part of the Android build configuration as shown below. You can also select a specific profile as the default if you have more than one configuration. General recommendation is to have separate build profiles for development and production purposes.        iOS Configuration iOS configuration requires following guidelines from Apple to generate the provisioning profile and the certificate required for generating the IPA file. You would need a Apple Developer account to generate the above.  There are two flavors of Apple Developer accounts you could use for this purpose :  1. Standard Apple Developer Program : This is required for distributing your application via Apple AppStore.  2. Enterprise Developer Program : This allows companies to distribute apps to employees without going through the AppStore. If you are planning to build apps targeted for employees of your company this program is better suited than the standard developer program as you don't have to go through the Apple review to distribute your app. More details about the enterprise program are available here.  Generating .p12 file: A very nice step by step instructions video from Josh Morony here for creating p12 file on windows. If you are using a Mac you could create this a bit more easily following the instructions from Apple. Here is nice article I found useful for generating p12 file on Mac. Upload the p12 file to the Certificate field in the screen shot shown below. Enter the same password used while generating the p12 file in the Certificate password field. Provisioning Profile Variants: Development provisioning profile:  Typically used when running locally on a phone plugged in to your computer. This allows debugger access. A development provisioning profile allows apps signed by you to run on your registered devices.  In-House Distribution Provisioning Profile: If you want to develop and distribute apps privately within your company or to a selected number of end users, you can use a provisioning profile for in-house distribution. It's available only when using Apple Enterprise Program AppStore Provisioning Profile : This Distribution Provisioning Profile is available for the Apple Developer Program, allows you to generate a release version of your mobile app that can be published and distributed through the App Store. Ad Hoc: This allows you to generate a release version of your mobile app that can only be used in a limited list of devices. Use this profile to distribute your application to a limited group of end-users. Only the devices specified for the provisioning profile will be able install and launch the app. Often used when sending out to testers. Configuring Provisioning Profile: Upload the provisioning profile file in to the Provisioning Profile and in the Signing identity field enter the Common Name of the certificate. This is a bit tricky to get right and I have seen a lot of people getting this wrong. We are working on improving this but in the mean time follow these steps: 1. Install the certificate (p12 file) on your mac by double clicking it 2. It opens in the key chain app 3. Copy the Common Name as shown in the screenshot below        Build Configuration Screen                   

A few tips to get mobile app build configuration right.   Mobile App Configuration Mobile app native build configuration is exposed as part of app settings Android build configuration 1. Keystore...

Oracle Visual Builder Cloud Service

Tips and Tricks for List of Values in Visual Builder Cloud Service

While working on some customers' applications, I ran into a few performance and functionality tips related to list of values in Visual Builder Cloud Service (VBCS). While it is very tempting to use the built in quick start that binds a list to results from a service, in some cases you might want to take a different approach. One reason is performance - some lists don't change very often - and it makes more sense to fetch them only once instead of at every entry into a page. VBCS offers additional scopes for variables - and in the demo below I show how to use an application scope to only fetch a list of countries once (starting at 1:15). I also show how to define an array that will store the values of the list in a way that will allow you to access them from other locations in your app, and not just the specific UI component. The other scenario that the demo shows relates to situations where you need to get additional information on the record you selected in the list. For example, your list might have the code and label but might contain additional meaningful fields. What if you need access to those values for the selected record? In the demo below (6:40), I use a little JavaSciprt utility method that I add to the page to get the full details of the selected record from the list. The code used is (replace the two bold names with the id field and the value you want to return): PageModule.prototype.FindThreeLetter = function(list,value) {  return  list.find(record => record.alpha2_code === value).alpha3_code; } In the past, any array used for an LOV had to have "label" and "code" fields, but Oracle JET now allows you to set other fields to act in those roles this is shown at 5:54 using the options-keys property of the list component - a combobox in my case. Check it out:

While working on some customers' applications, I ran into a few performance and functionality tips related to list of values in Visual Builder Cloud Service (VBCS). While it is very tempting to use...

Managing Visual Builder Code with Developer Cloud Service

Developer Cloud Service (DevCS for short) is a foundation service in the Oracle Cloud that provides you with a full cloud platform to manage agile development processes and automate DevOps cycles. It is available for every Oracle Cloud customer. One key capability (that is actually offered for free as part of your Oracle cloud subscription) is Git based repositories that you can create to manage the code of your application. In this blog we are going to show you how to leverage Visual Builder's built in integration with DevCS to manage your code lifecycle in these Git repositories. A full introduction to Git and the way you work with it - specifically the gitflow approach to code management is outside the scope of this blog. But since Git is the most popular version management solution out there - you can find many internet tutorials that will teach you how to implement these methodologies.  With the git integration in VBCS developing application in teams with multiple developers and multiple tasks is much more organized. In addition you have a full view of the code changes in your application and the ability to easily manage versions. In the video below we teach you some of the basic steps including: Creating a DevCS project with a default Git repository Connecting VBCS to DevCS and to a specific Git branch Pushing code into the repository Creating branches Pulling and importing code from repostiories Viewing code changes in DevCS The main concept to understand is that with this development approach, the app code source of truth becomes the git repository in DevCS. Developers then pull/import the code from that place to local copies in their DevCS development environment, where they can continue to develop it pushing changes back to the central repository. There is much more that you can do with DevCS and VBCS including managing and tracking issues, agile development processes and even automating the publishing of your applications. We'll cover these in upcoming blog entries. For more tips on using Developer Cloud Service see the DevCS documentation including the tutorials. 

Developer Cloud Service (DevCS for short) is a foundation service in the Oracle Cloud that provides you with a full cloud platform to manage agile development processes and automate DevOps cycles. It...

Oracle Visual Builder Cloud Service

Importing and Using Javascript libraries in your Visual Builder custom code

In a recent post, I shared the prescriptive model for creating custom code within Visual Builder. Namely, using Javascript modules at the App, Flow, or Page level to create custom functions within the module. In this post, I want to talk about importing and using external Javascript libraries so you can use functions, objects and variables within that library. For this example, I will use the glmatrix library, a collection of Vectors, Matrices, and associated linear algebra operations. These types of operations can be used for more than just graphics so they live in their own library. The glmatrix library is provided in a "min" format. Essentially one free of whitespace and newline characters and in one file. So, the library I am importing is the glmatrixmin.js library which can be downloaded from the "dist" directory within the project github page: https://github.com/toji/gl-matrix/tree/master/dist. First, you'll need to import the library into your project. With Visual Builder, you can import resources at each of the levels, App, Flow, and Page and that resource will be accessible via that path. To import the file, right click on the project App, Flow, or Page node and select Import Resource. The resource needs to be uploaded as a zip file. So compress the glmatrixmin.js into a zip and select it from your files system in the Import Resources dialog. The dialog will show the import location. Remember this as this is how we reference the file later. Now the file is imported, you can see it in your code view under the Resources folder of the "main" Flow within which it was imported.  Now, we can write some custom code in our PageModule and reference the file to load it into our module. To do that we use a define statement, which provides the path to the file and the alias with which we will refer to the imported library in our code. See the below code example, for the define statement and usage. The full path to the file is used combining the import location with the flow name and resources directory. Note, the .js file extension is not necessary. Also, note the alias "glmatrix" is used to reference the objects and functions within the library.       

In a recent post, I shared the prescriptive model for creating custom code within Visual Builder. Namely, using Javascript modules at the App, Flow, or Page level to create custom functions...

Styling Visual Builder Cloud Service Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll learn about how to style VBCS applications. All styling in VBCS applications happens manually in CSS. There are no declarative features for changing the display of text or images. As all VBCS applications are just JET applications, they use JET Themes to style the applications. When styling your VBCS or JET applications, it is important that you use theming correctly to do so, otherwise you run the risk of finding that your re-styling breaks when you upgrade your platform versions.  JET components provides a styling API through the use of SASS only, and any directly styled oj-* component selectors or other approaches will not be supported. This is because the internal structure of JET components, and the styles that they use, are subject to change from release to release. The published set of SASS variables constitutes a stable supported API that will internally re-map the configuration as required by internal changes within the JET implementation. Read the JET Dev Guide on Themes for more information. By default, all VBCS applications use the Alta UI Theme. VBCS applications have a built-in app.css file that you can use to define additional styling on top of the main Alta theme. For example, if you have made a <div> clickable, you may want to add a class called "clickable" to the div and define the CSS for the class so that it's highlighted, the cursor changes to a pointer when you hover over it, etc. If, however, you want to style the core elements of a VBCS theme, you should use SASS variables and generate the CSS rather than coding against the DOM elements directly using oj-* selectors in app.css. The reason is that the internal DOM of JET elements can and does change between releases of JET. Therefore a CSS that worked in one release may not work in another. SASS variables insulate you from these changes. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. If you are starting at this lab, go to Building Your First VBCS Application and follow the steps to import the project, then continue below. Download this ZIP file to your computer. In your project, click the menu in the top right and choose Import Resources. Drag and drop the ZIP file into the dialog. Select Delete existing files and resources and click Import. Using Custom Classes in VBCS CSS Let's define a custom class to style clickable text in VBCS. As you can see when you open the main-start page, I've changed the list in the Expense Reports to have a clickable <h3> title for each expense report that navigates to the Edit page for that record. I've also added the custom class "clickable" to the div. In the Web Apps panel, open Expenses → resources → css → app.css and add the following code: .clickable { color: #07C; } .clickable:hover { cursor: hand; cursor: pointer; } Go back to your main-start page and reload the page in the Page Designer. Using a Custom Theme We won't go into how you actually create a new theme in JET. For that you can read the JET Dev Guide on Themes and try out the JET Theme Builder. The JET Theme Builder will generate a theme that looks like these: JET Stealth Theme JET Green Theme To use this theme in your application: In the Web Apps panel, expand Expenses → resources and right-click the css node. Choose Import. Drag and drop one of the above ZIPs and choose OK. For the Stealth them, for example, you should get a directory structure like this: Switch to the Source View panel and click index.html to open it in the code editor: Change the link to the CSS file to: <link type="text/css" rel="stylesheet" href="resources/css/stealth.css">

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll learn about how to style VBCS applications. All styling in VBCS applications happens manually in CSS....

Connecting to an External REST API (Twitter) in a Visual Builder Cloud Service Application

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, we will look at integrating a third party REST API that has no description document (Swagger or ADF Describe). We will integrate the Twitter API to fetch a list of tweets for a list celebrities stored in a custom Business Object. Importing the Starter Project We'll start the lesson with an application that already contains the Celebrities Business Object and mobile application with a list of celebrities and a details page for each one. Download this ZIP file to your computer. In the VBCS list of applications, click Import > Application from File. Drag and drop the ZIP file into the dialog and click Import. Creating an Application in Twitter Before you can connect to the Twitter APIs, you need to register for the developer program and create an app in Twitter. Go to https://developer.twitter.com/en/docs/basics/getting-started and follow the instructions under Get started: Build an app on Twitter. Registering the Twitter API In order to work with a REST API, VBCS needs to understand basic information about that REST service, such as: The service endpoints and verbs The required query parameters and headers The authentication method used to connect The transformation patterns for creating URLs for pagination, sorting, and filtering Since the Twitter API doesn't have Swagger documentation, we can run through a wizard to input this information manually. In the left sidebar, click the Service Connections icon Click the icon in the Services panel Click Define By Endpoint In the wizard, enter the following information and click Next: Field Value Method Get URL https://api.twitter.com/1.1/statuses/user_timeline.json Action Hint Get Many Service Base URL Leave default (https://api.twitter.com/1.1/statuses) In the Service tab, change the Service Name to Twitter. In the Authentication tab, enter the following information. Go to https://apps.twitter.com to get this information: Field Value Authentication Method Client Credentials OAuth 2.0 Client Id The Consumer Key (API Key) from your app Secret Consumer Secret (API Secret)  Scope Leave blank Authorization URL https://api.twitter.com/oauth2/token Enable token relay Leave unchecked Click Request > URL Parameters. Add the following Dynamic Query Parameter: screen_name – String Click Test. Enter SFGiants as the screen_name and click Send. The response body appears in the Body area below. Click the Copy to Response Body button. Click Create. Consuming the Twitter API Now let's drop a list into the Celebrity Detail page and populate it with a list of the celebrity's tweets. Go to the Mobile Apps panel and click Tweets > flows > main > CelebrityDetail. The page opens but gives a 404 error as there is no cebrityId provided.  Click the button and enter 1 in the dialog box. The page renders with the Katy Parry information.  Drop a List View under the Twitter Feed header.  In the Property Inspector, click Add Data. Under Twitter, select GET /user_timeline.json and click Next. Choose the first template and click Next. Add the created_at field to Field 2 and the and the text field to Field 4. Set the Primary Key to id. Click Next. Map celebrity > twitterHandle on the left to uriParameters > screen_name on the right. Click Finish. Wrapping the Twitter Feed List in an oj-bind-if If you run the app now you'll notice that the Twitter call isn't working. If you look at the REST call in the Chrome Developer Tools, you'll see it's passing undefined as the screen_name. That's because the page hasn't finished loading the celebrity details before it tries calling Twitter. We fix that by wrapping the list in an oj-bind-if and check that celebrity object is populated before we render the Twitter list. Right-click the list in ContactDetail and choose Surround With > If Right-click the list and choose Select Parent > If.  In the Property Inspector, change the test to: [[$page.variables.celebrityRecord.twitterHandle !== undefined]] Note: In our database we know that twitterHandle will always have a value. In more complex cases, you'll have to create more complex logic to handle null, undefined, empty string values, and other situations. Reload the page. The list of Tweets renders correctly.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, we will look at integrating a third party REST API that has no description document (Swagger or ADF...

Oracle Visual Builder Cloud Service

Consuming Fusion Applications REST APIs in Visual Builder Cloud Service Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we will look at consuming Fusion Applications REST services in a VBCS mobile application. In order to work with a REST API, VBCS needs to understand basic information about that REST service, such as: The service endpoints and verbs The required query parameters and headers The authentication method used to connect The transformation patterns for creating URLs for pagination, sorting, and filtering Fusion Applications like Oracle CX, HCM, and ERP clouds expose REST APIs that VBCS knows how to consume right out of the box.  There are three ways you hook up to register a REST connection: Select from Catalog - The Service Catalog shows all of the REST APIs for a registered Fusion instance. VBCS understands FA REST services out-of-the-box. See Authenticating Against FA below to see the requirements for Service Catalog Define by Specification - Enter the location of a Swagger or ADF-Describe document for a REST API. Use this to set up an App ID connection to any FA server, regardless of whether it meets the requirements in Authenticating Against FA. Define by Endpoint - Use this wizard to manually specify the required information about a REST endpoint. We will use this to register a Twitter API in a later lesson. Creating the Project and the Mobile Application In this lesson we will build the following UI over the FA Contacts REST endpoint: To do this we will access three endpoints: The GET ONE and GET MANY endpoints for /contacts The finder method that retrieves all of the country names, country codes, and other information Creating the Mobile App Create a new project called FAContactList In the Mobile Apps panel, click Create New Mobile App. Name the app Contacts and select None for the Navigation Style. Click Finish. Registering the Contacts REST API Click the Service Connections panel and click Add Service Connection. If you have a registered Service Catalog, click Select from Catalog.  If you do not have a registered Service Catalog, click Define by Specification. Switch the API Type to ADF Describe. Enter https://pathToYourCRM/crmRestApi/resources/latest/contacts/describe in the Service Specification field. Set the Service ID to contacts. Enable Basic Authentication and enter a set of valid credentials that has permission to call the REST API. Then click Next. Expand the /contacts node and select all of the following: GET /contacts GET /contacts/{contacts_Id} GET /fndTerritories;for=contacts-CountriesLOV Creating the List Select the main-start page in the Page Designer. Drop a List View onto the page. Select the List View in the Page Designer. (If you have just dropped it in, it will be selected already.) Then open the Property Inspector and select the Quickstarts page. Under crmRestApi, select contacts. Select the first template and click Next Add the following fields: Field 2: ContactName Field 3: AccountName Field 4: Country Click Next and then click Finish. Creating the Details Page Select the List View in the Page Designer. In the QuickStart tab of the Property Inspector, click Add Details Page. In the Select Endpoint page, select contacts and click Next. Add these fields: AccountName ContactName FormattedHomePhoneNumber FormattedMobileNumber PrimaryAddress > item[i] > FormattedAddress Click Finish. Open the ContactDetails page in the Page Designer Select the Form Layout and in the Property Inspector change the Label Edge variable to Top. All of the display labels move to above the input fields. Fix the display label text and reorder the fields so the page looks like this: Displaying LOV Labels in Collections and Details Pages As you can see, the list of Contacts is showing the country code instead of the full country name. This is because there is no one REST API that you can use to retrieve both the country codes and the display labels in the same call. Instead, we have to cache all of the country display labels in an application-scope variable when the application is first accessed. Then we will use a custom Javascript function to swap out the country codes for the display labels when the list is rendered. Adding the getLOVMeaningValue Function Open the application editor by opening the Mobile Apps panel and clicking the top-level Contacts node. Open the JavaScript panel of the application editor by clicking the JS button Add the getLOVMeaningValue function as shown in lines 6-22 below: define([], function() { 'use strict'; var AppModule = function AppModule() {}; AppModule.prototype.getLOVMeaningValue = function(key, lovs) { if (!lovs || !lovs[0]) { return; } var res; var keyProperty = Object.keys(lovs[0])[0]; lovs.forEach(function(record) { if (record[keyProperty] === key) { res = record; } }); if (res) { return res[Object.keys(res)[1]]; } }; return AppModule; }); Creating the Type and Variable for the Status Code Options Still in the application settings editor, open the Variables editor, then click the Types tab. Create a new Type from Endpoint based on the /fndTerritories;for=contacts-CountriesLOV endpoint. Change the name of the type to countryCodeOptions. Add TerritoryCode and TerritoryShortName to the Type and click Finish. Switch to the Variables tab. Create a new variable called countryCodes of type countryCodeOptions. Creating an Action to Populate Account Type Options Still in the application settings editor, open the Actions page. Create a new Action Chain called populateCountryCodes. Drag a Call REST Endpoint action from the left panel to underneath the Start node. In the Property Inspector, click Select Endpoint and select contacts > contacts  > /fndTerritories;for=contacts-CountriesLOV By default the REST call only returns the first 25 entries, but we want to cache all of the country names in our variable. So we will set a high limit for the REST call. In the property inspector, click limit under Input Parameters. Map the variable to 500, leaving it set as Static Content, and click OK. Add an Assign Variables action that maps the body returned by the Call REST action to the statusCodes flow variable. Return to the application editor and open the Events panel Create a new event: Event: vbEnter Action Chain: populateStatusCode Updating the List to Call the getLOVMeaningValue Function Open the Page Designer for main-start. Select any row in the list In the General tab of the Property Inspector, change the Value1 to: [[ $application.functions.getLOVMeaningValue($current.data.Country,$application.variables.countryCodes.items)]]

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we will look at consuming Fusion Applications REST services in a VBCS mobile application. In order to work...

Getting The Label/Description Value from a Select List in Visual Builder

When you add a select list component such as selectOneChoice to a Visual Builder page, you get a nice wizard that helps you bind it to data, and you can then easily access the value that you select in the list. However in some cases you might want to access the label of the list rather than the value. Here is a quick tip that will help you get there. Oracle JET introduced a new attribute to the oj-select-one component called value-option - this contains an object with two fields value and label that synch up with the list. Read more about this attribute in the JET Doc here. Right now there is no design time support for using this property in VBCS right now, but you can still leverage it. First create a page variable of type object and then add two string attribute in it called label and value. Next go into the page layout editor and switch to the code editor view and add the value-option option to your component (note that you should use curly braces):   You can now refer to the label using a syntax such as: {{ $page.variables.selectedVal.label }} For example this page: The Code would be: <div class="oj-flex">     <oj-label id="oj-label--490912658-1" for="oj-select-one--490912658-1" class="oj-flex-item oj-sm-12 oj-md-2">Select (One)</oj-label>     <oj-select-one value-option="{{$page.variables.selectedVal}}" options="[[$page.variables.airlineListServiceDataProvider]]" options-keys.value="id" options-keys.label="airline" value="{{ $page.variables.airline }}" id="oj-select-one--490912658-1" class="oj-flex-item oj-sm-12 oj-md-4" ></oj-select-one> </div> <div class="oj-flex">     <oj-label id="oj-label--490912658-2" for="oj-input-text--490912658-1" class="oj-flex-item oj-sm-12 oj-md-2">value</oj-label>     <oj-input-text id="oj-input-text--490912658-1" class="oj-flex-item oj-sm-12 oj-md-4" value="{{ $page.variables.airline }}"></oj-input-text> </div> <div class="oj-flex">     <oj-label id="oj-label--490912658-3" for="oj-input-text--490912658-2" class="oj-flex-item oj-sm-12 oj-md-2">Selected val label</oj-label>     <oj-input-text id="oj-input-text--490912658-2" class="oj-flex-item oj-sm-12 oj-md-4" placeholder="{{ $page.variables.selectedVal.label }}" value="{{ $page.variables.selectedVal.label }}"></oj-input-text> </div> <div class="oj-flex">     <oj-label id="oj-label--490912658-4" for="oj-input-text--490912658-3" class="oj-flex-item oj-sm-12 oj-md-2">selected val value</oj-label>     <oj-input-text id="oj-input-text--490912658-3" class="oj-flex-item oj-sm-12 oj-md-4" value="{{ $page.variables.selectedVal.value }}"></oj-input-text> </div>

When you add a select list component such as selectOneChoice to a Visual Builder page, you get a nice wizard that helps you bind it to data, and you can then easily access the value that you select in...

Oracle Visual Builder Cloud Service

Data Security and Role-Based UI in VBCS Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lab we will add some role-based UI based on groups in IDCS. We will also implement Data Security on our Expense Report business object. It's important before we go on that you understand the difference between data security and role-based dynamic UI. You need to do both to provide a secure app that has elegant usability. Data Security Data Security controls what data a user can fetch from the back-end. You can limit access to an entire resource - i.e. all Expense Reports - or define more complex rules for a resource - i.e. all Expense Reports created by me. Data security is enforced at the service endpoint so it's always secure and can't be spoofed by changing settings in your browser or changing the URL of the REST service being called. For business objects, you can define your own security rules at the object level. You can't set data security rules for fields in an object - i.e. only Managers can see the Salary field in an Employee object. For external REST services, you have to set the permissions at the service endpoints. There is no way to set additional VBCS-specific security rules over what the endpoints already specify. For many Oracle PaaS and SaaS services, like Oracle Sales Cloud or Oracle Mobile Cloud Service, you can define the security rules for the endpoints exposed. Role-Based Dynamic UI Role-based dynamic UI controls what components a user sees on a page. You can set restrictions on entire pages, or just on certain components in a page. For example you can hide the navigation button to a page or a tab. We use this expression to set component visibility by role: <oj-bind-if test=“$application.user.roles.role_name” > </oj-bind-if> Role-based dynamic UI is only enforced on the client. It is easy to go into the browser's developer tools and change the value of the user role. As such it alone is not enough to make a secure application - you must always use it with data security. So you hide the navigation to a page and make the contents of that page appear only to certain roles, but you must also secure the data returned on that page so that if someone spoofs the role the REST call only returns an empty data set. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. If you are starting at this lab, go to Building Your First VBCS Application and follow the steps to import the project, then continue below. Download this ZIP file to your computer. In your project, click the menu in the top right and choose Import Resources. Drag and drop the ZIP file into the dialog. Select Delete existing files and resources and click Import. Setting Up a Role When you set up additional roles in your project, the roles map to groups in your IDCS account. Roles are defined at the project level and are available to all applications and business objects in the project. These roles act as additional roles on top of the standard VBCS "Authenticated User" role. We will talk more about what that means in the next section. For now, let's just set up a role. Open Project Settings in the top-right of the application window.   Click User Roles. Then click Add Role. Enter following information: Role: Admin Mapping: Any group you have access to. See https://docs.oracle.com/en/cloud/paas/identity-cloud/uaids/managing-oracle-identity-cloud-service-groups1.html for instructions on setting up a group Click the check box on the right. The Role switches to read-only mode.   Click Close to close the Settings dialog. Setting Up Data Security Now let's define data security rules on our Expense Report business object. We will it configure it so that: Authenticated User can only see their expense reports Admin user can see all expense reports So let's do that now: In the Business Objects panel, click Expense Report to open the Business Object Editor Click the Security tab in the editor, click the icon next to Role-based Security Select Authenticated User. The View, Edit, and Delete rows display below. Click the menu for each of these and select Allow if user created row Notice you can expand each node to see the exact query being checked for and add additional conditions to the query. Previewing the App as Different Roles The Page Designer has a Who Am I button  that allows you to preview the application in different roles. As we said, the Admin role is an additional role layered onto the Authenticated User role. But you can have different settings for all authenticated users and just Admin users. So if you want to preview the app as Admin, you have to deselect Authenticated User, even though Admin users are also authenticated users. Note that the Who Am I only spoofs the role in the UI and does not change the identity with which you call the services. Therefore, the Expense Reports REST calls will still return all the data that you - the currently logged in VBCS designer user - are allowed to see. Setting Role-Based View Restrictions on a Page You can set role-based permissions on a page or flow in the JSON metadata for the page/flow.  In the Web App panel, click the admin flow node to open the admin flow editor page.   Click the {} node to view the JSON for the page.  Enter the following code at the end of the JSON. Don't forget the comma at the end of the variable line:   "variables": {},   "security": {     "access": {       "requiresAuthentication": true,       "roles": ["Admin"]     }   } } If you run the page as a user who does not have Admin access, the Administration link no longer works Hiding the Navigation Link to the Admin Page Now we will set up a rule on the Administration link to make it visible only to people with the Admin role. In the Web Apps panel of the App Navigator, click root pages > shell. Right-click the Administration link and choose Surround With > Bind If. In the Property Inspector, set the Test property to {{$application.user.roles.Admin}} Use the Who Am I button to turn the Admin role on and off and see the dynamic UI in action.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lab we will add some role-based UI based on groups in IDCS. We will also implement Data Security on our Expense...

Oracle Visual Builder Cloud Service

Adding a Navigation Bar to a VBCS Application

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll add a navigation bar to our application. First it's important to understand what actually gets loaded when you open a VBCS page in the runtime. Here is the heirarchy: index.html - this is the page that actually gets loaded. It's just a wrapper. The only time you'll need to edit this page is when you want to specify a different CSS file. shell page - this is the wrapper you see in the page. It contains the header and footer and the navigation bar that you will add in this lesson. You can have multiple shell pages for different parts of your application. The default shell is specified in the application settings (i.e. click Expenses node in Web Apps panel, then click the Settings panel). Like any other page, a shell page has its variables, actions, events, and so forth. flow - each flow specifies a top-level page and the application settings also specify the default flow to open when the app is accessed. Currently VBCS only allows you to navigate to the top level page of a flow or to another page inside the same flow. That means that any page that you want linked from the top-level navigation menu must be in their own flows. That's why we created the admin page as its own flow instead of a page in the main flow. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. If you are starting at this lab, go to Building Your First VBCS Application and follow the steps to import the project, then continue below. Download this ZIP file to your computer. In your project, click the menu in the top right and choose Import Resources. Drag and drop the ZIP file into the dialog. Select Delete existing files and resources and click Import. Adding the Navigation Bar Open the Web Apps window and open Expenses > root pages > shell. Switch to the Code mode. Add the following code before the closing </header> tag: <div role="navigation" class="oj-web-applayout-max-width oj-web-applayout-navbar"> <oj-navigation-list id="123" aria-label="Choose a navigation item" navigationlevel="application" drill-mode="none" display="all" edge="top" selection="[[$page.currentFlow]]" class="oj-md-condense oj-md-justify-content-flex-end" on-selection-changed="[[$listeners.ojNavigationListSelection]]"> <ul> <li id="main"><a href="#">My Expense Reports</a></li> <li id="admin"><a href="#">Administration</a></li> </ul> </oj-navigation-list> </div> Creating the navigateToPage Action Chain Go to the Actions panel of the shell Page Editor Create a new Action Chain called navigateToPage. Go to the Variables panel of the Action Chain Editor. Add a String variable called page. Add a Boolean variable called navigate. In the Property Inspector for the page variable, check Input Parameters and Required. Do the same for the navigate variable. Switch back to the Action Chain view and drop an If action on the action chain. Set the Condition to {{ $chain.variables.navigate }}.  The reason you're doing this is that the selection change event can get dispatched from either a user action, like a click, or by external changes to the selection property. We only want to react to the former - user actions. We will set the navigate property below to ignore external changes. Drop a Navigate action to the true path of the If action. Switch to the Metadata View by clicking the { } tab and add the following lines in bold. Don't forget the comma at the end of the history line. "actions": { "navigateToPage1": { "module": "vb/action/builtin/navigateToPageAction", "parameters": { "history": "push", "page": "[[ $variables.page ]]" } } Adding the Listener on the Navigation List Go back to the shell tab and open the Events panel Click the + Event Listener button. Click the + button on Other Events and name your custom event ojNavigationListSelection. Click Select. Select the navigateToPage action chain and click Finish. The event is created. In the list of Events, click page under Input Parameters Set the mapping to be an Expression, then enter $event.detail.value as the mapping for page. Click navigate under Parameters. Enter $event.detail.updatedFrom !== 'external', set it to be an Expression, and click Save. The next lesson in the learning path is Data Security and Role-Based UI.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll add a navigation bar to our application. First it's important to understand what actually gets loaded...

Oracle Visual Builder Cloud Service

Dynamic UI in VBCS Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll look at how to dynamically hide or display items in a VBCS application. Although many components have a "hidden" HTML attribute, many times the value there can be overridden by some parent control. To explicitly control any component's visibility, use the <oj-bind-if> tag.   Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Dynamically Displaying Fields Let's wrap Exchange Rate and Amount in USD in an <oj-bind-if> that only displays if the currency is not USD. Go back to the Page Designer for CreateExpenseAccount and switch into Code view. Insert the following <oj-bind-if> statement above the Exchange Rate <oj-input-number> <oj-bind-if id="oj-bind-if--862244262-2" test="[[ $variables.expenseReport.country !== 1 && $variables.expenseReport.country !== undefined && $variables.expenseReport.country !== null && $variables.expenseReport.country !== '']]"> Put a closing </oj-bind-if> tag after the Amount in USD tag. The next lesson in the learning path is Creating a Navigation List

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we'll look at how to dynamically hide or display items in a VBCS application. Although many components have...

Oracle Visual Builder Cloud Service

Are you done with your call? Managing callbacks with a Promise in Visual Builder custom code

In a previous blog, we talked about how to create custom code within Visual Builder. In this blog, we'll discuss how to work with callbacks within that custom code. If you are familiar with Javascript callbacks, read on, but if you need an introduction to callbacks and asynchronous operations and why this takes special care, here is a good primer. In short, we need to manage this specifically because the return result of a custom function may not be available yet when it gets assigned within a callback. Since the callback gets scheduled to run later (asynchronously), your result can be returned undefined because the callback which populates that return value had not completed yet.  Let's look at a specific example, getting a GPS location using the HTLM5 navigator.geolocation API. Screenshot from: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition As shown above, the function takes three parameters called success, error, and options. Success and error are both callbacks and are used in this API because retrieving a location could take several seconds. If the function were to wait for the result, your app would be stuck waiting too. So, callbacks are you used to be "called back" when that information is available rather than blocking your code execution.  But then, how do you deal with the situation described above where our success callback may not be called yet? Use a Promise, as discussed in primer I linked to at the beginning of the article.   Let's implement this within Visual Builder custom code using a module function.  PageModule.prototype.getGeolocation = function()   {      return new Promise(function(resolve, reject) {         var geolocation = navigator.geolocation;         geolocation.getCurrentPosition(function(position) {                var latitude = position.coords.latitude;                var longitude = position.coords.longitude;                var latlong = JSON.stringify({ lat: latitude, lng: longitude});                console.log(latlong.toString());                resolve(latlong);            }, function(error) {                console.log(error);                reject("The error is: " + error);            });      });   }   Within our custom function getGeolocation, we are returning a Promise. This Promise wraps our call to navigator.geolocation and the two callbacks functions it expects as anonymous methods. This ensures our action chain custom function call will wait for the Promise to return (itself an asynchronous call) but will release the custom function from blocking execution at the same time.  A successful retrieval of a geolocation calls our anonymous function for success and returns our assigned variable in the Promise resolve function, ensuring it is not undefined. Non-success calls the error function as an anonymous function and then calls the Promise reject function.  Using the above pattern within Visual Builder custom module functions will ensure: Visual Builder can reference your custom code within an action chain Your callbacks will complete before a result is returned, ensuring a  return result is not undefined Allow you to also deal with error conditions within the same function            

In a previous blog, we talked about how to create custom code within Visual Builder. In this blog, we'll discuss how to work with callbacks within that custom code. If you are familiar with Javascript...

Adding New Oracle JET UI Component to Visual Builder Cloud Service

Oracle Visual Builder Cloud Service is an extendable platform - you can add your own UI components to the list of around 70 UI components that already show up in the component palette of your visual editor. In this blog and video we show you two ways to add additional Oracle JET components to the editor. In the first part of the video we show how to add a "core" Oracle JET components, specifically the train component. In the second part of the video (starting at minute 9) we show you how to add an Oracle JET Composite Component. For the core component, the main thing to know is that you also need to add the component to the json file that describes your page. This way VBCS will know to load this component into your pages. (This is needed since VBCS is optimized to only load needed resources - leveraging require.js for smart resource management). In the video we also show how to create a new data type and array of that type to store a data structure needed to populate the train steps, and how to hook up data from a business object to populate that object when the page loads. In the second part of the video we show how easy it is to pick up an Oracle JET Composite Component and add it to a page. A JET CCA Component is a complex UI component that can include multiple UI elements along with logic. This is based on the Web Components standard architecture, and allows developers to share UI components.

Oracle Visual Builder Cloud Service is an extendable platform - you can add your own UI components to the list of around 70 UI components that already show up in the component palette of your visual...

Using Mobile Cloud Backend API in Visual Builder Mobile App

This blog provides details about using MCS/OMCe back-ends in Visual Builder (VB) mobile apps. We will walkthrough the steps of configuring VB service connections and using the data from MCS to build a simple mobile app. MCS Mobile Backend(MBE) Configuration: Identify the MBE you want to use in your app and get the following information from the MBE API & Settings: 1. Service URI: Navigate to the API section of your MBE to get the base URI for the end point    2. Mobile Backend(MBE) ID  Get MBE ID from the Settings section as shown in the screenshot below 3. Authentication details Identify authentication mechanism used to secure the MBE. Typically, any mobile user defined in the Users section of the back-end Service Connection Configuration: 1. Create a Visual App 2. Create a Service Connection  using Define by End Point option. This experience is going to get much better in a upcoming release but for now follow the steps below                           3. Configure Base URI using the Base URI from step#2 in MBE Configuration section                 4. Configure MBE Id as Request Header                      5. Authentication From the Authentication mechanism drop down select Basic and configure the user name and credentials for the mobile user from step #3 in MCS MBE configuration section.    6. Use the Test tab to test the end point. Use Copy to Response Body option to create the resource definition from the response                       Create Mobile App UI 1. Create a mobile app & select navigation template 2. Select a page template 3. Add Listview from the component palette to the page and select AddData from the quick start menu 4. Select the end point configured in the Service Connection Configuration section to bind data to the Listview                 5. Run the app to preview in the browser using the play button on the top right          

This blog provides details about using MCS/OMCe back-ends in Visual Builder (VB) mobile apps. We will walkthrough the steps of configuring VB service connections and using the data from MCS to build a...

Computed Fields in VBCS Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. This lesson is the first in the series on Dynamic UI. In this lesson we'll learn how to create computed fields in the UI. We will create an Amount in USD field that is computed by multiplying the Amount by the Exchange rate. Simple enough, right? Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path.  Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Creating a Computed Field in the UI Open main-create-expense-report in the Page Designer. Select Amount in USD In the Data panel of the Property Inspector, change the Value property to: {{$variables.expenseReport.exchangeRate * $variables.expenseReport.amount }} Run the page and try entering different values for the Exchange Rate. Amount in USD is updated automatically. The next lesson in the Visual Builder Cloud Service Learning Path is Dynamic UI.

This blog is part of the series Visual Builder Cloud Service Learning Path. This lesson is the first in the series on Dynamic UI. In this lesson we'll learn how to create computed fields in the UI. We...

Oracle Visual Builder Cloud Service

Client-Side Validation in VBCS Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, we'll look at setting up client-side validation in a VBCS Form. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path.  Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Setting Up Validation First we have to set up our form to check the validity of its contents before submitting. We do this by surrounding the form with an <oj-validation-group> element, adding a custom isFormValid Javascript function that returns a boolean, and then calling that function before submitting the form. Open main-create-expense-report Switch to the Code view Surround the expense-form div with <oj-validation-group id="CreateForm">. Don't forget the closing tag. Now click the Expenses application node to open the main application editor and switch to the JS view Add the isFormValid function: define([], function() { 'use strict';   var AppModule = function AppModule() {};   AppModule.prototype.isFormValid = function(form) { var tracker = document.getElementById(form);  if (tracker.valid === "valid") { return true; } else { tracker.showMessages(); tracker.focusOn("@firstInvalidShown"); return false; } } ... Go back to the main-create-expense-report page. Click the Actions tab and open createExpenseReportChain. Add an If action after Start. Set the Condition to {{ $application.functions.isFormValid("CreateForm") }} Move the Call businessObjects/cre... node to the true branch of the If action Setting a Date Validation Note that we are going to use the Expression Editor here to create the expression. The Expression Editor gives you code completion over all in-scope variables as well as JS error highlighting. Go back to the Page Designer for main-create-expense-report. Select the End Date field in the form.   In the General panel of the Property Inspector, click fx button for the the Min property.   In the left panel, expand {} expenseReport and double-click startDate. The editor enters: $variables.expenseReport.startDate Run the page and try entering a date before the Start Date. The DatePicker for End Date makes all dates before the Start Date unavailable. If you manually enter a date before the Start Date it shows an error. Using a Custom Validator Open the JS panel for main-create-expense-report. Add the endDateAfterStartDateValidator function: var PageModule = function PageModule() {}; PageModule.prototype.endDateAfterStartDateValidator = function(startDate) { return [{ validate: (endDate) => { if (endDate) { const valid = endDate >= startDate; if (!valid) { throw new Error('End date must be start date or later'); } return valid; } }, }]; }; return PageModule; }); Return to the Page Designer panel and select End Date In the General panel of the Property Inspector, delete the value for the Min property. In the All panel of the Property Inspector, change the validators property to: {{ $page.functions.endDateAfterStartDateValidator($page.variables.expenseReport.startDate) }} Setting Up the Page for Dynamic UI Now we are going to do some dynamic UI around the amount and exchangeRate fields. There are a few things we need to do to set this up: Add the exchangeRate field to our Type and Variable Add the Input Number fields for Exchange Rate and Amount in USD (we will use this later) Give amount and exchangeRate a default value. The reason we have to do this is that we are going to add some expressions that act over these fields. However, the REST call that initializes and populates these fields may not have completed before the page is displayed and the expressions are evaluated. To get around this, we can either wrap our whole form in an oj-bind-if tag to only load it once the expenseReport variable has been populated, or just give the fields some default values to initiate the variable on page load. Open the Variables panel for main-create-expense-report and click the Types tab. Select the createExpenseReportRequest type. Click Edit from Endpoint Select Request -> exchangeRate and click Finish. Now if you look at the expenseReport variable in the Variables tab, you'll see it includes exchangeRate. In the Property Inspector for expenseReport -> exchangeRate, set the Default Value to 1. Select expenseReport -> amount and set the Default Value to 1. In the Page Designer panel, add an Input Number field below Amount. In the General tab of the Property Inspector, change its Label Hint to Exchange Rate. In the Data tab, bind its Value to {{ $page.variables.expenseReport.exchangeRate }} Drop a Currency field below Exchange Rate. In the General tab of the Property Inspector, change its Label Hint to Amount in USD. Make the field read-only. Making a Field Conditionally Required Let's make the Justification field required if the Amount is more than $500. Select Justification In the All panel of the Property Inspector, click the FX above the required property. Use the editor to set the following: {{ $variables.expenseReport.amount * $variables.expenseReport.exchangeRate >= 500 }} Run the page and try entering 600 for the Amount. Justification becomes required. The next lesson in the Visual Builder Cloud Service Learning Path is Computed Fields.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, we'll look at setting up client-side validation in a VBCS Form. Updating Your Project This lesson builds on the...

Oracle Visual Builder Cloud Service

Reflecting Changes in Business Objects in UI Tables with Visual Builder

While the quick start wizards in Visual Builder Cloud Service (VBCS) make it very easy to create tables and other UI components and bind them to business objects, it is good to understand what is going on behind the scenes, and what the wizards actually do. Knowing this will help you achieve things that we still don't have wizards for. For example - let's suppose you created a business object and then created a UI table that shows the fields from that business object in your page. You probably used the "Add Data" quick start wizard to do that. But then you remembered that you need one more column added to your business object, however after you added that one to the BO, you'll notice it is not automatically shown in the UI. That makes sense since we don't want to automatically show all the fields in a BO in the UI. But how do you add this new column to the UI? The table's Add Data wizard will be disabled at this point - so is your only option to drop and recreate the UI table? Of course not!   If you'll look into the table properties you'll see it is based on a page level ServiceDataProvider ( SDP for short) variable. This is a special type of object that the wizards create to represent collections. If you'll look at the variable, you'll see that it is returning data using a specific type. Note that the type is defined at the flow level - if you'll look at the type definition you'll see where the fields that make up the object are defined. It is very easy to add a new field here - and modify the type to include the new column you added to the BO. Just make sure you are using the column's id - and not it's title - when you define the new field in the items array. Now back in the UI you can easily modify the code of the table to add one more column that will be hooked up to this new field in the SDP that is based on the type. Sounds complex? It really isn't - here is a 3 minute video showing the whole thing end to end: As you see - a little understanding of the way VBCS works, makes it easy to go beyond the wizards and achieve anything.

While the quick start wizards in Visual Builder Cloud Service (VBCS) make it very easy to create tables and other UI components and bind them to business objects, it is good to understand what...

Oracle Visual Builder Cloud Service

Parent-Child Master-Detail in VBCS

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we create a Master-Detail view over Expense Reports and their child Line Item entries.  Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path.  Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Adding a Child Table Open EditExpenseReport. If you get a 404 when you open it, it means the page is missing the required context. Click the button, enter "1", and click Reload. Add a Heading between the form and the buttons and call it Line Items Add a List View below the heading. In the Property Inspector, click Add Data In the Choose an Endpoint tab, select the LineItem under Business Objects. Click Next. Select the second row template. Click Next.   Choose the name and amount fields. Click Next. In the Define Query for the page, expand filterCriterion on the left and set the following properties: item[0] -> attribute: expenseReport (mark as Static content) item[0] -> op: $eq (mark as Static content) item[0] -> value: $variables.expenseReportId (drag expenseReportId from the left panel to bind it, it will automatically be marked as an Expression. if you copy and paste the value in, the dialog box automatically marks it as Static Text. Switch it to Expression but be sure to remove the surrounding quote marks from "$variables.expenseReportId".) Click Finish Adding a New Line Item Form Go to the Variables panel of the EditExpenseReport page. Click the Types tab. Create a New Type from Endpoint. Select Business Objects > LineItem > POST /LineItem Click Next. Add the expenseReport, name, and amount fields. Click Finish. Click the Variable Tab and add a new variable called newLineItem of type create_LineItem   Expand the newLineItem variable and select the expenseReport property. In the Property Inspector, change Default Value to {{ $page.variables.expenseReportId }} Go back to the Page Designer by clicking . Drop a Form Layout component between the Line Items heading and the list of Line Items. In the Property Inspector, set the Label Edge to top.   Add an Input Text component and a Currency component to the Form Layout. Change the display labels to Name on the Input Text and Amount on the Currency component. Select the Name field in the Page Designer. In the Data tab of the Property Inspector, bind Value to {{ $variables.newLineItem.name }}. Do the same to bind the Amount field to {{ $variables.newLineItem.amount }} Add a Button below the Form Layout. Change the Text to Add. Select the Button and click the Events tab of the Property Inspector. Click New Event > Quick Start: 'ojAction'   Drop a Call REST Endpoint action under Start. Click Select Endpoint and select Business Objects > LineItem > POST /LineItem. Under Parameters in the Property Editor for the Call REST Endpoint action, click body. Map newLineItem on the left panel to body on the right panel. Click Save. Drag a Fire Data Provider Event under the Call REST Endpoint action. Select {{ $page.variables.lineItemListSDP }} as the Event Target. Set Refresh as the Type.   Drag a Reset Variables action to under the Fire Data Provider Event action. Set $page.variables.newLineItem as the Variables to Rest.   Run and test the app. The next lesson in the Learning Path is Single-Page Master Detail in VBCS.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we create a Master-Detail view over Expense Reports and their child Line Item entries.  Updating Your Project Thi...

Oracle Visual Builder Cloud Service

Pagination in VBCS Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. Most modern UIs use Load More on Scroll pagination rather than a list of pages with next and previous buttons. Also, note that Business Objects have their own "limit" and "offset" URL parameters that are visible in VBCS. We are going to leave those alone and let the component drive the pagination through the scroll-policy-options.fetch-size property on the list view. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Setting Pagination on the List Open main-start. Select the list of Expense Reports. In the All tab of the Property Inspector, set the following: scroll-policy: loadMoreOnScroll scroll-policy-options.fetch-size: 10 scroll-policy-options.scroller: [[document.documentElement]] Some notes about this: If you are using a table instead of a list, it does not support scroll-policy-options.scroller, so you have to set an explicit height to the div that contains the table. If you would like to have a traditional Paging Control on a table or list, you need to use an ArrayDataProvider instead of a ServiceDataProvider, as you cannot bind a Paging Control to a ServiceDataProvider. The next lesson in the Learning Path is Filtering and Sorting Lists in VBCS Applications.

This blog is part of the series Visual Builder Cloud Service Learning Path. Most modern UIs use Load More on Scroll pagination rather than a list of pages with next and previous buttons. Also, note...

Oracle Visual Builder Cloud Service

Filtering and Sorting Lists in VBCS Applications

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, we will add a filter and sort control to our list of Expense Reports. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. If you are starting at this lab, just import the zip file below as a new project. Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Adding a Filter to the List Open the Page Designer for main-start. Drop a Label and an Input Text component in the Toolbar next to the Create/Edit buttons. Change the display text to Filter: Select the input component. In the All tab of the Property Inspector, set the Placeholder to Name. Switch to the Variables panel and select expenseReportListSDP. In the Property Inspector, click filterCriterion and set map the following values to in filterCriterion: item[0] -> attribute: name item[0] -> op: $co Go back to the Page Designer panel. Select the input text component. In the Data tab of the Property Inspector map the Value to {{ $variables.expenseReportListSDP.filterCriterion.criteria[0].value }} Adding a Sorting Control Open the Page Designer for main-start. Drop a Label and a Select One component in the Toolbar next to the Filter component. Set the display text on the Label to Sort By: Select the Select One component, then click the Data tab in the Property Inspector. Then click the + sign next to Sub Elements (oj-ojoption) to add these options: Name: name Start Date: startDate In the General tab, enter an empty space -  " " - in Placeholder. Make sure it is set as an Expression and not as a Static value. Switch to the Variables panel and select expenseReportListSDP. Under Input Parameters click sortCriteria. Enter an empty string - "" - in the sortCriteria > items[i] > attribute. Change the mapping to be an Expression and not a Static String. Go back to the Page Designer and select the Sort By Select One component in the Toolbar. In the Data tab of the Property Inspector, set the Value to {{ $variables.expenseReportListSDP.sortCriteria[0].attribute }} The next lesson in the Learning Path is Client-Side Validations in VBCS Apps.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, we will add a filter and sort control to our list of Expense Reports. Updating Your Project This lesson builds...

Oracle Visual Builder Cloud Service

Single-Page Master Detail in VBCS

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we will look at another popular Master-Detail pattern, which is the single-page master-detail. Here we will create a new page that shows a list of ExpenseReport names on the left and some details of a selected report on the right. Updating Your Project This lesson builds on the Expense Report project we have been using in the VBCS Learning Path. Download this ZIP file to your computer. If you are continuing from a previous chapter and already have the Expense Report project, open the project, click Import, and drag and drop the file into the dialog.   If you are starting at this lab and not continuing from a previous lab, go to the Visual Builder home screen, click Import > Import from File, and upload the ZIP there. Creating the New Flow First we will create a new flow. As you remember, flows are sets of pages that logically belong together. We're going to create a flow that will serve as an administrator's view of all Expense Reports along with some reports. In the Web Apps panel, click the plus sign next to the flows node. Name the flow admin and click OK. Open the admin-start by double-clicking it in the flow editor for the admin flow.   Drop a List View on the page. Use the Add Data Quickstart to bind the list to the ExpenseReport business object and display the name and amount fields. See Building Your First VBCS Application for detailed instructions.  Shrink the List View to only take the left third of the page. You resize components by dragging the little resize handler on the edges of the component. Because the list is loading the entire set of data (we haven't set up pagination yet) you'll have to scroll down to see it. If you don't have enough horizontal space to see the whole list, you can shrink the designer by clicking the zoom button in the toolbar. You can play with the formatting, like removing the name label and expanding the field to take up the full width of the list. Go to the Variables panel for admin-start. In the Types tab, create a Type from Endpoint based on the GET /ExpenseReport/{ExpenseReport_Id} endpoint. Add the name, amount, startDate, and endDate fields to the Type and click Finish. Switch back to the Variables tab and add a variable called selectedReport of type get_ExpenseReport. Switch back to the Designer tab and drag a Form Layout on the right side of the List. Drag and configure the following components into the form: Component Display Text Bound to Property Input Text Name name Currency Amount amount Input Date Start Date startDate Input Date End Date endDate Make all of the components Read Only by selecting them and clicking the Read Only checkbox in the Property Inspector. Select the List View. In the General tab of the Property Inspector switch Selection Mode to single. In the Events tab of the Property Inspector, click New Event > New Custom Event.  Type first in the search box and select first-selected-item. The first-selected-item event passes both the key of the selected row and the data, so we won't have to make a second REST call to fetch the data to populate the form. Click Select.   Click New Action Chain. Drop an Assign Variables action to the chain. Click the Assign link next to Variables.  Select selecteReport in the right panel and map it to $chain.variables.firstSelectedItem.data. Set the mapping to be an Expression. Make sure to remove any surrounding quotes that the wizard enters when you switch from Static Content to Expression.   Right now our ServiceDataProvider (SDP) is only fetching id, name and amount, since that's what's in the list. But our form also displays startDate and endDate. So we have to modify the SDP to also fetch these values. We do so by modifying the SDP's type. Select the admin-start page and open its Variables tab. Click the Types tab, then click Edit form Endpoint. Select startDate and endDate and click Finish. Switch into Live mode and test selecting your different pages. The next lesson in the Learning Path is Pagination in VBCS Applications.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson we will look at another popular Master-Detail pattern, which is the single-page master-detail. Here we...

Oracle Visual Builder Cloud Service

Building your First VBCS Application

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, look at building our first app, the simple Expense Report app. We'll spend a fair amount of time reviewing the artifacts that are created and how we can customize them.  Setting Up the Project Throughout this series we will be working mostly on one project, Expense Reports. We will start small and eventually incorporate everything from complex server-side rules to Process Cloud Service flows. To start with, we will just import a project that contains the Business Objects and an empty web application. Importing the Project Download this ZIP to your computer. Click Import > Import from File Drag the ExpenseReportStarting.zip file into the dialog Give the file any name you want, I suggest ExpenseReport YourName Click Import. Adding the List Click the project to open it. In the left panel, click the Web Applications node. Then expand flows -> main and click main-start. The page opens in the Page Designer. In the list of components on the left, find the List View component. Then drag and drop it onto the page. Select the List View in the Page Designer. (If you have just dropped it in, it will be selected already.) Then open the Property Inspector and select the Quick Starts page.   Under Business Objects, select ExpenseReport and click Next.   Select the second row template and click Next. Select these fields in the left panel of the wizard: name countryObject -> items -> item[i] -> name amount startDate endDate   Change the display for startDate and endDate to Input Date. Click Next. Leave the default settings in the Query panel of the wizard and click Finish. The list in the Page Designer reloads with data. Click the Name label next to the country name and in the Property Inspector, change the Text property to Country.   Adding the Create Page Now we will generate the Create page. Select the List View in the Page Designer. In the QuickStart tab of the Property Inspector, click Add Create Page. In the Select Endpoint page, choose ExpenseReport from the Business Objects and click Next. Add these fields: amount country description endDate justification name startDate Change description and justification to display as Text Areas. Optionally change the Button Label and Page Title to better names. Click Finish. Open the Create page by switching into Live mode and clicking the Create button.   Switch back to Design mode and select the Form Layout component. In the Property Inspector, set Max Columns to 2. Select the Amount field. In the Property Inspector, set the Converter to $ and the Currency Code to USD. Select the Description field and set the Rows property to 4. Do the same for Justification. Rearrange the fields until your app looks like this: Adding the Edit Page           Go back to main-start tab in the editor. Select the List View then open the QuickStarts tab of the Property Inspector. Click Add Edit Page. Select ExpenseReport on both the Read Endpoint and Update Endpoint pages of the wizard. Add these fields: amount country description endDate justification name startDate id Switch the description and justification fields to display as Text Area like you did in the Create page. Optionally change the Button Label and Page Title to friendlier text (i.e. "Edit" and "Edit Expense Report").  Click Finish. Open the Edit Page. Note: When you open a page that takes a mandatory input parameter, like the Edit page for an entry, the editor needs a value for the input parameter, otherwise it will show a 404 error in the editor. You can either switch into Live mode, select a record in the list, and click the Edit button, or you can open the Edit page from the list of pages and use the button and input an ID manually. Delete the id field. Click the Heading and in the Property Inspector change the Text to {{ "Expense Report " + $page.variables.expenseReport.id }} Fix up the rest of the page like we did with the Create page. The next lesson in the Learning Path is Parent Child Master-Details in VBCS.

This blog is part of the series Visual Builder Cloud Service Learning Path. In this lesson, look at building our first app, the simple Expense Report app. We'll spend a fair amount of time reviewing...

Oracle Visual Builder Cloud Service

Variables, Modules, and Functions, OH MY! Custom Client Code in Visual Builder

Not only does the new version of Visual Builder (as of 18.2.5) give you full access to modify your generated client source code it also makes it really easy to create and manage custom code within the client application. This custom code can be accessed and called from other custom code blocks and from visual editors like the action editor. To get the most out of your custom code, it is import to understand 3 key concepts and how they present themselves within Visual Builder.  1) Variables Variables are cornerstone to working with code. With Visual Builder, you will use variables to interact with UI controls, REST interfaces, and general application logic. Visual Builder support standard Javascript types with built in types as well as custom types that can be declared and instantiated as needed.  To create a variable, you use the variables editor found within the designer. It is denoted by a symbol and allows you to quickly create new variables you wish to use within your module. Simply select a type (or create a custom type) and give it a unique name.  2) Modules Variables and Functions are stored within the scope of a Module. Visual Builder presents three types of modules: The AppModule, the FlowModule, and the PageModule. You may also declare a variable within the scope of an Action Chain.  In the below screenshot, the hierarchy of the various module types is visually shown. At the top level, called "custom" in this case, you have your AppModule. An App can contain one or more flows, each with their own FlowModule, and each flow can contain one or more pages, each with their own PageModule. Within a page, there can be several UI events captured and each associated with and action chain. And within each module and/or action, we define our custom variables and functions.    3) Functions To create a custom function, you use the Javascript editor, denoted by the  symbol, for either the app, flow, page, or action. Within each you will see a Module defined that within you can create a custom function. To define the function use the prototype function within the module object. Below is an example of adding a custom function to the AppModule, it takes a string appends some additional text to it and returns that new string.    Putting it all together To put this all together, we are going to create some UI within which we can enter some text, hit a button to call the function and pass that text, then modify the string and bind it to an output control.  To do this we need to use variables, actions, and custom module function. The UI control that takes input is bound to a PageVariable we created within the page.   The output control is bound to the AppVariable we created at the app level.   Now, we create an Action Chain that gets called when the button is pressed. The Action chain calls my custom function and maps that PageVariable to that input.     Then the Action chain assigns the output of that function to my AppVariable.    Since those are already bound to my UI control, they update automatically when the action chain runs.     

Not only does the new version of Visual Builder (as of 18.2.5) give you full access to modify your generated client source code it also makes it really easy to create and manage custom code within...

A New Oracle Autonomous Visual Builder Cloud Service - Visual and Coding Combined

We are happy to announce the availability of Oracle Autonomous Visual Builder Cloud Service (VBCS) - Oracle's visual low-code development platform for JavaScript based applications with built-in autonomous capabilities. Over the past couple of years, the visual development approach of VBCS has made it a very attractive solution to citizen developers who leveraged the no-code required nature of the platform to build their custom applications. Many professional developers also expressed interest in the visual development experience they saw, but they were looking for additional capabilities. Specifically developers were demanding an option to have direct access to the code that the visual tools created so they can change it and enhance it with their own custom code to achieve richer behaviors. With the new VBCS version we are addressing these demands adding direct access to manipulate code, while keeping the low-code characteristics of VBCS. Visual and Code Based Development Combined Just like in previous versions, constructing the UI is done through a visual WYSIWYG layout editor. Existing VBCS users will notice that they now have access to a much richer set of UI components in the component palette. In fact they now have access to all of the components offered by Oracle JET (Oracle's open-source JavaScript Extension Toolkit). In addition you can add more components to the palette using the Web-components standard based Oracle JET composite components architecture (CCA). The thing to note about the visual editor is the new "Code" button at the top right, clicking this button will give professional developers direct access to the HTML code that makes up the page layout.  They'll be happy to discover that the code is pure HTML/JavaScript/CSS based - which will let them leverage their existing expertise to further enhance and customize it. Developers can directly manipulate that code through the smart code editor leveraging features such as code insight, syntax highlighting, doc access, and reformatting directly in their browser. The visual development approach is not limited to page layouts. We extend it also to the way you can define business logic. Defining the flow of your logic is done through our new action flow editor. With a collection of operations that you can define in a declarative way, and the ability to invoke your specific JavaScript code for unique functionality. Now that developers have direct access to the code, we also added integration with Git, leveraging the private Git repositories provided through Oracle Developer Cloud Service (DevCS). Teams can now leverage the full set of Agile methodology capabilities of DevCS when working on VBCS applications, including issue tracking, version management, agile planning and code review processes. Mobile and Web Development Unified With the new version of VBCS we further integrated the development experience across both web browser-based and on-device mobile applications.  In the same project you can create both types of applications, leveraging the same development approach, application architecture, UI components, and access to custom business objects and external REST services. Once you are done developing your mobile application, we'll package it for you as an on-device mobile app that you install, test, and run on your devices - leveraging the native look and feel provided by Oracle JET for the various mobile platforms. Standard-Based Data Openness With the new version you can now hook up VBCS to any REST data source with a few button clicks, leveraging a declarative approach to consuming external REST source in your application. VBCS is able to parse standard Swagger based service descriptors for easy consumption. Even if you don't have a detailed structure description for a service, the declarative dialog in VBCS makes it easy to define the access to any service, including security settings, header and URL parameters, and more. VBCS is smart enough to parse the structure returned from the service and create variables that will allow you to access the data in your UI with ease. Let's not forget that VBCS also lets you define your own custom reusable business services. VBCS will create the database objects to store the information in these objects, and will provide you with a powerful secure set of REST services to allow you to access these objects from both your VBCS and external applications. Visual Builder Cloud Service Goes Autonomous Today’s Visual Builder Cloud Service release also has built-in autonomous capabilities to automate and eliminate repetitive tasks so you can instead focus on app design and development. Configuring and provisioning your service is as easy as a single button click.All you need to do is tell us the name you want for your server, and with a click of a button everything is configured for you. You don't need to install and configure your underlying platform - the service automatically provision for you a database, an app hosting server, and your full development platform. The new autonomous VBCS eliminates any manual tasks for the maintenance of your development and deployment platforms. Once your service is provisioned we'll take care of things like patching, updates, and backups for you. Furthermore autonomous VBCS automatically maintains your mobile app publishing infrastructure. You just need to click a button and we'll publish your mobile app to iOS or Android packages, and host your web app on our scalable backend services that host your data and your applications.  For more about the benefits of Oracle's Autonomous Cloud Services visit this page. But Wait There is More There are many other new features you'll find in the new version of Oracle Visual Builder Cloud Service. Whether you are a seasoned JavaScript expert looking to accelerate your delivery, a developer taking your first steps in the wild world of JavaScript development, or a citizen developer looking to build your business application - Visual Builder has something for you. So take it for a spin - we are sure you are going to enjoy the experience. For more information and to get your free trial visit us at http://cloud.oracle.com/visual-builder    

We are happy to announce the availability of Oracle Autonomous Visual Builder Cloud Service (VBCS) - Oracle's visual low-code development platform for JavaScript based applications with built-in...