DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 967,611 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for How to Add PDF Form Filler Options in Your JavaScript Application
Chelsea Devereaux for GrapeCity, Inc.

Posted on • Originally published at grapecity.com

How to Add PDF Form Filler Options in Your JavaScript Application

As more and more businesses move their forms to online formats, it is increasingly important to read, create, and fill out online forms. Given the current world health situation, many transactions that used to take place in person are being completed virtually through various methods.

However, this doesn't exclude the need for appropriate paperwork and forms which need completing. Some forms that need completing in a digital format include insurance claim applications, leases, mortgage applications, and government and legal forms. Many organizations still use non-editable forms, which require users to download the form, print it, then manually fill out the information and/or sign it.

Although this can be scanned and sent back digitally, many extra steps are involved, often confusing those less technically savvy. The alternative is interactive or editable PDF forms to make the process easier for all users. Anyone can complete these forms either using an online service or downloading and installing local software on a device. A few online services and software are available for completing editable PDF forms.

This feature was originally released in the 2020 v4 release of the JavaScript-based GrapeCity Documents for PDF Viewer and added a Form Filler feature in GcDocs PDF Viewer. This feature makes filling out PDF forms on any platform, such as desktop or phone, much more straightforward and allows for a single code-base using JavaScript for multiple platforms.

It allows customization of form field labels, the behavior of form fields, and additional input validation of the fields, all accomplished by using familiar JavaScript functions and methods. The fields' grouping and order may also be customized regardless of the order on the actual PDF form.

Form Filler Dialog

First, it's essential to understand how the Form Filler feature integrates within GcDocs PDF Viewer.

The Form Filler feature once enabled through the setting of JavaScript properties, is shown on the toolbar below. Once the button has been implemented, it is visible but not always active. The button is only activated if a PDF form is loaded, which is a fillable PDF. Below is a very simple example of such a form, along with the Form Filler Dialog associated with the PDF:

After clicking the Form Filler button, a dialog box displays the fields requiring input on the PDF form. Note, it does NOT show the actual PDF form, but rather just the fields requiring input. There are also two buttons, Cancel and Apply, allowing users to either exit without changing the document or apply any changes or entries made on the form. The field names and types on the Form Filler may be the same as the PDF file or may be customized to use different prompts/field names, as well as allowing customization of validation features of each field.

Here is a snapshot showing the Form Filler dialog, displaying the form fields of the PDF form loaded in the above screenshot:

It's also easy to implement the Form Filler feature on the client-side using the showFormFiller method of GcDocs PDF Viewer client-side API. A great example of when to do this would be when a form may be a long, multi-page form that collects much information yet also has many pages that do not include data capture. By utilizing the JavaScript and customizations (as shown in the next section), it is possible to β€œslim down” the PDF to only capture the required data, then fill in the form appropriately based on the data captured in the form filler. Programatically, here is a sample code snippet showing how this can be activated for use on multiple platforms:

    if(viewer.hasForm) { viewer.showFormFiller(); }

Enter fullscreen mode Exit fullscreen mode

Customize Form Filler Fields

Although the example above shows a sample with the same name and field types, it is possible to customize these forms in various ways, including through customized labels, input behavior, and validation, all using familiar JavaScript validation scripts. These customizations use a set of custom properties for Form Fields supported by GcDocs PDF Viewer. These custom properties are set to provide additional UI and validation for the text fields (see table below for a list of custom properties):

Attribute Description Type or Types
autocomplete Input type. all
autofocus Automatically focus the form control when the page is loaded. all
defaultvalue The default value. all
disabled Whether the form control is disabled. all
displayname Text label for the input control. Applicable only if the field appears in the Form Filler dialog box. all
min The minimum value to accept for the input. number, date
max The maximum value to accept for the input. number, date
maxlength Maximum length (number of characters) of value. password, search, tel, text, url
minlength Minimum length (number of characters) of value. password, search, tel, text, url
multiline Set this property to true if you want to use the textarea as a user input element. text
multiple Boolean. Whether to allow multiple values. email
pattern Pattern the value must match to be valid. password, text, tel
placeholder Text that appears in the form control when it has no value set. password, search, tel, text, url
readonly Boolean. The value is not editable. all
required Boolean. A value is required or must be checked for the form to be submitted. all
spellcheck Whether the element may be checked for spelling errors. search, text
type Type of form control. all
validationmessage Localized validation message. all
validateoninput Indicates whether validation should be performed immediately during user input. all

