Chapter 4. Forms

4.1. Integrating Forms Into A Cordova App

Forms functionality can be integrated into existing apps. This guide demonstrates the integration on an example of a workforce management application — a supervisor assigns jobs, a worker receives the assignments on their mobile device, and sends back information about the job.

The procedures in this guide use a Cordova app and a Cloud App. These apps can be imported into a project to demonstrate the working example described in this guide.

4.1.1. Working Example

4.1.1.1. Overview

The following requirements are set for the example application:

A supervisor creates a job for a worker to remove a fallen tree after a storm. The supervisor asks the worker for details of the job such as photos of the tree, location, comments, and the time started and finished. This can be achieved using forms apps.

The supervisor creates a job by:

  • Selecting the form for the worker to complete.
  • Selecting and filling out a form with the details for the job.
  • Giving the job a unique ID.

The requirements for the application include:

  • Jobs are created by an admin by filling out a creation form.
  • New jobs are available to both admin and non-admin users. App users can view the completed creation form.
  • App users can complete a job by filling in a separate completion form.
  • The completion form must be visible to any app user to review.
  • The Client App user can mark the job as either "In Progress" or "Complete" by saving the completion form as a draft.

4.1.1.2. Cordova App

The Client App is based on the following technologies:

  • Backbone: The Cordova app uses backbone models and views to manage the creation and update of jobs.
  • Handlebars: Used for view templating.
  • Boostrap: Used for styling.
  • Font-Awesome: Used for icons.

The Cordova app is responsible for:

  • Managing the listing of jobs in various states.
  • Managing the rendering of any forms.
  • Managing the submission and upload of any form submissions.
  • Managing the creation of jobs containing form and submission data.
4.1.1.2.1. Job Model

The job model is a simple Backbone model describing a job.

The jobs collection is a collection of job models.

A custom URL is included for synchronizing jobs between the client and cloud. This custom URL is used to access RESTful /jobs endpoints on the Cloud App.

4.1.1.3. Cloud App

The Cloud App consists of RESTful endpoints (/jobs) for performing CRUD operations on job data using the $fh.db API.

Note

There is no visible logic in the Cloud App to deal with forms, because all cloud-based forms logic is contained in the cloud APIs.

4.1.2. Creating A Working Example

  1. Create a new project in the App Studio.
  2. Import an app into your project. For example, the examples in this guide use the Cordova app and Cloud App.
  3. Create forms and themes for the project. Any created forms and themes associated with the project will now be visible in the Cordova app.
  4. Optionally, add users and field codes to the project. For example:

    • Admin: Able to create and complete jobs.
    • User: Able to complete jobs.

    A user has the userId and userName fields that are automatically added to a submission before rendering the related form. Add two text fields to any forms associated with this working example.

    When the fields have been added, add two users to the users collection in your Data Browser.

    Admin

    {
        "userId": "admin",
        "userName": "<<Any Name>>"
    }

    User

    {
        "userId": "user",
        "userName": "<<Any Name>>"
    }

4.1.3. Implementation Guide

