Loading a Clickwrap 101

Overview

Below, we'll cover a few key topics to getting up and running with the PactSafe JavaScript Library.

Requirements

To get started, you'll need to ensure that you have the following:

  • Ironclad Clickwrap Site Access ID. More info in the Authentication page.
  • Group key from a published Ironclad Clickwrap Group that contains published Ironclad Clickwrap contracts.
  • Development environment with SSL enabled

Loading Your First Clickwrap

Ironclad Clickwrap Snippet

Our JavaScript snippet was designed to load our external JavaScript library and give you an interface to interact with your code.

Load the snippet into your page, preferably in the <head> of the page.

// Minified PactSafe Snippet
(function(w,d,s,c,f,n,t,g,a,b,l){w['PactSafeObject']=n;w[n]=w[n]||function(){(w[n].q=w[n].q||[]).push(arguments)},w[n].on=function(){(w[n].e=w[n].e||[]).push(arguments)},w[n].once=function(){(w[n].eo=w[n].eo||[]).push(arguments)},w[n].off=function(){(w[n].o=w[n].o||[]).push(arguments)},w[n].t=1*new Date(),w[n].l=0;a=d.createElement(s);b=d.getElementsByTagName(s)[0];a.async=1;a.src=c;a.onload=a.onreadystatechange=function(){w[n].l=1};a.onerror=a.onabort=function(){w[n].l=0};b.parentNode.insertBefore(a,b);setTimeout(function(){if(!w[n].l&&!w[n].loaded){w[n].error=1;a=d.createElement(s);a.async=1;a.src=f;a.onload=a.onreadystatechange=function(){w[n].l=1};a.onerror=a.onabort=function(){w[n].l=0};b.parentNode.insertBefore(a,b);l=function(u,e){try{e=d.createElement('img');e.src='https://d3r8bdci515tjv.cloudfront.net/error.gif?t='+w[n].t+'&u='+encodeURIComponent(u);d.getElementsByTagName('body')[0].appendChild(e)}catch(x){}};l(c);setTimeout(function(){if(!w[n].l&&!w[n].loaded){w[n].error=1;if(g&&'function'==typeof g){g.call(this);}l(f)}},t)}},t)})(window,document,'script','https://vault.pactsafe.io/ps.min.js','https://d3l1mqnl5xpsuc.cloudfront.net/ps.min.js','_ps',4000);

Loading a Group

In order to get your clickwrap loaded into the page, we need to create the Ironclad Clickwrap Site object with a Clickwrap Site Access ID and then load the Clickwrap group using its group key. Follow along in the code below.

📘

Note on Sending Acceptance and the Signer ID Listener

By default, Ironclad Clickwrap will automatically send acceptance when the Group's checkbox is checked and when the signer ID selector (in this case an email address field) contains a value.

// We'll need a couple of things to get started from PactSafe.
var siteAccessId = '1e8ddd9d-f32c-4dc7-9c13-62095e6d4317'; // A PactSafe Site Access ID
var groupKey = "clickwrap-example"; // A PactSafe Group Key.

// Creates a Site object with the a PactSafe Site Access ID.
_ps('create', siteAccessId);

// Since we're testing, we can enable debugging
// which will log events to console. You'll want to
// set this to false in a production environment.
_ps.debug = true;

// Options set on the PactSafe Group.
var groupOptions = {
  container_selector: 'pactsafeContainer', // HTML Element ID of where we want the clickwrap to load in the page.
  display_all: true, // Always display the contracts, even if previously signed by the Signer.
  signer_id_selector: 'exampleInputEmail1', // Uses the email input field value as the Signer ID and listen to the field.
  test_mode: true, // Allows you to clear test data from the PactSafe web app.
}

// Load a Clickwrap group into the page.
_ps('load', groupKey, groupOptions);

Verifying Acceptance

Pretty often, you'll want to ensure acceptance of the contracts within the group before proceeding. In order to do this, you can add validation that may look like the below.

🚧

Example Only Code

Please note that the example code is for demonstration purposes only. Your implementation will most likely be different than what is shown here.

