Form Embed

Use the code snippet to add the form to your website. Alternatively, you can share the direct link with your customer.

If you've read through the comparisons here and believe embedding a PandaDoc Form is best, let's get it done!

📘

Useful links

PandaDoc forms

Help center

Embed Form Code Snippet

<div id='form-container-id'></div>

<script type="text/javascript">
    (function () {
        var config = {
            nodeId: 'form-container-id',
            width: '100%',
            height: '700px',
            url: 'embed-form-url',
            events: {
                loaded: function () {},
                started: function (data) {},
                completed: function (data) {},
                exception: function (data) {}
            },
            data: {
               recipients: {
                 ROLE_NAME: {
                   ROLE_TOKEN: 'ROLE_TOKEN_VALUE',
                   ...
                 }
               },
               metadata: {
                 KEY: 'VALUE',
                 ...
               },
               variables: {
                 VARIABLE_NAME: 'VARIABLE_VALUE',
                 ...
               },
               fields: {
                 FIELD_ID: 'FIELD VALUE',
               }
            }
        };
                
        const dataQueryString = config.data ? Object.keys(config.data)
      		.map(function (key) {
        		return '&' + key + '=' + encodeURIComponent(JSON.stringify(config.data[key]));
      		})
      		.join('') : '';

        var iframe = document.createElement('iframe');
        iframe.frameBorder = 0;
        iframe.src = config.url + dataQueryString;

        if (config.nodeId) {
            var node = document.getElementById(config.nodeId);
            node.style.height = config.height;
            node.style.width = config.width;
            iframe.height = '100%';
            iframe.width = '100%';
            node.append(iframe);
        } else {
            iframe.height = config.height;
            iframe.width = config.width;
            document.body.append(iframe);
        }

        var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
        var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';

        window[eventMethod](messageEvent,function(e) {
          if (e && e.data && config && iframe && e.source === iframe.contentWindow) {

            try {
              var message = JSON.parse(e.data);
              if (message && message.event) {
                var event = message.event.replace('embed.form.', '');
                var callback = config.events ? config.events[event] : null;
                if (callback) {
                  callback(message.data);
                }
              }
            } catch(e) {}
          }
        },false);
    })();
</script>
<div id='form-container-id'></div>

<script type="text/javascript">
    (function () {
        var config = {
            nodeId: 'form-container-id',
            width: '100%',
            height: '700px',
            url: 'embed-form-url',
        };

        var iframe = document.createElement('iframe');
        iframe.frameBorder = 0;
        iframe.src = config.url;

        if (config.nodeId) {
            var node = document.getElementById(config.nodeId);
            node.style.height = config.height;
            node.style.width = config.width;
            iframe.height = '100%';
            iframe.width = '100%';
            node.append(iframe);
        } else {
            iframe.height = config.height;
            iframe.width = config.width;
            document.body.append(iframe);
        }

        var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
        var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';

        window[eventMethod](messageEvent,function(e) {
          if (e && e.data && config && iframe && e.source === iframe.contentWindow) {

            try {
              var message = JSON.parse(e.data);
              if (message && message.event) {
                var event = message.event.replace('embed.form.', '');
                var callback = config.events ? config.events[event] : null;
                if (callback) {
                  callback(message.data);
                }
              }
            } catch(e) {}
          }
        },false);
    })();
</script>

Embed Form Config

* denotes a required parameter.

*Attribute: ExampleDescription
text * nodeIdid of the HTML element to which the form will be appended
text * widthThe width of an element JavaScript embed will be rendered
text * heightThe height of an element JavaScript embed will be rendered
text * URLURL of the form will be rendered
eventsIt is possible to capture events from an embedded form. You can subscribe to four types of events: loaded started completed exception
dataIt is possible to pre-fill recipients data, metadata and variables and fields

Pre-fill values using JavaScript config

It is possible to pre-fill recipients data, metadata, variables and fields

recipients - allows to pre-fill data in authorization form. All role tokens are supported

data: {
  recipients: {
    'Form Signer': {
      Email: '[email protected]',
      FirstName: 'John',
      LastName: 'Doe',
    }
  },
}

