Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added info on data-signature-ignore attribute

Table of Contents

 


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.

Sample form code can be downloaded from Github.

Creating a new HTML form

...

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.  

Code Block
languagexml
titleweb.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>
Info
title@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);

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

 

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.

Code Block
languagejs
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:

Code Block
languagexml
<?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.

Code Block
languagejs
titleAlert 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.

AnchorDocumentLoadCallDocumentLoadCallQuery API as documented in the article "Using the Query API".  


Anchor
alertapi
alertapi

Function calls when the document is loaded in the application

...

titleDocumentLoadCall deprecation

...

  • The

...

  • 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:

...

  • 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.

Code Block
languagejs
themeRDark
firstline1
titlePreDataLoad Example
linenumberstrue
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
}

...

Warning
titlePreDataLoad/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.

Anchor
VerifyFormDataCall
VerifyFormDataCall

Data Validation Before Submission

...

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. 


Anchor
SignatureInputs
SignatureInputs

...

  • 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.
  • If there are multiple groups of users and only certain groups should have access to the signature, this can be achieved using JS to add/remove the data-signature-ignore attribute to the canvas element. When the attribute is there the signature cannot be interacted with. 
Code Block
languagexml
themeRDark
titleCanvas Signature Element
<canvas style="width:550px; height:150px; " id="Signature" data-signature="Signature space for delivery"></canvas>

...

Code Block
languagexml
themeRDark
titleField 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

Warning
titlebutton 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

Code Block
languagexml
themeRDark
titleField 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.

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

...

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


...

Other Button APIs

Warning
titlebutton 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

Code Block
languagexml
themeRDark
titleField Types
<button type="button" data-submit="" id="[something]">Submit Package</button>

Scan

Code Block
languagexml
themeRDark
titleField Types
<button type="button" data-scan="" id="[something]">Scan</button>

Previous form

Code Block
languagexml
themeRDark
titleField Types
<button type="button" data-previous="" id="[something]">Previous</button>

Next form

Code Block
languagexml
themeRDark
titleField 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.

Default Saved Form Name

It is possible to automatically populate the save message for a form package using an input on your form.  This can be a hidden input but it must have an ID of "FORMSINMOTION_SAVENAME".

Code Block
languagexml
titleDefault save ID
<input id="FORMSINMOTION_SAVENAME" style="display:none;" />

Filter by label (Content by label)
showLabelsfalse
max5
spacesFIMKB
showSpacefalse
sortmodified
reversetrue
typepage
cqllabel in ( "development" , "forms" , "html" , "javascript" ) and type = "page" and space = "FIMKB"
labelshtml forms development javascript

...

Page Properties
hiddentrue


Related issues
 

Component