// Get the form element on the page.
var pageFormElement = function() {
  return document.getElementById('myPageForm');
}

// Return whether to block the submission or not.
var blockSubmission = function() {
  // Check to ensure we're able to get the Group successfully.
  if (_ps.getByKey(groupKey)) {

    // Return if we should block the submission using the .block() method
    // provided by the Group object.
    return _ps.getByKey(groupKey).block();
  } else {
    // We weren't able to get the group,
    // so blocking form submission may be needed.
    return true;
  }
}

// We want to prevent the form submission
// unless acceptance has gone through.
function addFormAcceptanceValidation() {
  // Get the form element.
  var form = pageFormElement();

  // Return if no form is found in the page.
  if (!form) return;

  // Add listener for form submissions.
  form.addEventListener('submit', function(event) {
    // Prevent the form from automatically submitting without
    // checking PactSafe acceptance first.
    event.preventDefault();

    if (!blockSubmission()) {
      // We don't need to block the form submission,
      // so submit the form.
      form.submit();
    } else {
      // We can get the alert message if set on the group
      // or define our own if it's not.
      var acceptanceAlertLanguage = (_ps.getByKey(groupKey) && _ps.getByKey(groupKey).get('alert_message')) ?  _ps.getByKey(groupKey).get('alert_message') :  'Please accept our Terms and Conditions.'

      // Alert the user that the Terms need to be accepted before continuing.
      alert(acceptanceAlertLanguage);
    }
  });
}

// Set up validation of Terms before allowing form submission.
if (document.readyState === 'loading') {  // Loading hasn't finished yet
  document.addEventListener('DOMContentLoaded', addFormAcceptanceValidation);
} else {  // `DOMContentLoaded` has already fired
  addFormAcceptanceValidation();
}

Full Example Code

Below, you'll find the code to a full working example, which includes a sample form validation piece.

🚧

Example Only