Now that the tool's basics and background are understood, let's look at how we can apply this in a real-world scenario.

Use Case for New PDF Form Filler

Recently, we became empty-nesters as our children have gone off to school. My daughter (the older of the two) decided she wanted to get an apartment rather than live on campus. "Back in my day..." (Insert grumpy old man voice), there used to be a ton of paperwork, background checks, leasing documents, and deposits, which all had to be completed while sitting in a rental agent's office.

However, the current generation of new adults wants everything to be a bit more streamlined, and more importantly, they want to be able to do any paperwork or forms on their phones or tablets. Although this generation still utilizes laptop and desktop computers, almost all do this work on their phones or smaller footprint devices. I witnessed my daughter filling out a leasing application on a mobile device, which (because the agency wasn't using the GrapeCity tools) was a pretty painful experience to watch.

However, she was able to complete the process eventually. Because of this experience, I'd like to show you how people can do this better by using the GrapeCity GcDocs Form Filler tools in this BLOG.

Here is a sample of a commercial tenant application PDF form loaded in GcPdfViewer, along with how it looks in the Form Filler dialog after customizing the form fields:

That's pretty cool, isn't it? The best part is that it has a built-in responsive design, so the form filler view (on the right) will work on various platforms without having to be re-coded by developers! Let's move on to how this is done!

Step 1: Configure GcDocs PDF Viewer using JavaScript and C# - (Jump to the code for Form Filler if you already have GcDocs PDF Viewer set up appropriately!)

First, we need to configure GcDocs PDF Viewer to add the Form Filler button to the toolbar. The steps listed below will help you perform the configuration:

Create a new ASP. NET Core Web Application, choosing the Empty project template. Choose .Net Core 3.1 as the project's target framework.

Run the following command to install GcDocs PDF Viewer. Ensure that the directory location in the command prompt is set to the lib folder in the project. The GcDocs PDF Viewer will be installed in <app_name>\wwwroot\lib\node_modules folder.

    npm install @grapecity/gcpdfviewer
Enter fullscreen mode Exit fullscreen mode

Get the SupportApi project (from GcPdf Distribution zip or GcPdfViewer Sample zip) in a sub-folder named GcPdfViewerWeb.

Add the SupportApi project to the application solution. Right-click the solution, Add | Existing Project, and then select SupportApi.csproj from the SupportApi project folder downloaded in the last step.

In your project, right-click the Dependencies | Add Project Reference to SupportApi.csproj.

Add a new HTML page to the www root folder and name it "Index.html." Add the following code in the index.html file to initialize GcDocs PDF Viewer with the Form Filler button in the toolbar:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, shrink-to-fit=no">
      <meta name="theme-color" content="#000000">
      <title>GC Viewer Demo | PDF Plugin</title>
      <link rel="stylesheet" href="https://cdn.materialdesignicons.com/2.8.94/css/materialdesignicons.min.css">
      <script>
          //Initialize GcPdfViewer to add the Form Filler Button
          function loadPdfViewer(selector) {
              var options = {};
              options = setupFormFiller(options);
              var viewer = new GcPdfViewer(selector, options);
              viewer.addDefaultPanels();
              viewer.toolbarLayout.viewer = {
                  default: ['open', 'form-filler', '$navigation', '$split', 'text-selection', 'pan', '$zoom', '$fullscreen', 'print', 'title', 'about'],
                  mobile: ['open', 'form-filler', '$navigation', 'title', 'about'],
                  fullscreen: ['$fullscreen', 'open', 'form-filler', '$navigation', '$split', 'text-selection', 'pan', '$zoom', 'print', 'title', 'about']
              };
              viewer.open("Commercial-Rental-Application-Form.pdf");
          }

          //Function used to customize the Form Fields in Form Filler dialog
          function setupFormFiller(baseOptions) {
              var options = baseOptions || {};
              // Form Filler options:
              options.formFiller = {
                  //Add code to customize the form fields
              };
              return options;
              }
      </script>
    </head>
    <body onload="loadPdfViewer('#root')">
        <div id="root"></div>
        <script type="text/javascript" src="lib/node_modules/@grapecity/gcpdfviewer.js"></script>
    </body>
    </html>
Enter fullscreen mode Exit fullscreen mode

Modify the Startup.cs file by replacing the default 'Configure' method with the below code snippet. This action will open the index.html by default when the app starts.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if (env.IsDevelopment())
      {
        app.UseDeveliperExceptionPage();
      }
      app.UseRouting();
      app.UseDefaultFiles();
      app.UseStaticFiles();
    }
