Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 22 Next »

 

This information is for building your own HTML forms to import into Forms inMotion.  Typically this information would be used by someone familiar with javascript/css/html development and information about working with those technologies is beyond the scope of this document.

Creating a new HTML form

HTML forms should be HTML5 compliant.  When developing a new form, you should keep in mind how these will be rendered by the Forms inMotion application.  The form itself will be displayed to the end-user inside of an IFRAME element inside the Forms inMotion application's HTML interface.  IFRAME can present unique security restrictive challenges in different browsers so forms should be tested thoroughly before deploying.

All fields should have an ID tag.  Seriously, we key off the ID and it is part of the XML output on the server.  A missing ID tag means that your field will not be represented in the XML output.  You can use the name tag in addition, but Forms inMotion server is only looking for ID.

Querying for external information

Since forms are HTML standard, it is possible to use external AJAX calls to talk to a webservice.  This is acceptable for many public data sources (Google Maps, data.gov, etc.) but not ideal for private sources.  For these, the recommended approach is to use the internal query API.  This requires a few things to configure so an example follows:

Step 1) Configure the query on the server.  The query information and connection string are all contained in the web.config file for the FormsServiceJSON.asmx.  There should be a queryDefinitions section inside your formsinMotionConfiguration section of the web.config.  There should also be a connectionstring in the normal web.config connectionstrings section for each of your queries.  

As you can see in the examples below, each query is contained inside a queryDefinition node.  Attributes for name, querytext and connectionstringname are required.  connectionstringname must match one of the configured connectionstrings in the connectionstrings section.  Parameters are optional, but an empty parameters node should be included.  If parameters are used, make sure that they match the parameter name used in the query exactly and begin with an @ symbol on SQL Server queries.  

web.config
<formsinMotionConfiguration>
 
...
 
      <queryDefinitions>
		<queryDefinition name="departmentsForWhichYouCanProxy" querytext="select ADUserName,Department from dbo.ADDepartment where ADUserName = @username" connectionstringname="onbasetest" >
          <parameters>
          </parameters>
        </queryDefinition>
		<queryDefinition name="testqueryOne" querytext="SELECT * FROM cc_SSN_AutoFill_vw where (SSN = @ssn or CCN = @casenum) and DOB = @dateofbirth" connectionstringname="onbase" >
          <parameters>
			<parameter name="@ssn" datatype="String" />
			<parameter name="@casenum" datatype="String" />
			<parameter name="@dateofbirth" datatype="DateTime" />
          </parameters>
        </queryDefinition>
		<queryDefinition name="currentUserID" querytext="select ADUserName,UID from dbo.ADUser where ADUserName = @username" connectionstringname="onbasetest" >
          <parameters>
          </parameters>
        </queryDefinition>
		<queryDefinition name="userIDFromEmpID" querytext="select ADUserName,UID from dbo.ADUser where UID=@employeenum" connectionstringname="onbasetest" >
          <parameters>
			<parameter name="@employeenum" datatype="String" />
          </parameters>
        </queryDefinition>
      </queryDefinitions>
    </formsinMotionConfiguration>
...
 
<connectionStrings>
    <add name="formsserver" providerName="System.Data.SqlClient" connectionString="Data Source=SQLVMD11,1517; Initial Catalog=Forms_inMotion_V2;User Id=Forms_inMotionUser;Password=formsinMotionPass"/>
    <add name="advantage" providerName="System.Data.OracleClient" connectionString="Data Source=servername;User id=tst;Password=mypass;"/>
</connectionStrings>

@username parameter

Note that in the querytext, it is possible to use a parameter in your query called @username. This is a special parameter that will be automatically replaced on the server side with the username of the logged in user who performed the query.

 

Step 2) Performing the query inside your form.  The query is performed by calling a native API function inside your javascript called Forms_inMotion.  Your parameters will be passed into the function as an array.  You also must specify the callback javascript function that will receive the results of the query.  An example is below.  Here we initialize a new parameters array.  Add a single parameter (note that the @ syntax persists here as well) at the 0th position.  This parameter value is a JSON object with keys for name and value.  Then the function is called

