JavaScript Library

Our JavaScript library is designed to be über flexible while also giving you rich functionality out of the box to plug into your app. There is a whole bunch of documentation on the library here, but here we'll cover the general use cases of our library:

  • Loading your checkbox into a form correctly
  • Using "Test Mode" in development
  • Validating that someone has accepted your various contracts
  • Disabling sending when the box is checked
  • Manually sending acceptance in JavaScript

The example in this Guide

The working example used in this example can be cloned from Github or viewed in your browser here!

Important things to note

Our JavaScript Library has some things that you should know about before jumping into coding:

  • Our Activity API is called when tracking important legal events like your user being shown a contract (displayed), clicking a checkbox (agreed), unchecking a box (disagreed), etc.
  • "Agreed" activities are automagically sent to PactSafe when 1) a user is identified as a signer and 2) that user checks a box.

🚧

HTTPS is Required for Sending Events

In order to see data in your PactSafe Site, you must be using the snippet over HTTPS. Without using SSL, you will not see data being sent to your PactSafe site for Activity events like Agreed, Disagreed, etc.

The Activity API relies on 3 main data structures to function: _ps, Sites, and Groups. The _ps is a global object that can be used to schedule asynchronous tasks and status updates of the API itself. Sites are created by users of PactSafe using the PactSafe app and contain Groups, or collection points, that will be presented to the end signer. Each data structure fires a variety of events. The API also supports using actions both synchronously and asynchronously.

What you need

Copy & paste your global snippet into your page. Every account at PactSafe uses the same snippet of code to load our library in.