Enter fullscreen mode Exit fullscreen mode

Build and run the application to view GcDocs PDF Viewer in your browser, which contains the Form Filler button to fill the fillable PDF form loaded in the viewer.

Step 2: Using JavaScript to Customize Form Fields in Form Filler Dialog

The Commercial Tenant Application form loaded in the last step has a long list of Form Fields types. The following sections contain instructions on adding, grouping, reordering, customizing, and performing validation of these fields utilizing the properties described above.

Note: The mappings attribute (part of the ViewerOptions Class and form-filler property) from the GcDocs PDF Viewer client-side API allows custom properties for each field and reordering grouping of the form fields. Examples of these are provided below.

Here is a quick look at how the default form filler form fields would look after applying customization:

The image above depicts the before and after screens of the form filler view. The form on the left is what this document would look like to a user in form filler with NO customizations. In contrast, the right screen is what the user experience looks like after applying the below customizations.

Adding New Form Fields for Displaying Static Text

To make the user experience more manageable, the raw form fields, as displayed above, need some customization to make the form more meaningful. Applying static text and additional contextual information makes the form easier to understand and complete. The text field's Content property is set to a value displayed in the form filler dialog to accomplish this. The value of the Content property is a string or an HTML string. The type of property in this text field must be "custom-content" for the Form Filler to understand that it is a static text for display purposes.

Here is a sample JavaScript code snippet for adding an HTML table by setting the Content property of a text field to an HTML string:

    options.formFiller = {
          mappings: {
                      'CustomContent_Info1': {
                            type: 'custom-content',
                            content: <table>
                              <tr><td style='vertical-align:top;'>
                                  <i><u>Corporation:</u></i>
                              </td><td style='vertical-align:top;'>
                                  <i>Articles of Incorporation muyst be provided and 2 years' Annual Report and corporate tax return.</i>
                              </td></tr>
                              <tr><td style='vertical-align:top;'>
                                  <i><u>Partnership:</u></i>
                              </td><td style='vertical-align:top;'>
                                  <i>Partnership Agreement must be provided plus individual partners' current personal financial statement and 2 years' personal tax returns.</i>
                              </td></tr>
                              <tr><td style='vertical-align:top;'>
                                  <i><u>Individual:</u></i>
                              </td><td style='vertical-align:top;'>
                                  <i>Personal balance sheet and 2 years' personal tax returns must be provided. Must include Drivers' license number.</i>
                              </td></tr>
                            </table>
                      }
            }
    };

Enter fullscreen mode Exit fullscreen mode

Here is how the custom field is displayed:

Group and Reorder Form Fields

Generally speaking, a group consists of items of a similar nature. For example, an address block consists of a few fields, each of which contributes to the whole of an address to make it complete. To group a set of form fields, you can add a new text field to the Form Filler dialog, which does not exist in the original PDF form, using the approach described in the last section. The value of this text field will act as the group header. After adding the text field for the Group header, you can add all the form fields which must be a part of this group to the mappings attribute. The value of the Content property of this text field can define the Group title or header.