Use the following to integrate forms functionality into an app.

  1. Add Forms Initialization by adding the $fh.forms.init function to the client. This initializes forms on the Client App to enable the usage of the $fh.forms Client API in the rest of the app.

    The $fh.forms.init function is part of the log in process for the app.

  2. As an admin user, select a completion form. This specifies the form that needs to be completed in order to complete the job. List all of the forms available to the app using the $fh.forms.getForms Client API function.

    Note

    The $fh.forms.getForms Client API call only downloads a list of forms, it does not download the entire form definition for each form.

  3. Download a form to the client using the $fh.forms.getForm Client API.

    As forms are used in job creation, viewing job details, and completing jobs, this function is abstracted to a set of helper functions here.

    The $fh.forms.getForm client API usage can be seen here as part of the loadForm function in FormFunctions.js.

  4. Load a submission into your app. This process is illustrated using the loadSubmission function in the FormFunctions.js file.

    Forms are related to submissions, in that any data entered into a form is populated to a submission. However, a submission is validated against a form before being upload to the cloud.

    There are three ways to create a submission:

    • From Local Memory: Save a submission as a draft to local memory then edit later using the saveDraft function on the submission model. The implementation of this functionality is shown in the loadLocalSubmission function.
    • Download From Remote: Download a submission from the cloud. For example, when the supervisor completes a form to describe the details of the job, the ID of the submission is saved to the job model. When the app user downloads the job model, they have access to the remote submission ID of the form submitted by the admin user. This remote submission ID is used to download the full submission definition from the cloud. The implementation of this functionality is shown in the downloadSubmission function.
    Note

    The form definition for the submission is contained in the submission downloaded from the cloud. This is because the form definition may have been edited between submissions.

    Note

    Downloaded submissions should not be edited on the client. They are intended for read-only access. Any attempt to submit a downloaded submission to the cloud will return an error.

    • Create A New Submission: If there is no submission associated with a form, a new submission can be created. In this case, the submission is created from a form model. This ensures that the submission is automatically related to the correct form.
  5. Render the form into the view for editing by a user.

    There are two methods of rendering a form into an existing Cordova app:

    • Rendering the form using the $fh.forms.backbone API, which includes a backbone/bootstrap SDK ($fh.forms.backbone), by downloading the Appforms Backbone file and include it as part of your Cordova app. In addition, the Cordova app must satisfy the following JavaScript and CSS dependencies:

      • Backbone
      • Bootstrap
      • Font-Awesome

      The CSS and JavaScript dependencies are included in the example Cordova app.

      The FormViewSDK.js file contains the Backbone SDK version of the form view. The Cordova app contains an option in the "Settings" tab to switch between the Backbone SDK and manual form rendering.

      Note

      The Backbone SDK is intended to speed up forms apps integration for Backbone/Bootstrap based Cordova apps. However, the $fh.forms Client API will work with any Cordova app. The rendering of the form and managing the population of user data to a submission will be the responsibility of the developer.

    • Rendering a form manually.

      Note

      Rendering a form to the user is the simplest method of completing a submission. However, field input values can be added to a submission from any source. The submission is still required to be valid against any field or page rules.

      The $fh.forms SDK does not depend on any framework, and can therefore be added to any Cordova app. This app is based on Backbone and Bootstrap, however it is equally possible to use the $fh.forms API with other javascript-based UI frameworks (for example, Angular).

      A basic Bootstrap form is rendered based on the form definition. This form is defined in the FormView.js file. All of the rendering, submission input, and validation logic of the form is defined in the app using the $fh.forms API and models.

      Note

      The manually rendered form is implemented for illustration purposes only. Only the text and number fields are manually implemented. However, all available form field types can be rendered using the $fh.forms.backbone SDK.

      The rendering logic for the custom form view is located in the FormView.js file. Here, you can see that the view handles all of the events related to rendering the form to the user.

      In addition, the FormView.js file contains logic for:

      • Validating field data when entered.
      • Checking field and page rules.
      • Populating data to a submission.
      • Saving a submission as a draft.
      • Submitting a form to the cloud.

      The following steps illustrate how the Cordova app addresses these requirements when manually integrating the $fh.forms SDK into a custom rendered form.

  6. Define the validation parameters that restrict the data that can be entered into the field (for example, a text field can specify a minimum/maximum number of characters that can be entered into the field). Adding this functionality to the Client App reflects the restrictions of the field.

    To satisfy this requirement, the validateInput function is registered to the blur event of an input in the FormView.js file.

    Note

    Validation parameters influence whether a submission is valid. Even if field validation is not performed on the Client App, all submission fields will be validated before saving to the database.

  7. Form apps include field and page rules. In the Studio, forms editors can create field rules to show and hide fields based on field input data and page rules to show and skip pages based on field input data.

    This functionality is reflected in the implementation of the $fh.forms API. By processing a submission using a rules engine, the submission can identify fields or pages that need to be shown or hidden.

    This is implemented in the checkRules function in the FormView.js file.

    Note

    Field and page rules influence whether a submission is valid. Even if field and page rules are not checked on the Client App, the submission will be checked against all rules before saving to the database.

  8. Add data to a submission model using the addInputValue function. The source of this data can either be the form rendered to the user, external data available to the app, or a mixture of both.

    • From a rendered form: In this case, a form is rendered for the user to input data using the $fh.forms.backbone SDK or by manually rendering a form.

      When manually integrating the $fh.forms API into a custom rendered forms, it is necessary to handle the migration of data from the view to the submission model.

      This is illustrated by the saveFieldInputsToSubmission function in the FormView.js file.

    • From an external source using field codes: You can add field codes to form fields to uniquely identify a field within a form. This field code can relate to an external data source (for example, a header in a CSV file). Using this functionality, it is possible to import external data into a form submission.

      This functionality is demonstrated in the example Cordova app by the addSubmissionData function. In this example, a user has userId and userName fields. If a form contains fields with fields codes userId and userName, these fields will be populated with the data from the User model.

      Note

      Field codes must be unique within a form. However, the same field code can be present in multiple forms.

  9. Save a submission as a draft. This functionality is illustrated by the saveDraft function in the FormView.js file.
  10. Having added validation and rules functionality to the form, we can now submit valid submissions to the cloud for viewing/editing on the submission editor.

    The form view listens for submission-related events (validationerror, queued, progress, error, submitted) emitted by the submission model as the data is being processed and uploaded.

    The submission process has two distinct steps:

    • Submit: Calling the submit function on a submission model validates the submission against the local form definition and changes the submission status to pending.
    • Upload: Calling the upload function on a submission model will queue the submission for upload to the forms database.