Forms_inMotion("query", "<yourCallBackFunctionName>","<nameOfQueryToExecuteOnServer>",parameters_array, responsetype);

var parameters = [];
parameters[0] = { name:"@employeenum",value:empID };
Forms_inMotion("query","userNameLookupCallback","userIDFromEmpID", parameters, "xml");

 

Step 3) Handling the callback.  The data object that is returned is an XML document.  The below example shows using the native JavaScript parser, loading the response into an object called xmlDoc, then looping through the "record" nodes that are returned.  Each record node represents a single line of results from the query.  Each column of the query is an attribute on that record node.

function userNameLookupCallback ( data ) {
	var parser = new DOMParser();
	var xmlDoc = parser.parseFromString(data, "application/xml");
	var recordNodesList = xmlDoc.getElementsByTagName("record");
	var j;
	var recordCount = recordNodesList.length;
	if (recordCount>0) {
		for (j=0; j<recordNodesList[0].attributes.length; j++) {
			switch (recordNodesList[0].attributes[j].nodeName.toUpperCase()) {
				case "ADUSERNAME" :
					$("#employeeid").val(recordNodesList[0].attributes[j].nodeValue);
				return;
			}
		}
	}
}

For reference, an example of the return xml format that will be inside the data object can be seen below:

<?xml version="1.0"?>
<xml>
  <results>
    <record authnum="3520049" fname="JOHN" lname="SMITH" AMT="723.40" sdate="11/17/2014 12:00:00 AM" apr="" empid="108594"/>
    <record authnum="3520050" fname="JOHN" lname="SMITH" AMT="723.40" sdate="11/17/2014 12:00:00 AM" apr="" empid="108594"/>
    <record authnum="3520051" fname="JANE" lname="SMITH" AMT="723.40" sdate="11/17/2014 12:00:00 AM" apr="" empid="108594"/>
    <record authnum="3520052" fname="JANE" lname="SMITH" AMT="723.40" sdate="11/17/2014 12:00:00 AM" apr="" empid="108594"/>
    <record authnum="4374468" fname="JOHN" lname="SMITH" AMT="" sdate="7/25/2015 12:00:00 AM" apr="" empid="108594"/>
  </results>
  <recordcount>5</recordcount>
</xml>

 

Using application level popups from your form

In places where you may typically use javascript "alert()" to show a message to your user, you cannot do so from your custom forms inside Forms inMotion.  This is for 2 reasons:

  1. The popup occurs at the application level and halts execution of that thread which can cause problems in some browser environments
  2. The popup may appear to come from the application when it does not so it might be confusing to the user

The solution to this is a built in function call that you can use in the same way that the query API is called above.  This is the alert call.

Alert API
var parameters = [];
Forms_inMotion("alert","Your alert text goes here","", parameters);

 

As you can see it still goes to the same function as the query so make sure to include the empty string and empty parameters array after your call to the alert function and your message.

Function calls when the document is loaded in the application

DocumentLoadCall deprecation

See the following article. The DocumentLoadCall() function should not be used for versions more recent than 2.6.11. Your end users will see a warning about this if the DocumentLoadCall function is still present in those versions. DocumentLoadCall deprecation


  • The Forms inMotion application will call into the frame once your form is completely loaded.  The function we are looking for is called PreDataLoad().  It should be defined like this:
PreDataLoad
function PreDataLoad() {
	//your important loading stuff here
}
  • If this function is present in your custom HTML, the application will wait for this function to return true before proceeding
  • After PreDataLoad() is complete, the application will inject the elementData field information.  This information will be present when reloading a saved form or when loading a forwarded form.
  • After the field data has been loaded, you can perform additional formatting or configuration with the PostDataLoad() function.
  • If the PostDataLoad() funciton is present in your custom HTML, the application will wait for the function to return true before proceeding


Another way to use these functions for testing OUTSIDE your Forms inMotion environment is to trigger your functions with jQuery .ready events such as below.
PreDataLoad Example
var alreadyLoaded = false;