Here is a sample JavaScript code snippet for adding a group of Form Fields:

    options.formFiller = {  
            mappings: {  
                        'CustomContent1': {  
                            type: 'custom-content',  
                            content: '<h2>COMMERCIAL TENANT APPLICATION</h2>'  
                        },  
                        'AppDate': {  
                            title: 'Application date', 
                            displayname: 'Date',  
                            type: 'date',  
                            defaultvalue: new Date().toJSON().slice(0, 10)  
                        },  
                        'Entity': {  
                            autofocus: true,  
                            title: 'Name of individual, partnership, or corporation', 
                            displayname: 'Applicant or Leasing Entity',  
                            placeholder: 'Name of individual, partnership, or corporation', 
                            required: true,  
                            validationmessage: 'Entity name is required', 
                            validateoninput: true  
                        }  
                      }  
    };  
Enter fullscreen mode Exit fullscreen mode

The code above even customizes the form fields, which will be explained in detail in the steps ahead. This is how the Form Filler dialog would look after adding the first group of Form Fields:

Similarly, users can add more text fields to create other Form Fields or static text groups when required.

The order in which fields appear in the user experience is defined by the order in which they are added to the mappings attribute. Therefore, you can add the form fields in any order, regardless of the original PDF form's layout.

Customize UI Appearance and Behavior of Form Fields

Several custom properties are used to modify the appearance and behavior of the form fields. This section discusses some of these properties using JavaScript to customize a few form fields from the Commercial Tenant Application form.

Customize label and tooltip: The form field label and tooltip are customized by setting the displayname and title property, respectively.

Here is a sample code snippet for altering these properties for the 'AppDate' field:

    options.formFiller = {  
          mappings: {  
              'AppDate': {  
                  title: 'Application date', 
                  displayname: 'Date'  
              }  
          }  
      };  

Enter fullscreen mode Exit fullscreen mode

Here is how the custom field would appear:

Customize input type: The type property changes the form field's input type according to its purpose.

Here is a sample of JavaScript code for changing the type of the 'AppDate' field to date. Since the required data should be in a specific date format, the date picker UI is used to capture the information:

    options.formFiller = {  
          mappings: {  
              'AppDate': {  
                  title: 'Application date', 
                  displayname: 'Date',  
                  type: 'date'  
              }  
          }  
      };   
Enter fullscreen mode Exit fullscreen mode

Here is how the customized field displays after the above modifications are applied:

Set default value: The default value for the form field is set using the defaultvalue property.

Here is the sample code for setting the 'AppDate' field's default value to today's date. It even focuses on the 'AppDate' field when the Form Filler dialog is opened by setting the autofocus property to true.

    options.formFiller = {  
            mappings: {  
                'AppDate': {  
                    autofocus: true,  
                    title: 'Application date', 
                    displayname: 'Date',  
                    type: 'date',  
                    defaultvalue: new Date().toJSON().slice(0, 10)  
                }  
            }  
      };  
Enter fullscreen mode Exit fullscreen mode

Here is how the custom field is displayed after the above modification is applied:

Define placeholder: The placeholder property is used to set placeholder text for a form field when its value is empty.

Here is the sample code for setting the placeholder text for the 'Entity' field:

    options.formFiller = {  
          mappings: { 
            'Entity': {  
                title: 'Name of individual, partnership, or corporation', 
                displayname: 'Applicant or Leasing Entity',  
                placeholder: 'Name of individual, partnership, or corporation',  
              }  
          }  
      };   
Enter fullscreen mode Exit fullscreen mode

Here is how the custom field is displayed after applying the above modifications:

Convert to textarea: The form field type is changed to a text area to allow multiple line inputs by setting the multiline property.

Here is the sample code for converting the 'Addr1' field to a text area:

    options.formFiller = {  
            mappings: {  
              'Addr1': {  
                  title: 'Current corporate headquarters/home address (For partnership/individuals) (Do not use P.  O. Box)',  
                  displayname: 'Current address',  
                  placeholder: 'Current corporate headquarters/home address (For partnership/individuals) (Do not  use P.O. Box)',  
                  multiline: true  
              }  
          }  
      }; 
Enter fullscreen mode Exit fullscreen mode

Here is how the custom field is displayed after applying the modification above:

Hide field: A form field is hidden by setting the hidden property to true.

