Client Builder Tutorial

Tutorial Overview

This tutorial guides a developer through lessons in the using the Client Builder feature of VANTIQ Modelo. Clients are browser-based web applications with (a) the ability to display data stored in the VANTIQ system in a variety of forms (graphs, gauges, tables) and (b) accept data from the user of the client either to be displayed and/or stored in the VANTIQ system. The Client Builder allows the developer to write small amounts of Javascript which implements the logic behind the client, such as responses to button pushes and data entry.

The tutorial lessons show the developer how to create a simple invoicing client application. This client displays a form to create and submit a simple invoice, displays a table which dynamically updates the last five submitted invoices, and displays a gauge which dynamically displays the sum of the last five submitted invoices.

All lessons assume the developer has a working knowledge of VANTIQ Modelo. It is recommended that a new developer completes the lessons in the Introductory Tutorial before starting the lessons in this tutorial.

1: Creating a Client Builder Project

The first task is to create a project in Modelo to assemble all the client components.

Use the Projects button, select Create New Project and title the project “Invoice”:

        ClientProject

The rest of the lessons take place inside this Modelo project.

2: Creating a Data Type

The invoice client needs to store invoice data input by the user in the VANTIQ system. You must create a data type to specify that data.

Use the Add button to select Type…:

        AddType

Use the New Type button to create the invoice data type:

        CreateInvoice

The Invoice type contains six properties:

The invoice client creates the ID and timestamp properties using Javascript. The user of the invoice client will manually enter all other properties.

Once the six properties are defined, use the Save button to save the Invoice type. Use the Save button at the top, left of Modelo to save the project.

3: Creating the Invoice Client

This lesson uses Modelo’s Client Builder feature to create our invoice client.

Use the Add button to select Client…, then use the New Client button to display the New Client dialog:

        NewCB

Enter “Invoice” as the Client Name and use the default Design for browser radio button since we’ll be running our client in a browser. Use the OK button to display the Client Builder:

        NewCB

The rest of the lessons take place inside this Client Builder.

4: Creating the Client Invoice Form

The next task is to create the invoice data entry form. This is multi-step process and demonstrates concepts of the Client Builder common to many clients.

First, we’ll need to create a new Data Object for the client. Data Objects define Javascript variables that are referenced by the client. In this invoice client, we need to define one Data Object which is used to hold the invoice properties (firstName, lastName, etc.) the user enters. To create a new Data Object, use the Data Objects button to display the ‘Editing Data Object’ dialog:

        DataObjects

Use the Choose Type pull-down menu to select Invoice, then use the Add a ‘Typed Object’ based on Type: button to add the new Invoice property to the list of Data Objects. By creating the Invoice property, any Javascript may now reference the Invoice variable using the following syntax: page.data.Invoice. (page.data is the client’s syntax prefix to reference the data object associated with the client.)

Second, we’ll use the Client Builder to automatically create a data entry form based on the Invoice properties. Use the Generate Widgets icon, which is found under the –Actions– menu heading and looks like a small lightning bolt. The Generate Widgets process creates two data entry widgets for each property of the Invoice type (a text widget which is the name of the property and an edit widget which allows for the actual data entry) plus a container widget to hold the data entry widgets.

Use the Save and Exit button to save the new Invoice Data Object.

        InvoiceForm

Third, we’ll edit the data entry form to make it a little more user friendly. Since we’ll use Javascript to automatically generate the invoice ID and timestamp properties, delete those widgets from the client display. Select the timestamp title widget by tapping on it then use the Delete button just above the palette of widgets to delete the title. In the same manner, select and delete the timestamp data entry widget, the ID title widget, and the ID data entry widget.

Next, change the titles of the remaining widgets. To change the title of the amount widget, tap on that title, then edit the Text property to contain “Amount”. In the same manner, change the titles of the description, firstName, and lastName title widgets to “Description”, “First Name” and “Last Name”. Finally, drag and drop the Last Name title widget and its data entry widget so they are directly under the First Name widgets. The data entry form should now look like this:

        InvoiceFormEdit

Fourth, add a button to the form to submit the invoice data. To add the Submit button, drag the Inline widget palette tile and drop it just under the Last Name title in the form. By default, the button is titled ‘Click Me’. Tap the ‘Click Me’ button to display its property sheet:

        SubmitButton