$(document).ready(function() {
	PreDataLoad();
});

function PreDataLoad() {
	if (alreadyLoaded) {
		return;
	}
	alreadyLoaded = true;
	//your important loading stuff here
	PostDataLoad();
}


function PostDataLoad() {
	//your important post loading formatting stuff here
}

PreDataLoad/PostDataLoad

Notice in the above example the boolean flag to prevent executing the load call twice when it's been loaded into the Forms inMotion environment.  You should definitely implement this behavior to prevent HTML strangeness.

Data Validation Before Submission

It is also possible to include a function in your form that will run your own validation routines before submission.  If we don't find this function, we'll assume validation passed and continue submission.  The function must be named

VerifyFormDataCall

This can return true or false whether or not the validation passed.  A validation failed notification will be displayed if false is returned and submission will be cancelled.

 

Electronic Signature Inputs

  • Canvas elements for signatures also need to have an ID tag.  If you want additional description data for them to appear in the signatures box, include it as a data-signatures field like this.
Canvas Signature Element
<canvas style="width:550px; height:150px; " id="Signature" data-signature="Signature space for delivery"></canvas>

Using external includes in your form

  • Consider the behavior of external includes in your form.  HTML forms are injected into iframes in order to be properly displayed in the Forms inMotion application. IFRAME behavior can be heavily restricted by the browser's security implementation.  External includes should always be made using the same protocol of your hosted Forms inMotion server (if your server address is https://yourserver.com/FormsinMotion/) then make sure that your external references all use https as well!  It may be easier to include things like jQuery, BootStrap, etc. directly in your code instead to prevent external includes problems.
  • Fields should be defined as follows.  Non-standard or non-HTML5 implementations may prevent the form from being submitted.  You can wrap these things with labels or DIVs to make them conform to your style preferences, but the field definition must be as follows:
Field Types
<input id="myinputname" />
<input id="mycheckbox" type="checkbox" />
<input id="myradio" type="radio" />
<select id="myselectbox"><option value="stuff">Stuff</option></select>
<textarea id="mytextarea"></textarea>

 

Using the Attach API

button type

When using the <button> directive in HTML the default behavior type is "submit". You MUST use the phrase 'type="button"' or your button will attempt to submit the entire form to the application. This will cause an error.

 

  • You can trigger the application level file attachment API using the following syntax

    Field Types
    <button type="button" data-attach="[attachment name]" id="[something]">Upload</button>
  • If you would like to trigger a callback after the file has been loaded, you can add an additional data property. You only need to include the function name and Forms InMotion will add the (filename) parameter.

    <button type="button" data-attach="[attachment name]" data-attach-callback="[function name in your script]" id="[something]">Upload</button>


    Note that the callback will receive the attached file name as the first parameter.  In this example, the callback will use that information to write data into a div and also disable the original upload button:

    function attach_resume_callback(filename) {
    	$("#resume_results").html("Resume attached successfully. File name was: " + filename);
    	$("#resume").prop('disabled','disabled');
    }

Other Button APIs

button type

When using the <button> directive in HTML the default behavior type is "submit". You MUST use the phrase 'type="button"' or your button will attempt to submit the entire form to the application. This will cause an error.

In addition to the attachment described above, you can also trigger application behavior through a few other custom button types in your form.  Those are:

 

    • Submit

      Field Types
      <button type="button" data-submit="" id="[something]">Submit Package</button>
    • Scan

      Field Types
      <button type="button" data-scan="" id="[something]">Scan</button>
    • Previous form

      Field Types
      <button type="button" data-previous="" id="[something]">Previous</button>
    • Next form

      Field Types
      <button type="button" data-next="" id="[something]">Next</button>

Notes on Form Design

  • Be sure to set your body to a non-relative size in pixels. Your form is framed into the application using an iframe, so CSS VH or VW units do not work properly. If your body is set to 100% width or height, make sure that all of the elements in the DOM have a set height so your page is rendered properly.

  • No labels