Please note that the example code is for demonstration purposes only. Your implementation will most likely be different than what is shown here.

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha512-MoRNloxbStBcD8z3M/2BmnT+rg4IsMxPkXaGh2zD6LGNNFE80W3onsAhRcMAMrSoyWL9xD7Ert0men7vR8LUZg==" crossorigin="anonymous" />

    <title>Simple Form!</title>
  </head>
  <body>
    <div class="container">
      <h1>PactSafe Example with a Form</h1>

      <form id="myPageForm">
        <div class="form-group">
          <label for="exampleInputEmail1">Email address</label>
          <input type="email" class="form-control" id="exampleInputEmail1" />
        </div>
        <div class="form-group">
          <label for="exampleInputPassword1">Password</label>
          <input type="password" class="form-control" id="exampleInputPassword1" />
        </div>

        <!-- Note the div container here! -->
        <div id="pactsafeContainer"></div>

        <button type="submit" class="btn btn-primary">Submit</button>
      </form>
    </div>

    <!-- Optional JavaScript -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.bundle.min.js" integrity="sha512-kBFfSXuTKZcABVouRYGnUo35KKa1FBrYgwG4PAx7Z2Heroknm0ca2Fm2TosdrrI356EDHMW383S3ISrwKcVPUw==" crossorigin="anonymous"></script>

    <!-- PactSafe Implementation -->
    <script>
      // Minified PactSafe Snippet
      (function(w,d,s,c,f,n,t,g,a,b,l){w['PactSafeObject']=n;w[n]=w[n]||function(){(w[n].q=w[n].q||[]).push(arguments)},w[n].on=function(){(w[n].e=w[n].e||[]).push(arguments)},w[n].once=function(){(w[n].eo=w[n].eo||[]).push(arguments)},w[n].off=function(){(w[n].o=w[n].o||[]).push(arguments)},w[n].t=1*new Date(),w[n].l=0;a=d.createElement(s);b=d.getElementsByTagName(s)[0];a.async=1;a.src=c;a.onload=a.onreadystatechange=function(){w[n].l=1};a.onerror=a.onabort=function(){w[n].l=0};b.parentNode.insertBefore(a,b);setTimeout(function(){if(!w[n].l&&!w[n].loaded){w[n].error=1;a=d.createElement(s);a.async=1;a.src=f;a.onload=a.onreadystatechange=function(){w[n].l=1};a.onerror=a.onabort=function(){w[n].l=0};b.parentNode.insertBefore(a,b);l=function(u,e){try{e=d.createElement('img');e.src='https://d3r8bdci515tjv.cloudfront.net/error.gif?t='+w[n].t+'&u='+encodeURIComponent(u);d.getElementsByTagName('body')[0].appendChild(e)}catch(x){}};l(c);setTimeout(function(){if(!w[n].l&&!w[n].loaded){w[n].error=1;if(g&&'function'==typeof g){g.call(this);}l(f)}},t)}},t)})(window,document,'script','https://vault.pactsafe.io/ps.min.js','https://d3l1mqnl5xpsuc.cloudfront.net/ps.min.js','_ps',4000);

      // We'll need a couple of things to get started from PactSafe.
      var siteAccessId = '1e8ddd9d-f32c-4dc7-9c13-62095e6d4317'; // A PactSafe Site Access ID
      var groupKey = "clickwrap-example"; // A PactSafe Group Key.

      // Creates a Site object with the a PactSafe Site Access ID.
      _ps('create', siteAccessId);

      // Since we're testing, we can enable debugging
      // which will log events to console. You'll want to
      // set this to false in a production environment.
      _ps.debug = true;

      // Options set on the PactSafe Group.
      var groupOptions = {
        container_selector: 'pactsafeContainer', // ID of where we want the clickwrap to load in the page.
        display_all: true, // Always display the contracts, even if previously signed by the Signer.
        signer_id_selector: 'exampleInputEmail1', // Uses the email input field value as the Signer ID and listen to the field.
        test_mode: true, // Allows you to clear test data from the PactSafe web app.
      }

      // Load a Clickwrap group into the page.
      _ps('load', groupKey, groupOptions);

      // If there's an error from the PactSafe snippet,
      // you may want to prevent submission if needed.
      _ps.on('error', function(message, event_type, context) {
        // Handle any errors.
        console.log(arguments);
      });

      // Get the form element on the page.
      var pageFormElement = function() {
        return document.getElementById('myPageForm');
      }

      // Return whether to block the submission or not.
      function blockSubmission() {
        // Check to ensure we're able to get the Group successfully.
        if (_ps.getByKey(groupKey)) {

          // Return if we should block the submission using the .block() method
          // provided by the Group object.
          return _ps.getByKey(groupKey).block();
        } else {
          // We weren't able to get the group,
          // so blocking form submission may be needed.
          return true;
        }
      }

      // We want to prevent the form submission
      // unless acceptance has gone through.
      function addFormAcceptanceValidation() {
        // Get the form element.
        var form = pageFormElement();

        // Return if no form is found in the page.
        if (!form) return;

        // Add listener for form submissions.
        form.addEventListener('submit', function(event) {
          // Prevent the form from automatically submitting without
          // checking PactSafe acceptance first.
          event.preventDefault();

          if (!blockSubmission()) {
            // We don't need to block the form submission,
            // so submit the form.
            form.submit();
          } else {
            // We can get the alert message if set on the group
            // or define our own if it's not.
            var acceptanceAlertLanguage = (_ps.getByKey(groupKey) && _ps.getByKey(groupKey).get('alert_message')) ?  _ps.getByKey(groupKey).get('alert_message') :  'Please accept our Terms and Conditions.'

            // Alert the user that the Terms need to be accepted before continuing.
            alert(acceptanceAlertLanguage);
          }
        });
      }

      // Set up validation of Terms before allowing form submission.
      if (document.readyState === 'loading') {  // Loading hasn't finished yet
        document.addEventListener('DOMContentLoaded', addFormAcceptanceValidation);
      } else {  // `DOMContentLoaded` has already fired
        addFormAcceptanceValidation();
      }
    </script>
  </body>
</html>

Did this page help you?