Miracle Mobile Forms enables you to send form submissions in PDF documents to designated email addresses. While you are welcome to use the default PDF template in htmlTemplate in User Defined Settings, you can always create and use custom templates which reflect your corporate branding.


To create a custom PDF template, you need to learn how to use special keywords. These pre-defined keywords are important for Miracle Mobile Forms’ HTML Parser. In addition to defining the appearance of data in the final HTML output (and ultimately the PDF output), they can specify how the Parser works. They can instruct the Parser to operate in Pattern Based Mode, HTML Dictated Mode, or both. 


So, without further ado, here is the list of keywords you should keep in mind to create custom PDF templates.


DataRepeater Keyword

<div class="DataRepeater">

This will initiate the PDF Parser. Anything that comes under this element (i.e. the element with a CSS class ‘DataRepeater’) will be executed by the PDF Parser. Majority of the remaining HTML will be used as is, including other hardcoded HTML elements and CSS.


NoteOnly the elements under the DataRepeater element will be executed by the Parser. The rest of the HTML will used as is in the final outcome, except for PageTitle, PageHeader, and LogoImage. More on these keywords later in this section. 


mt_control Keyword

The mt_control keyword is used to provide an HTML pattern for controls of a specific type. It is used in combination with a control type as shown in the example below.


<div class="mt_control c_textbox"> </div>

You can use this line of code to customize the appearance of all text box controls in the form. You can find a list of all controls at the bottom of this page.


You can also use the same title and value style with customized CSS, such as in the following example:

<tr class="mt_control c_textbox">

   <td class="FieldLabel">Label</td>

   <td class="FieldValue">Value</td>

</tr>


Moreover, you can define any style you wish to use.