Here is the sample code for hiding the 'Addr2' field:

    options.formFiller = {  
            mappings: { 
              'Addr2': {  
                    hidden: true  
                  }  
            }  
      };  
Enter fullscreen mode Exit fullscreen mode

Display full-width field: A field input control can be displayed full width without a label by setting the nolabel property to true.

Here is some JavaScript for displaying HazSub1, HazSub2, and HazSub3 as full-width input fields without a label:

    options.formFiller = {  
          mappings: {  
              'CustomContent4': {  
                  type: 'custom-content',  
                  content: '<h4>Please list all hazardous substances that will be on the premises and the approximate amounts</h4>'  
                  },  
                  HazSub1: {  
                      title: 'Please list all hazardous substances that will be on the premises and the approximate  amounts',  
                      placeholder: 'List all hazardous substances that will be on the premises and the approximate amount (line 1)', 
                      nolabel: true  
                  },  
                  HazSub2: {  
                      title: 'Please list all hazardous substances that will be on the premises and the approximate  amounts',  
                      placeholder: 'List all hazardous substances that will be on the premises and the approximate amount (line 2)',  
                      nolabel: true  
                  },  
                  HazSub3: {  
                      title: 'Please list all hazardous substances that will be on the premises and the approximate  amounts',  
                      placeholder: 'List all hazardous substances that will be on the premises and the approximate amount (line 3)',  
                      nolabel: true    
                  }  
            }  
      };  
Enter fullscreen mode Exit fullscreen mode

This is how the customized field is displayed after applying the above modification:

Adding Validation to Form Fields using JavaScript

It is possible to customize the form field validation, including setting items such as max length, min length, data type, etc., to the form fields. By default, the form fields in the Form Filler dialog are validated based on specified validation criteria and only when a user clicks the Apply button. Users can change this behavior to check validation immediately during end-user input by setting the validateoninput property to true. Fields failing validation display a visual indicator and a validation message. The validation message is set using the validationmessage property.

Here is a sample code snippet applying required validation to the Entity field and setting the validateoninputand validationmessage property:

    options.formFiller = {  
            mappings: { 
                'Entity': {  
                      title: 'Name of individual, partnership, or corporation', 
                      displayname: 'Applicant or Leasing Entity',  
                      placeholder: 'Name of individual, partnership, or corporation', 
                      required: true,  
                      validationmessage: 'Entity name is required', 
                      validateoninput: true  
                  }  
            }  
      };   
Enter fullscreen mode Exit fullscreen mode

Here is a screenshot displaying the invalid value indicator along with the validation message when the field is left blank after editing:

Let's look at the variety of available and supported validation types, as well as how to set these programmatically:

Required validation: The required property is used to apply the required validation to a form field. This validation ensures that the user does not leave the specified field blank after editing. Required fields are marked with a red asterisk on the top right corner of the field label.

Here is the code snippet setting a required property for the Entity field:

    options.formFiller = {  
            mappings: { 
              'Entity': {  
                  title: 'Name of individual, partnership, or corporation', 
                  displayname: 'Applicant or Leasing Entity',  
                  placeholder: 'Name of individual, partnership, or corporation', 
                  required: true  
              }  
          }  
      };
Enter fullscreen mode Exit fullscreen mode

Here's the validation result using the above code and leaving the field blank after editing. Observe the red asterisk on the top right of the field label:

Pattern Validation: Verifies user input against a regular expression to ensure the user has entered a valid value. For example, a Phone number field should not have any alpha characters, only numbers, left/right parenthesis or dashes, and particular order. The regular expression for validation is set using the patternproperty.

The JavaScript code snippet sets a pattern property for a phone number field. The regular expression validates that the user has input a valid phone number:

    options.formFiller = {  
            mappings: { 
                'CorpPhone': {  
                    title: 'Corporate phone number', 
                    displayname: 'Corporate phone #', 
                    placeholder: 'Corporate phone', 
                    type: 'tel',  
                    pattern: '^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}/div>,  
                    validationmessage: 'Valid formats: 1234567890, (123)456-7890,\n 123-456-7890, 123.456.7890,  +31636363634, 075-63546725',  
                    validateoninput: true  
                }  
            }  
      }; 