Change the Button Label field to “Submit”. Next, tap the <None> field titled On Click to display the ‘Edit Javascript’ dialog:

        SubmitJavascript

This dialog is where we enter Javascript that is executed whenever the user taps the Submit button. For our invoice client, we want to generate values for the ID and timestamp properties, validate some user-provided invoice properties, and submit the invoice data to the VANTIQ system:

    // generateUUID is used to create a unique ID to use as the invoice ID
    generateUUID = function() {
        // http://www.ietf.org/rfc/rfc4122.txt
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++)
        {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
        s[8] = s[13] = s[18] = s[23] = "-";

        var uuid = s.join("");
        return uuid;
    };

    if (!page.data.Invoice.lastName || (page.data.Invoice.amount === 0)) {
        client.errorDialog("Please enter Last Name and Amount values!");
    } else {
        // programatically generate a timestamp and ID for our invoice
        page.data.Invoice.timestamp = new Date().toISOString();
        page.data.Invoice.ID = generateUUID();

        // create a VANTIQ database connection to insert our new invoice
        var http = new Http();
        http.setVantiqUrlForResource("Invoice");
        http.setVantiqHeaders();
        http.insert(page.data.Invoice, null, function(response) {
            client.infoDialog("Invoice " + page.data.Invoice.ID + " submitted.");            
        }, function(errors) {
            client.errorDialog("Submit fails: " + JSON.stringify(errors));
        });
    }

Use the OK button to save the Javascript and return to the property sheet.

Fifth, add a button to the form to reset the invoice data. To add the Reset Form button, drag the Inline widget palette tile and drop it to the right of the Submit button. Tap the new ‘Click Me’ button to display its property sheet:

        SubmitButton

Change the Button Label field to “Reset Form”. Next, tap the <None> field titled On Click to display the ‘Edit Javascript’ dialog:

        SubmitJavascript

This dialog is where we enter Javascript that is executed whenever the user taps the Reset Form button. For our invoice client, we want to reset the data entry form fields:

    page.data.Invoice.firstName = page.data.Invoice.lastName = page.data.Invoice.description = "";
    page.data.Invoice.amount = null;

Use the OK button to save the Javascript and return to the property sheet.

The data entry form should now look like this:

        InvoiceFormEdit

5: Creating a Recent Invoices Table

The next task is to create a table that displays the last five entered invoices. This is a two step process: (1) creating a Data Stream which is used to retrieve invoice data and (2) creating a table to display the data.

First, create a Data Stream. Use the Data Stream button to display the ‘Edit Data Stream’ dialog, then use the New Data Stream button to create the new Data Stream:

        InvoiceDataModel

Select the On Timed Query option then title the Data Stream “Invoice Queryable”. A Timed Query Data Stream means that the client will retrieve data from the VANTIQ database on a periodic basis. Select Invoice as the ‘Data Type’ since we want to retrieve invoice data. Enter 15 as the ‘Update Interval’ to retrieve the invoice data every 15 seconds. Since the goal is to create a table that displays the last five entered invoices, enable the Limit maximum number of records to return and enter ‘5’. Then select timestamp as the ‘Sort By’ property (since we want to sort by when the invoice was created) and, finally, enable Sort Descending so the top entry in the table will be the most recent invoice. Use the Save button to save the Data Stream.

Second, create a table to hold the recent invoice data. To add the table, drag the Table widget palette tile and drop it to the right of the data entry form. Tap the new table to display its property sheet:

        Table

Use the Data Stream pull-down menu to select Invoice Queryable, our recently created Data Stream. Use the Columns property to display the ‘Edit Columns’ dialog:

        ConfigureTable

Use the right arrows to add all six properties of the Invoice type as table columns, then use the OK button to save the column configuration.

6: Creating a Recent Invoices Gauge

The next task is to create a gauge that displays the sum of the last five entered invoices. This is a four step process: (1) creating a new Data Object to hold the sum, (2) creating a new Data Stream that uses the Data Object, (3) creating the gauge to display the data and (4) adding Javascript to compute the sum.

First, create a Data Object. To create a new Data Object, use the Data Objects button to display the ‘Editing Data Object’ dialog:

        InvoiceDOSum