.c_textbox {color:#64f5e3 !important;}


You can also define the style of all children controls (controls contained within a control, or parent) by customizing the style of a parent control. The following HTML code is a good example on how to customize the style of all controls inside a Repeater control.


<tr class="mt_control c_repeater">

   <td class="FieldLabel anyClassForStyling">Label</td>

   <td class="FieldValue" style=”backgroung-color: red;”>Value</td>

</tr>


CSS:

. anyClassForStyling {color:#64f5e3 !important;}


NoteYou can use any HTML tags you want. For instance, in the example above, you can use div or any other tag instead of tr and td.


mt_identifier Keyword

The mt_identifier keyword is used to customize the style of a control based on its identifier. It works in combination with a control’s identifier as depicted below.

<div class="mt_identifier textbox1"> </div>


Each control in a form has a unique identifier, which means you can customize the style of each control using mt_identifier. To find the identifier of a control:

  • Open the form you need in Page Designer.  
  • Select the control and look at the Identifier field in the properties pane on the right.


The above line of code can be used to customize appearance of a textbox with the identifier ‘textbox1’.


FieldDataRow Keyword

The FieldDataRow keyword is used to define generic HTML code which can be used for all controls. If no other HTML pattern has been defined for a control, the Parser will use this code. Here is an example:

<div class="FieldDataRow" style="background-color:red;">


FieldLabel Keyword

Each control has a value and a title. Value is what Miracle App users enter in the control and submit with the form. As for Title, it is the label associated with the control and displayed in the PDF.


Titles can be set for each control using the following steps:

  • Open the form you need in Page Designer.  
  • Select the control.
  • Scroll down the properties pane on the right. Type a title in the ‘Title shown in PDF’ field.

Once an HTML pattern for a control is identified, the Parser then checks its children to see if any FieldLabel element defines them. If that is the case, it sets the title in that element. 


Here is an example

<tr class="FieldDataRow">

   <td class="FieldLabel">Label</td>

   <td class="FieldValue">Value</td>

</tr>


FieldValue Keyword

Like the FieldLabel keyword, once an HTML pattern for a control is identified, the Parser checks its children for any specific element with class=”FieldValue’. If it exists, the control value will be set in that element. If not, it will set the value in the main node.


<tr class="FieldDataRow">

   <td class="FieldLabel">Label</td>

   <td class="FieldValue">Value</td>

</tr>


HeadingDataRow Keyword

If you wish to set certain text as a header in PDF, you need to first create a Label control in the form you wish to use. The Label should have the ‘Show as PDF Header’ property checked.

The Parser will check if the control has this check marked. If yes, it will use the HeadingDataRow element. If the HeadingDataRow element is not available, the parser will use the default element, i.e. FieldDataRow.


Here is an example of how to use the HeadingDataRow Keyword:

<div class="HeadingDataRow" style="background-color:black; color:white">


HeadingLabel Keyword

As is the case for the FieldLabel and FieldValue keywords, you may need to set text as a heading inside a child element instead of using the value of the main HeadingDataRow element. In this case, you can use the HeadingLabel element for the children of the HeadingDataRow element.  

<tr class="HeadingDataRow">

   <td class="HeadingLabel" colspan="2">Page Header</td>

</tr>


RowSeparator Keyword

To separate elements when rendered in the PDF, you can provide an element with the class=”RowSeparator”.

<div class="RowSeparator"></div>


You can use CSS too, such as in the following example.

. RowSeparator {background-color:#64f5e3; width: 100%; height:2px;}


The Parser explicitly looks for this element in the template. If this element is found, it inserts it after each control it resolves.


mt_wrapper Keyword

mt_wrapper acts as a wrapper for all child controls within a parent control. An example can better help explain this concept.


Suppose a form has three (3) Textbox controls. Two (2) of these Textbox controls are within a Layout, and one (1) is on root level.


If you’re using the default PDF template, but want to style the Texbox controls inside the Layout differently, you can carry out the following modifications.

<table class="DataRepeater">

   <tr class="HeadingDataRow">

      <td class="HeadingLabel" colspan="2">Page Header</td>

   </tr>

   <tr class="FieldDataRow">

      <td class="FieldLabel">Label</td>

      <td class="FieldValue">Value</td>

   </tr>

   <div class="mt_control c_layout">

      <tr class="FieldDataRow myCustomClass">

         <td class="FieldValue">Value</td>

      </tr>

   </div>

   <tr class="RowSeparator"></tr>

</table>


The following is the final HTML output once the Parser is done:

<table class="DataRepeater">

   <tr class="FieldDataRow myCustomClass mt_textbox" id="textbox4">

      <td class="FieldValue">1</td>   

   </tr>

   <tr class="RowSeparator mt_sep_textbox"/>

   <tr class="FieldDataRow myCustomClass mt_textbox" id="textbox6">

      <td class="FieldValue">2</td>

   </tr>

   <tr class="RowSeparator mt_sep_textbox"/>

   <tr class="FieldDataRow mt_textbox" id="textbox1">

      <td class="FieldLabel"/>

       <td class="FieldValue">3</td>

   </tr>

   <tr class="RowSeparator mt_sep_textbox"/>

</table>


The HTML code in bold indicates the output for the Textbox controls within the Layout.


Note that the following HTML element is not present in this output.

<div class="mt_control c_layout">


This is because this row is used to indicate your intention to customize the style of the child controls within the Layout.


In some cases, however, you may want to include this element in the output HTML as a wrapper for all the controls inside a parent control. For that, you need to use the mt_wrapper control.


Here’s the same code as before, but with the addition of the mt_wrapper keyword.

<table class="DataRepeater">

   <tr class="HeadingDataRow">

      <td class="HeadingLabel" colspan="2">Page Header</td>

   </tr>

   <tr class="FieldDataRow">

      <td class="FieldLabel">Label</td>

      <td class="FieldValue">Value</td>

   </tr>

   <div class="mt_control c_layout mt_wrapper">

      <tr class="FieldDataRow myCustomClass">

         <td class="FieldValue">Value</td>

      </tr>

   </div>

   <tr class="RowSeparator"></tr>

</table>

The following will be the output HTML:

<table class="DataRepeater">

   <div class="mt_control c_layout mt_wrapper mt_layout" id="layout1">

      <tr class="FieldDataRow myCustomClass mt_textbox" id="textbox4">

         <td class="FieldValue">1</td>

      </tr>

      <tr class="RowSeparator mt_sep_textbox"/>

      <tr class="FieldDataRow myCustomClass mt_textbox" id="textbox6">

         <td class="FieldValue">2</td>

      </tr>

      <tr class="RowSeparator mt_sep_textbox"/>

   </div>

   <tr class="FieldDataRow mt_textbox" id="textbox1">

      <td class="FieldLabel"/>

      <td class="FieldValue">3</td>

   </tr>

   <tr class="RowSeparator mt_sep_textbox"/>

</table>


As you can see, the two Textbox controls are wrapped under the mt_wrapper element.


Note that the RowSeparator element has not been added after the mt_wrapper element. This is because mt_wrapper serves the same purpose, which is separating a child element from other elements.


mt_strict Keyword

mt_strict keyword is used to instruct the Parser to operate in Strict Mode or HTML Dictated Mode. [Refer to Miracle Mobile Forms’ HTML Parser]


This mode offers you more control over rendering the final HTML output. In it, you need to provide comprehensive HTML code with control identifiers added as placeholders. The Parser will simply replace the placeholders with control values, and use the rest of the code as is.


Here’s an example to better elaborate this concept.

<table class="mt_strict mt_identifier layout1 myTable myCustomClassForStyling">

   <tr>

      <th width="200" rowspan="2" align="center">

         <span style="font-size:16px; font-weight:bold;">Display Name</span>

      </th>

      <th width="50" align="left">Cell #</th>

      <th width="50" align="left">Address</th>

<th width="50" align="left">Designation</th>

   </tr>

   <tr>

<td align="left">${employeeName}</td>

<td align="left">${contactNumer}</td>

<td align="left">${ResAddress}</td>

<td align="left">${CurrentDesignation}</td>

   </tr>

   <tr>

<td colspan="5" align="center" valign="top">

<p> This task <b>({$taskName})</b> has been assigned to ${employeeName}

  on ${taskAssingedDate}.

</p>          

<br />

<p> The delivery date of this task is ${taskDueDate}. </p>

   </tr>

</table>


As you can see, the mt_strict keyword is specified at the table class element, along with mt_identifier and layout1. This means that Strict Mode would be applied to all the children of the control with the identifier=’layout1’.


You may also note some placeholders at different parts in this HTML - ${employeeName}, ${contactNumber}, ${ResAddress} etc. Each of the values in curly brackets - employeeName, contactNumber, and ResAddress – is an actual control identifier. Meanwhile, ${} is a marker which instructs the compiler to find any control identifiers in the HTML.


To generate the output HTML in this case, the Parser will simply use the whole HTML as is, and only replace ${employeeName}, ${contactNumber}, and ${ResAddress} with the exact values of the controls specified by these identifiers.


The following are some points which you should know about Strict Mode:

  • You can use Strict Mode for the whole PDF if you want. For this, you will need to set mt_strict with the DataRepeater keyword.
  • <div class="DataRepeater">
  • Through mt_strict keyword, you get more control over output HTML. Therefore, we recommend its use if you have advanced HTML styling needs which cannot be fulfilled using the Pattern Based approach.
  • You cannot provide HTML pattern in Strict Mode. This means the keywords mentioned above won’t work in Strict Mode. Since you’re providing actual output rather than specifying general patterns, it also means the HTML code can be lengthy. So, you need to be careful while mentioning identifiers as well as while updating identifiers through Page Designer.
  • Since Strict Mode works with identifiers, a template designed for one form may not work for another as forms shouldn’t have the same control identifiers. On the other hand, the Pattern Based mode enables you to provide generic HTML patterns that can be used in multiple forms.


mt_strict and Images

You can use the following HTML code to show images via Image Picker in Strict Mode.

<img class="" src="${imagepicker1}" > </img>


In this example, imagepicker1 is the identifier for an Image Picker control.


You can control the size of the image through CSS as well as the Parser’s built-in functionality. The following are two examples.


<img class="" src="${min(100w):imagepicker1}" > </img>

This code will ensure the image has a minimum width of 100. The image’s height will be adjusted accordingly without affecting the width and height ratio.


<img class="" src="${min(100w,150h):imagepicker1}" > </img>

This code will ensure the image is minimized to width=100 and height=150.


mt_strict and Control title

Each control can have a Value (which is sent through at the time of form submission) and a Title (set using the Title Shown in PDF property in Page Designer).


To use the control title in PDF, you can use code similar to this:

${title:textbox1}


Here, textbox1 is the control identifier. In the output HTML, this text will be replaced by the text you entered in the Title Shown in PDF property of textbox1.


mt_repeating Keyword

The mt_repeating keyword is strictly used when a form contains a Repeater control and you wish to parse an HTML document in Strict Mode.


A Repeater control defines a set of controls that can be repeated multiple times at runtime. For example, app users can tap an “Add New” button in a form to generate new rows to enter more data. [More on the Repeater control in this video.]


When using the Repeater control in a form, you cannot determine exactly how many times the set of controls will be added in a particular form submission. This can be a challenge for the Parser in Strict Mode since it simply replaces control identifier placeholders with control values. In this case, you’ll need an HTML pattern for the Repeater control. Moreover, the pattern will have to repeat as many times as the number of instances present in a form submission.


Suppose you have a form which collects a user’s personal details and a list of their dependents. As the number of a person’s dependents may vary, the Repeater control was used while designing the form. Below is a possible HTML code for PDF customization:

<div class="DataRepeater mt_strict">

   <div class="main">

      Name: ${FirstName} ${LastName}

   </div>

   <b>Dependants:</b>

   <div class="mt_repeating mt_identifier dependantsRepeater parentDiv">

      <div class="childDiv">

         ${SNO}. ${dependantFirstName} ${dependantLastName}

      </div>

   </div>

</div>


The mt_repeating keyword set inside the div class attribute indicates that this control shouldn’t be handled like others in Strict Mode. Instead, the Parser will go over this HTML as many times as the control has been used for adding dependents.

<div class="mt_repeating mt_identifier dependantsRepeater parentDiv">


Going over the code, you may have noticed other keywords like mt_identifier and dependantsRepeater. These two keywords specify the exact Repeater control for which this HTML is used. As for parentDiv, that is a simply a class for styling purposes.


Also note that the mt_repeating element is used inside the mt_strict element, which is mandatory.

<div class="DataRepeater mt_strict">


Here is a sample output in PDF when the person name is John Davis and his dependents:



And here is a sample output in HTML for the same:

<div class="DataRepeater mt_strict">

   <div class="main">

      Name: John Davis

   </div>

   <b>Dependants:</b>

   <div class="mt_repeating mt_identifier parentDiv"> 

      <div class="childDiv">

         Deborah Davis

      </div>

   </div>

   <div class="mt_repeating mt_identifier parentDiv"> 

      <div class="childDiv">

         Ann Davis

      </div>

   </div>

   </div>

</div>


Note how the mt_repeating element appears twice in the code. Since the user added two (2) dependents, the set of controls wrapped inside a Repeater have been repeated twice at the time of form submission.


mt_repeat_children Keyword

Limited to Strict Mode, the mt_repeat_children keyword works in combination with the mt_repeating element to repeat its child content rather than the element itself.

If you look at the example used previously in the mt_repeating section, you will notice that the mt_repeating element has been rendered for each set of controls inside the Repeater.

<div class="mt_repeating mt_identifier parentDiv"> 

   <div class="childDiv">

      Deborah Davis

   <div>

</div>

<div class="mt_repeating mt_identifier parentDiv"> 

   <div class="childDiv">

      Ann Davis

div>

</div>


By using the mt_repeat_children element, you don’t need to use the mt_repeating element over and over again. Instead, you use this element as a wrapper for the whole Repeater element, and repeat child content (childDiv in this case).


Applying the mt_repeat_children in the same example:

<div class="DataRepeater mt_strict">

   <div class="main">

      Name: ${FirstName} ${LastName}

   </div>

   <b>Dependants:</b>

   <div class="mt_repeating mt_repeat_children mt_identifier

      dependantsRepeater parentDiv">

      <div class="childDiv">

         ${SNO}. ${dependantFirstName} ${dependantLastName}

            </div>

   </div>

</div>


Here is the output:

<div class="DataRepeater mt_strict">

   <div class="main">

      Name: John Davis

   </div>

   <b>Dependants:</b>

   <div class="mt_repeating mt_repeat_children  mt_identifier parentDiv"> 

      <div class="childDiv">

         Deborah Davis

      </div>

      <div class="childDiv">

          Ann Davis

      </div>

   </div>

   </div>

</div>


Comparing this output with the output in the previous section, you’ll notice mt_repeat_children element has been repeated only once.


PageHeader Keyword

The PageHeader keyword is used to indicate an HTML element as a header. You need to use this keyword if you’re:

  • Using PageTitle and LogoImage Keywords – The PageTitle and LogoImage keywords (explained below) should come inside this header element. However, the latter can also be used independently.
  • Adding Custom Fonts in PDF – This header element must be defined in the template. To use custom fonts, check ‘Use Custom Fonts in PDF’ in System Settings in Miracle Studio.


Here is an example using the PageHeader element.

<div class="PageHeader">

   <div class="LogoSection" required="false">

      <img src="" alt="logo" class="LogoImage"/>

   </div>

   <div class="PageTitle" required="true" style="display:inline;">Page Title</div>

</div>

                       

The first div with class=”PageHeader” represents the header element.

<div class="PageHeader">

</div>



PageTitle Keyword

The PageTitle element is used to specify where and how a form’s DisplayName appears in the PDF. Once the Parser locates this element, it will replace its content with the form’s DisplayName.

<div class="PageTitle" required="true" style="display:inline;">Page Title</div>


To set a form’s DisplayName:

  • Launch Miracle Studio. Click on Page & Forms.
  • Hover over the form you wish to configure until you see the Edit Form button.
  • Click on the button.
  • Set the form’s DisplayName, then click Save.


LogoImage Keyword

LogoImage is used to describe how and where a logo image would appear in the PDF output if used at all. The following code utilizes the LogoImage keyword:

<img src="" alt="logo" class="LogoImage"/>


To define the logo image:

  • Upload the image you wish to use in Assets.
  • Open the page or form you wish to send as PDF in Page Designer.
  • Click on Actions/Triggers. Add an action and then click Save.
  • Click Add a Sub Trigger. Choose SendEmail as its type, and fill in any details you deem necessary.
  • Click the Add a Sub Trigger associated with the SendEmail trigger. Choose Email PDF as the type.
  • Click on the Data tab and choose the asset you added from the PDF Logo dropdown.


You can also set the logo image dynamically based on the app user’s input. To do this, upload the desired assets uploaded in your app’s Assets, then include your own version of the following HTML:

<img src="${textbox1}" alt="logo" class="LogoImage"/>


Here, ${textbox1} is a placeholder which specifies the value of a control with the identifier ‘textbox1’.


Once the form is submitted, the Parser will go over the submitted value of textbox1 to check if an asset with this name exists in the app. Once the asset is found, the src attribute of the LogoImage element will be set as an img element.


You don’t need to include the image’s extension as part as the control’s value. The system will find out the image extension itself by looking into asset details.



List of controls:

c_autocomplete

c_barcodereader

c_boxview

c_button

c_cartesianchart

c_datepicker

c_datetimepicker

c_donutchart

c_image

c_imagepicker

c_label

c_layout

c_listview

c_location

c_pagerview

c_picker

c_piechart

c_repeater

c_segmented

c_separator

c_signature

c_slider

c_stepper

c_subform

c_switch

c_textbox

c_timepicker

c_uploader

c_webview