Enter fullscreen mode Exit fullscreen mode

Here's the validation result when applying the above code and entering an invalid value:

Length Validation: Ensures the user enters a fixed number of characters in the field. The minlength and*maxlength* properties are used to set the minimum and the maximum number of characters input in a field.

Here is the code snippet setting minlength and maxlength properties for the bank account number field:

    options.formFiller = {  
            mappings: { 
              'BankAcct': {  
                  title: 'Bank account number', 
                  displayname: 'Account number', 
                  placeholder: 'Account number', 
                  minlength: 8,  
                  maxlength: 12,  
                  validationmessage: 'Expected value between 8 and 12 digits', 
                  validateoninput: true  
                }  
            }  
      };  
Enter fullscreen mode Exit fullscreen mode

Here's the validation result when applying the above code and entering an invalid value:

Validator function: This allows the use of JavaScript code to perform validation. A JavaScript function is defined with the necessary validation logic and set to the validator property to check the submission value.

Here is the code snippet defining a function that makes sure the user can enter only the "Delaware" value in the "State of incorporation" field:

    options.formFiller = {  
            mappings: { 
              'CorpState': {  
                    title: 'State where the company was registered', 
                    displayname: 'State of incorporation', 
                    placeholder: 'State of incorporation', 
                    validateoninput: true,  
                    validator: function(fieldValue, field) { 
                        if(!fieldValue || !fieldValue.trim())  
                            return 'This field cannot be empty'; 
                        if(fieldValue.toLowerCase().indexOf('delaware') === -1)  
                            return 'Only Delaware state allowed.'; 
                        return true;  
                    }  
                  }  
            }  
      }; 
Enter fullscreen mode Exit fullscreen mode

Here's the validation result when applying the above code and entering an invalid value:

Common Validator function: The validator property can be set either for a specific field or commonly for all the fields. When the validator property is set for the form filler, it is a common validator function that applies the same validation rule to all the form fields.

Here is the code snippet defining a common validator function, which is applied to all the fields in form filler:

    var viewer = new GcPdfViewer(selector, { 
        renderInteractiveForms: true, 
        formFiller: {  
          validator: function(fieldValue, field) {  
              return (fieldValue? true : 'The field cannot be empty');  
          },  
          mappings: {  
                'fld1': {  
                    title: 'Application date', 
                    displayname: 'Date',  
                },  
                'fld2': {  
                    title: 'Name of individual, partnership, or corporation', 
                    displayname: 'Applicant or Leasing Entity'  
                  }  
              }  
          }  
      }); 
Enter fullscreen mode Exit fullscreen mode

Form Filler Event Handlers

Form Filler provides three events: onInitialize, beforeApplyChanges, and beforeFieldChange. These are used to alter the behavior and appearance of the form fields. Let's take a look at an example to get a better understanding of its use:

onInitialize: This event is raised after the list of custom form fields is initialized but not yet rendered.
beforeApplyChanges: This event is presented when the Apply button is clicked after successfully validating all custom form fields.