Select client.data from the uppermost pull-down menu since our upcoming Data Stream may only reference client.data Data Objects. Use the Add a Property button to add the new Data Object: enter sumLastFive as the Property Name, select Typed Object from the DataType pull-down menu, and enter sumLastFive as the Default Label. (Please refer to the Client Builder User’s Guide for more information about Typed Objects.) The sumLastFive Data Object is now present but we need to add one field to hold the actual invoice sum. Use the Edit Typed Object icon, which is found under the –Actions– menu heading and looks like a small pencil:

        InvoiceDOSumProperty

Use the Add a Property button to add the new Typed Object property: enter value as the Property Name, select Real from the DataType pull-down menu, and enter value as the Default Label. The value property of the sumLastFive Data Object will be used to hold the sum of the recent invoices. Use the OK button to save the value property, then use the Save and Exit button to save the sumLastFive Data Object.

Second, create a Data Stream which is used to send data events to the gauge. To create a new Data Stream, use the Data Streams button to display the ‘Edit Data Stream’ dialog:

        InvoiceDSSum

Select the On Client Event option then title the Data Stream “Invoice Sum”. Select Get schema from client.data.object then select client.data.sumLastFive from the Data Object pull-down menu. This data stream now references the sumLastFive Data Object we created in the previous step. Use the Save button to save the Data Stream.

Third, create a gauge to display the invoice sum. To add the gauge, drag the Gauge widget palette tile and drop it under the invoice table. Tap the new gauge to display its property sheet:

        Gauge

Use the Data Stream pull-down menu to select Invoice Sum, our recently created Data Stream. Use the Data Stream Property pull-down men to select value. Since we’re anticipating high-value invoices, enter the following property values:

Fourth, modify our submit Javascript to sum the recent invoices then send the Client Event to update the Data Stream. Tap the Submit button in the data entry form. Next, tap the Click to Edit field titled On Click to display the ‘Edit Javascript’ dialog:

        SubmitJavascript

Here is the modified Javascript which includes summing the recent invoice values and sending the client event to the Invoice Sum Data Stream:

    // generateUUID is used to create a unique ID to use as the invoice ID
    generateUUID = function() {
        // http://www.ietf.org/rfc/rfc4122.txt
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++)
        {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
        s[8] = s[13] = s[18] = s[23] = "-";

        var uuid = s.join("");
        return uuid;
    };

    if (!page.data.Invoice.lastName || (page.data.Invoice.amount === 0)) {
        client.errorDialog("Please enter Last Name and Amount values!");
    } else {
        // programatically generate a timestamp and ID for our invoice
        page.data.Invoice.timestamp = new Date().toISOString();
        page.data.Invoice.ID = generateUUID();

        // create a VANTIQ database connection to insert our new invoice
        var http = new Http();
        http.setVantiqUrlForResource("Invoice");
        http.setVantiqHeaders();
        http.insert(page.data.Invoice.values, null, function(response) {
            // the invoice was saved, now query for the last five invoices based on timestamp
            client.infoDialog("Invoice " + page.data.Invoice.ID + " submitted.");
            var parameters = {
                "limit":5,
                "sort":{"timestamp":-1}
            };
            http.select(parameters, function(response) {
                // sum the amounts of the last five invoices
                client.data.sumLastFive.value = 0;
                for (var i = 0; i < response.length; i++) {
                    client.data.sumLastFive.value += response[i].amount;
                }
                // create a client event for widgets listening on the Invoice Sum data stream
                client.sendClientEvent("Invoice Sum", client.data.sumLastFive);
            }, function(errors) {
                client.errorDialog("Select fails: " + JSON.stringify(errors));
            });
        }, function(errors) {
            client.errorDialog("Submit fails: " + JSON.stringify(errors));
        });
    }

Use the OK button after adding the modifications to save the Javascript and return to the property sheet.

Our simple invoice client is complete and should look like this:

        FinalClient

Use the Save button to save the client and return to the Modelo project. The Project Resources Graph will look similar to this:

        PRG

7: Running the Client

The last lesson of this tutorial is to run the client, entering sample invoices and watching the invoice table update. Click the Client: Invoice oval in the Project Resource Graph to display the Client Builder, then use the Run icon button of the Client: Invoice pane (small triangle in a square at the top, right of the pane):

        RunClient

To create a new invoice, add values to the Amount, Description, First Name, and Last Name fields, then use the Submit button to submit the invoice. After entering several invoices, the client display will look similar to this:

        RunClient

Use the Stop Running icon button of the Client: Invoice pane (small square in a square at the top, right of the pane) to end the client session.