Action

Airtable.js Example

Posted by agiletortoise, Last update 18 days ago

Proof-of-concept example showing use of AirTable’s JavaScript API embedded in an HTML Preview.

Before using, edit the define template tag steps in this action to add your own API key, base ID, and default table name/field name values.

When run, edit the HTML form to match values in your own AirTable account, then “Update” to fetch records. Then use the “Select” links on rows to choose a row and pass it’s field values back to drafts for use in script steps after the preview.

Steps

  • defineTemplateTag

    name
    airtableAPIKey
    template
    YOUR-API-KEY
  • defineTemplateTag

    name
    airtableBase
    template
    YOUR-BASE-ID
  • defineTemplateTag

    name
    airtableTable
    template
    TestTable
  • defineTemplateTag

    name
    airtableFields
    template
    Name,Description
  • htmlpreview

    <!DOCTYPE html>
    <html dir="auto">
    
    <head>
      <title>AirTable Example</title>
      <meta name="viewport" content="width=device-width, initial-scale=1">
    
      <script type="text/javascript" src="http://media.agiletortoise.com/airtable.js"></script>
      <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.1/build/pure-min.css"
            integrity="sha384-oAOxQR6DkCoMliIh8yFnu25d7Eq/PHS21PClpwjOTeU2jRSq11vu66rf90/cZr47" crossorigin="anonymous">
    
      <style>
        @charset "utf-8";
    
        :root {
          --main-bg-color: white;
          --main-color: black;
          --alternate-bg-color: #efefef;
          --alternate-color: #222222;
          --main-border-color: #BBBBBB;
            --link-color: #627EC9;
        }
    
        @media (prefers-color-scheme: dark) {
          :root {
            --main-bg-color: #222222;
            --main-color: #eeeeee;
            --alternate-bg-color: #444444;
            --alternate-color: #cccccc;
            --main-border-color: #AAAAAA;
              --link-color: #627EC9;
          }
        }
    
        html {
          font-size: 100%;
          font-family: -apple-system, BlinkMacSystemFont, "helvetica neue", helvetica, roboto, noto, "segoe ui", arial, sans-serif;
          line-height: 1.4;
        }
    
        body {
          margin: 0;
          padding: 1em;
          background-color: var(--main-bg-color);
          color: var(--main-color);
        }
    
        @media (max-device-width: 480px) {}
    
        @media (min-device-width: 481px) {
          body {
            margin: auto;
            max-width: 600px;
          }
        }
    
        blockquote {
          font-style: italic;
          margin: 1.5em 2em;
          padding: 1em;
          background-color: var(--alternate-bg-color);
          color: var(--alternate-color);
        }
    
        a {
          color: var(--link-color);
        }
        pre {
          display: block;
          overflow: scroll;
          width: 100%;
          background-color: var(--alternate-bg-color);
          padding: .5em 1em;
          margin: 1em 0;
        }
    
        code {
          background-color: var(--alternate-bg-color);
          color: var(--alternate-color);
          font-family: Menlo, Courier, sans-serif;
          padding: 2px 3px;
        }
    
        table {
          margin: 1.5em 0;
          border: 1px solid var(--main-border-color);
          border-collapse: collapse;
        }
    
        th {
          padding: .25em .5em;
          background: var(--alternate-bg-color);
          border: 1px solid var(--main-border-color);
        }
    
        td {
          padding: .25em .5em;
          border: 1px solid var(--main-border-color);
        }
    
        img {
          max-width: 90%;
        }
      </style>
    </head>
    
    <body>
    
    <p>Demo action showing how data could be fetched from AirTable using their <a href="https://github.com/Airtable/airtable.js">Javascript API</a>, which runs in a browser.
    Before using, fill-in valid table and field names, as well as API key and database ID based on the values from your account.
    </p>
    
    <div id="form-div">
    <form class="pure-form pure-form-stacked">
    <fieldset>
    	<label for="tableName">Table</legend>
    	<input id="tableName" class="pure-input-1-3" type="text" placeholder="Table Name" value="[[airtableTable]]" />
    	<label for="fieldNames">Fields</legend>
    	<input id="fieldNames" class="pure-input-1-3" type="text" placeholder="Field, Names" value="[[airtableFields]]" />
    	<label for="maxRecords">Max Rows</legend>
    	<input id="maxRecords" class="pure-input-1-4" type="text" placeholder="" value="10" />
    	<button type="submit" class="pure-button pure-button-primary" onclick="update();return false;">Update</button>
    </fieldset>
    </form>
    </div>
    
    <div id="result-div">
    <table id="results" class="pure-table">
    </table>
    </div>
    
    <script>
    const apiKey = '[[airtableAPIKey]]';
    const database = '[[airtableBase]]';
    let fetched = [];
    
    let update = () => {
    	let Airtable = require('airtable');
    	let base = new Airtable({apiKey: apiKey}).base(database);
    	let tableName = document.getElementById("tableName").value;
    	let fieldNames = document.getElementById("fieldNames").value.split(",").map(i => i.trim());
    	let max = parseInt(document.getElementById("maxRecords").value);
    	
    	fetched = [];
    	let resultsTable = document.getElementById("results");
    	while (resultsTable.hasChildNodes()) {
    		resultsTable.removeChild(resultsTable.firstChild);
    	}
    	
    	let ix = 0;
    	base(tableName).select({
    		// Selecting the first 3 records in Grid view:
    		maxRecords: 10,
    		view: "Grid view"
    	}).eachPage(function page(records, fetchNextPage) {
    		// This function (`page`) will get called for each page of records.
    		
    		records.forEach(function(record) {
    			let row = resultsTable.insertRow();
    			let rec = { };
    			for (let field of fieldNames) {
    				let cell = row.insertCell(-1);
    				let val = record.get(field);	
    				if (val) {
    					cell.innerHTML = val;
    				}			
    				else {
    					cell.innerHTML = "-";
    				}
    				rec[field] = val;
    			}
    			let sel = row.insertCell(-1);
    			sel.innerHTML = `<a onclick="send(${ix});return false;"">Select</a>`;
    			fetched.push(rec);
    			ix += 1;
    		});
    
    		// To fetch the next page of records, call `fetchNextPage`.
    		// If there are more records, `page` will get called again.
    		// If there are no more records, `done` will get called.
    		fetchNextPage();
    
    	}, function done(err) {
    		if (err) { console.error(err); return; }
    	});
    }
    
    let send = (ix) => {
    	let i = parseInt(ix);
    	Drafts.send("record", fetched[i]);
    	Drafts.continue();
    }
    
    window.onload = (e) => {	
    	//update();
    }
    </script>
    </body>
    
    </html>
    
  • script

    // display record selected
    
    let vals = context.previewValues["record"];
    if (vals) {
    	alert("SELECTED::\n\n" + JSON.stringify(vals));
    }

Options

  • After Success Default
    Notification Error
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.