(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','//vault.pactsafe.io/ps.min.js','//d3l1mqnl5xpsuc.cloudfront.net/ps.min.js','_ps',4000);

_ps('create', 'YOUR_ACCESS_ID');

Replace YOUR_ACCESS_ID with your own ID, located here. Or, if you just want to load a demo clickwrap in, use the access ID 25b2b173-632a-4227-9877-31d2109d8c98.

Some stuff inside PactSafe's UI. In order to start embedding our library into your app, you need to do a couple of things inside the user interface:

Want to know more about Groups? Check out our knowledgebase.

An HTML page with a form in it. In order to test how our library embeds in your app, you'll need to have a page with a form in it. There are two important things you'll need to be successful in dropping in the library:

  • signer_id selector: You can set who your signer is in two ways:
    • By using the Signer ID Selector in our Groups interface, our library will listen to the input field in your form that you use for your Signer ID. Typically this is an email address or username.
    • Manually set the signer_id with JavaScript.
  • Container selector for your contracts: create a div on your page (or specify an existing div) where your contract(s) checkbox(es) will be injected.

Getting started: Loading in your form

OK, let's get to the fun part — actually making it work. :thumbsup:

Loading a clickwrap

Loading your clickwrap on your page is seriously easy. There are 3 steps to test a working integration to PactSafe.

1. Configuring how and where your clickwrap loads on the page.

Since you've created and published a contract and a group in our interface, you can paste in your group _ps('load') call into your page like so...

(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','//vault.pactsafe.io/ps.min.js','//d3l1mqnl5xpsuc.cloudfront.net/ps.min.js','_ps',4000);

_ps('create', 'YOUR_ACCESS_ID');

// now we add the group here
// replace 'your-group-key' with the key of your group 
// here: https://app.pactsafe.com/groups
_ps('load', 'your-group-key');
// if you don't have your Signer ID Selector or Container Selector set in your Group,
// you can set it with code:
_ps('load', 'your-group-key', { container_selector: "contracts", signer_id_selector: "input-email" });
// the above will load the contract/checkbox HTML into <div id="contracts"></div>
// the signer will be populated and set based on <input id="input-email" />

Some options you have for loading in your group allow you to do a couple of things.

Test Mode: Firstly, to test within your page you can enable test_mode when the JavaScript library is loaded:

// Set test mode here!!
_ps('create', 'YOUR_ACCESS_ID', { test_mode: true });

You can also enable test mode when you send an activity like agreed to PactSafe as outlined here.

As you go, you can clear your test data by going to your signers page in our app and click the three dots in the upper right and selecting "Clear Test Data":

Clear test data used in development

Disable automatic sending: By default, "agreed" activities are sent through our library whenever a user checks the box. To disable that and control when you send your response, use the disable_sending: true parameter:

// disabling sending
_ps('create', '25b2b173-632a-4227-9877-31d2109d8c98', { disable_sending: true });
_ps('load', 'your-group-key');

Overwrite contract container: You can also overwrite the div where your contracts actually show. Note: By specifying the container here, you don't have to define this in the PactSafe interface.

// specify where in your HTML to inject the contracts checkbox(es)
_ps('create', '25b2b173-632a-4227-9877-31d2109d8c98', { disable_sending: true });
_ps('load', 'your-group-key', { container_selector: "contracts" });

Don't forget to map that to your div:

<div id="clickwrap-div"></div>

Overwrite signer_id selector: You can do the same thing when identifying your signer. On blur of your input field marked as your signer_id_selector, the signer_id will automatically be tracked by the library:

// specify the #selector of your signer input field
_ps('create', '25b2b173-632a-4227-9877-31d2109d8c98', { disable_sending: true });
_ps('load', 'your-group-key', { container_selector: "contracts", signer_id_selector: "login-email" });

2. Validating your checkboxes are checked

Before allowing your user to submit the form, you probably want to make sure they check all the right boxes right? We plug right into your client-side validation with our allChecked() method.

_ps.getByKey("register-clickwrap").allChecked() // returns TRUE if all are checked, FALSE if not

The below example that illustrates where you would add a clickwrap and validate that your user has checked all the boxes to proceed.

Remember, by default the library will send activity to PactSafe every time the box is checked.

<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/skeleton.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
  (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','//vault.pactsafe.io/ps.min.js','//d3l1mqnl5xpsuc.cloudfront.net/ps.min.js','_ps',4000);
  
  // initiate PactSafe with your SITE ACCESS ID found here: http://beta.pactsafe.com/settings/account
  _ps('create', '25b2b173-632a-4227-9877-31d2109d8c98');
  
  // load a specific group dynamically loads http://ps-vault.s3.amazonaws.com/s/<SITE ACCESS ID>/groups/<AGREEMT GROUP KEY>/group.js
  // your group key can be found here: https://beta.pactsafe.com/groups
  	// => click into your group and find the "Key" field
  	// => should be something like checkout-click-through-agreement
  _ps('load', 'your-group-key', { container_selector: "contracts", signer_id_selector: "login-email" });
  
  //when the form is submitted, double check that all contract checkboxes are checked
  $(document).ready(function(){
    // when your form is submitted, validate everything is good
    $('#form1').submit(function(e){
      e.preventDefault();
      // ALL client-side validation would go here
      // validate();
      
      // Add a trigger to check status of PactSafe being checked
      if(_ps.getByKey(agreement_key).allChecked()){
        // this.submit();
        console.log("Thanks for agreeing!");
      } else {
        // do something if the user doesn't check all the boxes
        console.log("Agree to our terms. Kthx!");
      }
    });
  });
</script>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="twelve columns">
        <form action="..." method="post" id="form1" class="form">
          <h1>Sign up for our service!</h1>
          <p>Simply fill out the form below and accept our legal terms.</p>
          <div>
            <label for="email-address">Email Address:</label>
            <input type="email" name="email" id="login-email" />
          </div>
          <div id="contracts"></div>
          <input type="submit" value="Submit">
        </form>
      </div>
    </div>
  </div>
</body>
</html>

3. Sending agreed in JavaScript

Many folks who use our library choose not to send an agreed activity until the form is successfully submitted. Is that you? No problem. You can easily send responses using the _ps('send') function like so:

// Sends an "agreed" action for the "register-clickwrap" Group
_ps('register-clickwrap:send', 'agreed');

When using disable_sending: When you disable sending of the checkbox when it's checked, you'll need to set disable_sending to false when you send the call:

// Sends an "agreed" action for the "register-clickwrap" Group
_ps('register-clickwrap:send', 'agreed', {
  disable_sending: false
});

Note: This call is asynchronous with a callback. What does that mean? It means it is added to a queue of calls being made. You won't want to submit the form until the call is completed, so you'll want to implement a call like this in your form...

// this makes an asynchronous call to PactSafe
_ps('register-clickwrap:send', 'agreed', {
  // event_callback is executed once
  // the 'send' call completes
  event_callback: function(e){
    // SUBMIT the form! ... or do whatever :-)
    $('#form').submit();
  }
});

Want more detail?

Find more advanced documentation here.


What’s Next

Learn how to enable debugging with PS.js, populate contracts with dynamic data from your app or website, and learn how to get the URL to download a PDF generated from your click-through contract.