Quick & Dirty Custom Airtable Dashboard

First of all — I’m not a very good programmer but lately I’ve been getting into building a custom dashboard which pulls machine data, job status, and some other info onto a dashboard so myself and my employees can see what’s going on at the shop. It’s been a little bit of a pain to learn since most of the documentation out there assumes that you actually know what you’re doing — which I don’t. I’m a cnc guy.

Anyways, here’s a basic outline of how I pulled data from our Airtable database into a custom dashboard to be displayed around the shop.

Select the database you want to pull data from, Airtable’s documentation is pretty great in that it actually shows you the code in context of your database.

Pretty simple, copy the code and change the top three variables. Also, for $url, you’ll want to put in any filters after the URL. You can use the Airtable API URL Encoder to easily apply these filters, or you can look them up in the API documentation.

<?php$api_key = ‘YOUR_API_KEY’;$base = ‘YOUR_BASE’;$table = ‘YOUR%20BOARD%20NAME’;$airtable_url = ‘https://api.airtable.com/v0/' . $base . ‘/’ . $table;$url = ‘https://api.airtable.com/v0/' . $base . ‘/’ . $table . ‘?maxRecords=30&view=Master+-+Grid’;$headers = array(‘Authorization: Bearer ‘ . $api_key);$ch = curl_init();curl_setopt($ch, CURLOPT_HTTPGET, 1);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_TIMEOUT, 10);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_URL, $url);$entries = curl_exec($ch);curl_close($ch);echo $entries;?>

Pretty self explanitory, airtableData will now store all the response data. If you want to see the structure of this, open airtable.php directly in the inspector to see the response data.

function getAirtable() {$.ajax({type: “post”,url: “airtable.php”,dataType: “json”,success: function (response) {airtableData = response || null;},});}
setInterval(getAirtable, 5000);

Okay, so this part is a little messy and could probably be done better. Basically we are just sorting the data by status “Waiting” “Active” and “Post Processing”, and then creating an item card for each one, then updating the corresponding columns with the data.

Note #1 — Since this dashboard is for internal use only, I opted to be lazy and just hard code the status names as strings into the first three variables, and then filter it into three objects.

Note #2 — For me this is in a function called tick() since I am doing some other API calls on my dashboard, but you can put this in the getAirtable() function if you want.

Anyways, here’s my example code to get you started:

var waitingJobs = airtableData.records.filter(d => d.fields.Status == “Waiting — Machine”);var activeJobs = airtableData.records.filter(d => d.fields.Status == “Active”);var postJobs = airtableData.records.filter(d => d.fields.Status == “Post Processing”);var r1 = new Array(), j1 = -1;for (var key=0, size=waitingJobs.length; key<size; key++){r1[++j1] = ‘<div class=”item-card”>’;r1[++j1] = ‘<div class=”item-card-upper”>’;r1[++j1] = ‘<p>’;r1[++j1] = waitingJobs[key].fields.Client;r1[++j1] = ‘</p>’;r1[++j1] = ‘</div>’;r1[++j1] = ‘<div class=”item-card-lower”>’;r1[++j1] = ‘<h3>’;r1[++j1] = waitingJobs[key].fields.Name;r1[++j1] = ‘</h3>’;r1[++j1] = ‘<table>’;if (waitingJobs[key].fields.hasOwnProperty(‘Qty’)) {r1[++j1] = ‘<tr><td>Qty:</td><td>’;r1[++j1] = waitingJobs[key].fields.Qty;r1[++j1] = ‘</td></tr>’;}if (waitingJobs[key].fields.hasOwnProperty(‘Cell’)) {r1[++j1] = ‘<tr><td>Cell:</td><td>’;r1[++j1] = waitingJobs[key].fields.Cell;r1[++j1] = ‘</td></tr>’;}if (waitingJobs[key].fields.hasOwnProperty(‘PO’)) {r1[++j1] = ‘<tr><td>PO #:</td><td>’;r1[++j1] = waitingJobs[key].fields.PO;r1[++j1] = ‘</td></tr>’;}r1[++j1] = ‘</table><br />’;r1[++j1] = ‘<a class=”ico airtable” target=”_blank” href=”’;r1[++j1] = waitingJobs[key].fields.Link.url;r1[++j1] = ‘“>-> Open in Airtable</a>’;if (waitingJobs[key].fields.hasOwnProperty(‘LinkedAttachment’)) {r1[++j1] = ‘<a class=”ico doc” target=”_blank” href=”’;r1[++j1] = waitingJobs[key].fields.LinkedAttachment[0].url;r1[++j1] = ‘“>-> View Attachment</a>’;}r1[++j1] = ‘</div>’;r1[++j1] = ‘</div>’;}$(‘#waiting’).html(r1.join(‘’));var r1 = new Array(), j1 = -1;for (var key=0, size=activeJobs.length; key<size; key++){r1[++j1] = ‘<div class=”item-card”>’;r1[++j1] = ‘<div class=”item-card-upper”>’;r1[++j1] = ‘<p>’;r1[++j1] = activeJobs[key].fields.Client;r1[++j1] = ‘</p>’;r1[++j1] = ‘</div>’;r1[++j1] = ‘<div class=”item-card-lower”>’;r1[++j1] = ‘<h3>’;r1[++j1] = activeJobs[key].fields.Name;r1[++j1] = ‘</h3>’;r1[++j1] = ‘<table>’;if (activeJobs[key].fields.hasOwnProperty(‘Qty’)) {r1[++j1] = ‘<tr><td>Qty:</td><td>’;r1[++j1] = activeJobs[key].fields.Qty;r1[++j1] = ‘</td></tr>’;}if (activeJobs[key].fields.hasOwnProperty(‘Cell’)) {r1[++j1] = ‘<tr><td>Cell:</td><td>’;r1[++j1] = activeJobs[key].fields.Cell;r1[++j1] = ‘</td></tr>’;}if (activeJobs[key].fields.hasOwnProperty(‘PO’)) {r1[++j1] = ‘<tr><td>PO #:</td><td>’;r1[++j1] = activeJobs[key].fields.PO;r1[++j1] = ‘</td></tr>’;}r1[++j1] = ‘</table><br />’;r1[++j1] = ‘<a class=”ico airtable” target=”_blank” href=”’;r1[++j1] = activeJobs[key].fields.Link.url;r1[++j1] = ‘“>-> Open in Airtable</a>’;if (activeJobs[key].fields.hasOwnProperty(‘LinkedAttachment’)) {r1[++j1] = ‘<a class=”ico doc” target=”_blank” href=”’;r1[++j1] = activeJobs[key].fields.LinkedAttachment[0].url;r1[++j1] = ‘“>-> View Attachment</a>’;}r1[++j1] = ‘</div>’;r1[++j1] = ‘</div>’;}$(‘#active’).html(r1.join(‘’));var r1 = new Array(), j1 = -1;for (var key=0, size=postJobs.length; key<size; key++){r1[++j1] = ‘<div class=”item-card”>’;r1[++j1] = ‘<div class=”item-card-upper”>’;r1[++j1] = ‘<p>’;r1[++j1] = postJobs[key].fields.Client;r1[++j1] = ‘</p>’;r1[++j1] = ‘</div>’;r1[++j1] = ‘<div class=”item-card-lower”>’;r1[++j1] = ‘<h3>’;r1[++j1] = postJobs[key].fields.Name;r1[++j1] = ‘</h3>’;r1[++j1] = ‘<table>’;if (postJobs[key].fields.hasOwnProperty(‘Qty’)) {r1[++j1] = ‘<tr><td>Qty:</td><td>’;r1[++j1] = postJobs[key].fields.Qty;r1[++j1] = ‘</td></tr>’;}if (postJobs[key].fields.hasOwnProperty(‘Cell’)) {r1[++j1] = ‘<tr><td>Cell:</td><td>’;r1[++j1] = postJobs[key].fields.Cell;r1[++j1] = ‘</td></tr>’;}if (postJobs[key].fields.hasOwnProperty(‘PO’)) {r1[++j1] = ‘<tr><td>PO #:</td><td>’;r1[++j1] = postJobs[key].fields.PO;r1[++j1] = ‘</td></tr>’;}r1[++j1] = ‘</table><br />’;r1[++j1] = ‘<a class=”ico airtable” target=”_blank” href=”’;r1[++j1] = postJobs[key].fields.Link.url;r1[++j1] = ‘“>-> Open in Airtable</a>’;if (postJobs[key].fields.hasOwnProperty(‘LinkedAttachment’)) {r1[++j1] = ‘<a class=”ico doc” target=”_blank” href=”’;r1[++j1] = postJobs[key].fields.LinkedAttachment[0].url;r1[++j1] = ‘“>-> View Attachment</a>’;}r1[++j1] = ‘</div>’;r1[++j1] = ‘</div>’;}$(‘#post-processing’).html(r1.join(‘’));

Hopefully this is helpful to someone, I know it’s crappy code but it’s at least a good starting point for those of us, like myself, who are not very good programmers. If you’re trying to build a similar project and want some help or have some extra ideas to make this better, shoot me an email pete at ftrcnc.com

Resources that were helpful to me:

Airtable API Tutorial on scotch.io: https://scotch.io/tutorials/airtable-api-tutorial-curl-and-javascript
Airtable API Docs: https://airtable.com/api
Airtable API URL Generator: https://codepen.io/airtable/full/rLKkYB

Owner of FTR CNC & Chatter — Roseville, CA