Here is an example defining the handlers for onInitilaize and beforeApplyChanges events considering the following scenario. The Commercial Tenant application form loaded in GcDocs PDF Viewer has a text field seeking information for "Any Overnight Parking." In the Form Filler dialog, this will be presented as a checkbox. The PDF form's text field will be set to a predefined text value when the checkbox is checked in the Form Filler dialog. The onInitialize event is used to set the checkbox's value in the form filler if the PDF Form text field has some value. The beforeApplyChanges event is used to set the text field's value in the PDF form based on the checkbox's value in the form filler.

    var ovnPark_FieldValue_On = 'Has overnight parking.', 
        ovnPark_FieldValue_Off = 'NO';    

        options.formFiller = {  
            onInitialize: function(formFiller) {  
                var ovnParkField = formFiller.getFieldByName('OvnPark'); 
                if(ovnParkField.fieldValue) {  
                    var ovnPark_LowVal = (ovnParkField.fieldValue || '').toLowerCase();  
                    if(!ovnPark_LowVal || ovnPark_LowVal.indexOf('no') !== -1 || ovnPark_LowVal === 'off' || ovnPark_LowVal === 'false') {  
                        ovnParkField.fieldValue = 'Off'; 
                        formFiller.onFieldChanged(ovnParkField);  
                        }  
                  else {  
                        ovnPark_FieldValue_On = ovnParkField.fieldValue; 
                        ovnParkField.fieldValue = 'On'; 
                        formFiller.onFieldChanged(ovnParkField);  
                    }  
                }  
            },  
            beforeApplyChanges: function(formFiller) {  
                var ovnParkField = formFiller.getFieldByName('OvnPark'); 
                if(ovnParkField.fieldName === 'OvnPark') {  
                    if(ovnParkField.fieldValue === 'On') { 
                        ovnParkField.fieldValue = ovnPark_FieldValue_On;  
                    } else {  
                        ovnParkField.fieldValue = ovnPark_FieldValue_Off;  
                    }  
                }  
                return true;  
            },  
            mappings: {  
                OvnPark: {  
                    title: 'Any overnight parking?', 
                    displayname: 'Any overnight parking?', 
                    type: 'checkbox'  
                }  
            }  
    }  
Enter fullscreen mode Exit fullscreen mode

Here is a snapshot depicting the result of the above code:

beforeFieldChange: This event is raised before the input type's value changes. Return false if you want to cancel the field value change.

Here is an example defining the handler for a beforeFieldChange event. The Commercial Tenant application form loaded in GcDocs PDF Viewer has fields 'CorpCHK', 'GPCHK', and 'IndivCHK' of checkbox type, but they are meant to be used as radio buttons so that the user can check only one of these at a time. So, we used the beforeFieldChange event handler to change behavior for these fields from checkbox to radio button, allowing only one checkbox to be checked at a time:

    var updatingFieldsFlag = false;
    options.formFiller = {
            beforeFieldChange: function(changedField, formFiller) {
                if(updatingFieldsFlag)
                    return true;
                updatingFieldsFlag = true;
                try {
                    var fieldName = changedField.fieldName;
                    var fieldValue = changedField.fieldValue;              
                    if(fieldName === 'CorpCHK' || fieldName === 'GPCHK' || fieldName === 'IndivCHK') {
                        if(fieldValue === 'Off')
                            return false; // deny unchecking
                        var setFieldValue = function(chkboxFieldName, newVal) {
                            var tmpField = formFiller.getFieldByName(chkboxFieldName);
                            if(tmpField.fieldValue !== newVal) {
                                tmpField.fieldValue = newVal;
                                formFiller.onFieldChanged(tmpField);
                            }
                        };
                        // Uncheck other fields:
                        switch(fieldName) {
                            case 'CorpCHK':
                                setFieldValue('GPCHK', 'Off');
                                setFieldValue('IndivCHK', 'Off');
                            break;
                            case 'GPCHK':
                                setFieldValue('CorpCHK', 'Off');
                                setFieldValue('IndivCHK', 'Off');
                            break;
                            case 'IndivCHK':
                                setFieldValue('CorpCHK', 'Off');
                                setFieldValue('GPCHK', 'Off');
                            break;
                        }
                    }
                } finally {
                    updatingFieldsFlag = false;
                }
                return true;
            },
            mappings: {
                'CustomContent5': {
                    type: 'custom-content',
                    content: '<h4>Please check one:</h4>'
                },
                CorpCHK: {
                    title: 'Corporate',
                    displayname: 'Corporate'
                },
                GPCHK: {
                    title: 'General partner(s)',
                    displayname: 'General partner(s)'
                },
                IndivCHK: {
                    title: 'Individual(s) signing the lease',
                    displayname: 'Individual(s) signing the lease'
                }
            }
       };
Enter fullscreen mode Exit fullscreen mode

Here is a snapshot depicting the result of the above code:

To try this example, please download the sample that implements all blog use cases using the code snippets described above.

Refer to Documentation and Demo for further details.

Top comments (0)

This post blew up on DEV in 2020:

js visualized

πŸš€βš™οΈ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! πŸ₯³

Happy coding!