metadata - allows to set metadata for the document that will be generated from the form. Max limit - 10 key-value pairs

data: {
  metadata: {
    test_metadata_key: 'test value',
  }
}

variables - allows to set values to variables in the document. All variables(predefined and custom) are supported except Document.Value

data: {
  variables: {
    'Form signer.FirstName': 'John',
     custom_variable: 'custom variable value',
  }
}

fields - allows to set values to variables in the document. Text field, Checkbox, Date, Dropdown fields are supported

data: {
  fields: {
    TextField1: 'TextField1 value',
    Dropdown1: 'Dropdown selected value',
    Checkbox1: true,
    Date1: '2021-02-21T00:00:00.000Z'
  }
}

📘

Working with Date fields

Specify date formatting in PandaDoc template date field settings. Pass your date field value in the following ways:

fields: {  
    Date1: **'2021-02-21T00:00:00.000Z'**,  // ISO 8601 date and time  
    Date2: **'2021-02-21'**, // ISO 8601 date, will be added with UTC timezone  
    Date3: **'02/21/2021'** // date, will be added with UTC timezone  
}

Pre-fill values using direct web-link

It is possible to pre-fill recipients data, metadata, variables and fields without embedding form only adding needed data as url parameter:

&KEY=VALUE

where
KEY - metadata or recipients or variables
and
VALUE - encoded data that matches the js config

https://eform.pandadoc.com/?eform=test-eform-id&variables=%7B%22test%22%3A%22test%20value%22%7D

is similar to this code in config

data: {
 variables: {
   test_field_id: 'test value',
 }
},

Handling events

It is possible to capture events from an embedded form. You can subscribe to this events:

loaded - the form is loaded and a user is asked to enter contact details (recipients names and emails)

started - a user has entered contact details for all recipients, press button ‘review document’ for creating document from form

{
  recipients: [{
    first_name: ‘John’,
    last_name: ‘Doe’,
    email: ‘[email protected]’
  }],
}

completed - a user filled in the assigned fields and finalized the document

{
  document, //public document
}

exception - an error occurred while any recipient tries to finish their part

{
 uuid, //document uuid
}

Reload form after submission

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
<div id='form-container-17d74b52-853d-4299-bfa8-d3f89f1fd202'></div>
​
<script type="text/javascript">
    (function () {
        var config = {
            nodeId: 'form-container-17d74b52-853d-4299-bfa8-d3f89f1fd202',
            width: '100%',
            height: '700px',
            url: 'https://eform.pandadoc.com/?eform=ef41d1e6-f0f4-4d77-972e',
            events: {
                loaded: function () {},
                started: function (data) {},
                completed: function (data) {},
                exception: function (data) {}
            },
            data: {},
        };
​
        const dataQueryString = config.data ? Object.keys(config.data)
        .map(function (key) {
          return '&' + key + '=' + encodeURIComponent(JSON.stringify(config.data[key]));
        })
        .join('') : '';
​
        var iframe = document.createElement('iframe');
        iframe.frameBorder = 0;
        iframe.src = config.url + dataQueryString;
​
        if (config.nodeId) {
            var node = document.getElementById(config.nodeId);
            node.style.height = config.height;
            node.style.width = config.width;
            iframe.height = '100%';
            iframe.width = '100%';
            node.append(iframe);
        } else {
            iframe.height = config.height;
            iframe.width = config.width;
            document.body.append(iframe);
        }
​
        var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
        var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';
​
        window[eventMethod](messageEvent,function(e) {
          if (e && e.data && config && iframe && e.source === iframe.contentWindow) {
            try {
              var message = JSON.parse(e.data);
              if (message && message.event) {
                if(message.event ===  "embed.form.completed"){
                    // If form is complete, reload the page after 1 second 
                    setTimeout(() => window.location.reload(), 1000)
                    return false
                };
                var event = message.event.replace('embed.form.', '');
                var callback = config.events ? config.events[event] : null;
                if (callback) {
                  callback(message.data);
                }
              }
            } catch(e) {
                console.log(e)
            }
          }
        },false);
    })();
</script>
</body>
</html>