4.2. Enabling Forms Support in OpenShift 2 Targets

Support for using Forms in Cloud Apps deployed to OpenShift 2 targets is not immediately available. It can be enabled by following the steps outlined in this document.

Note

This guide only applies to Platform instances with support for OpenShift 2 targets, for example openshift.feedhenry.com. Other targets have Forms support available without any extra configuration.

4.2.1. What’s behind Forms in the Platform

There’s a service in the back end of the Platform responsible for handling Forms-related operations, called fh-mbaas. Its functions are exposed through the $fh.forms API and include access to form definitions, submissions and deployment of forms.

With Red Hat MBaaS targets an instance of the fh-mbaas is always available and doesn’t need to be manually enabled. This is however not the case for OpenShift 2 targets which, by default, don’t have the fh-mbaas service deployed. This functionality is provided separately as a service template in the Platform which can be deployed to an OpenShift 2 target to enable Forms support.

fh-mbaas OpenShift application

On the OpenShift side the Forms support is implemented through a cartridge. This cartridge is hosted, along with a Node.js runtime and database cartridges, in a separate application in your OpenShift account and exposes its functionality to all of your Forms-based applications.

4.2.2. How to enable Forms support for OpenShift 2 targets

Prerequisites:

  • a RHMAP account with support for OpenShift 2 targets
  • an existing OpenShift 2 target and an associated environment

The following steps will guide you through the process of enabling your app to use Forms in an OpenShift 2 target:

  1. Create and deploy an instance of the OpenShift mBaaS Service.

    1. In the Services & APIs section of the Studio, click Provision MBaas Service/API
    2. From the list of available services, choose OpenShift mBaaS Service, enter any suitable name for the service instance and click Next
    3. Wait until the log window shows Service is ready! and click Finish. The Service Details page will be displayed.
    4. Navigate to the Deploy section in the left-hand side menu
    5. Select an appropriate OpenShift-backed environment from the dropdown menu on the right-hand side of the screen
    6. Click Deploy Cloud App
    7. Wait until the service gets deployed. In the Deploy History section at the bottom of the screen, the deployment status and result are displayed. It might happen that these indicators don’t reflect the immediate state. Reload the page to update the status and check that the correct environment is selected. After the deployment is finished, reload the page again and check that there’s a Current Host field in Deploy Options at the top of the screen.

      Note

      It may take several minutes for the service to get deployed, as this involves creating a gear, provisioning several cartridges, cloning a git repository and other setup operations. This is only performed once for an OpenShift 2 target. Similarly, the first deployment of a Cloud App might take longer than any subsequent deployments.

      Deploy History of a service

    8. Write down or copy the value of Current Host field of the Deploy Options section of the screen. The URL points to the newly created OpenShift application which acts as the fh-mbaas service.

      Current Host of a deployed fh-mbaas service

  2. Set the correct fh-mbaas host URL in an OpenShift 2 target.

    1. Navigate to the Admin / MBaaS Targets section of Studio and open an existing OpenShift 2 MBaaS target.
    2. Enter the URL of the fh-mbaas service that you saved earlier into the fh-mbaas Host field.
    3. Click Save MBaaS.

Any Cloud App deployed to this new OpenShift-backed environment will have access to Forms functionality.

A single fh-mbaas service can be used to provide Forms support to multiple OpenShift 2 MBaaS targets and can reside on a different OpenShift instance than the OpenShift 2 MBaaS targets using it. Cloud apps using Forms can be deployed to any OpenShift 2 target as long as that target has a valid fh-mbaas Host set.