Example App
For those who are interested I finally made that “instant print” thing…
I made a quick react app (use npx create-react-app or vite).
Uses React Router’s “useSearchParams” to grab the URI query parameters and plop their value in the component’s fields, generating a label with a QR code.
Once rendered, window.print() opens the print dialog.
//Test URI: lotlabel?lotId=dHVhjE7f28cJ3NNNB27Dsu&sku=PAINT0016&jobName=GARD%2010574&jobId=23717&release=1of1&kit=23717-R1-K1
import { useSearchParams } from "react-router-dom";
import { useEffect } from "react";
import QRCode from "react-qr-code";
function LotLabel() {
let [searchParams] = useSearchParams();
const allParams = {};
for (const [key, value] of searchParams.entries()) {
allParams[key] = value;
}
const { lotId, sku, jobName, jobId, release, kit } = allParams;
useEffect(() => {
window.print();
}, []);
return (
<div className="label">
<div className="lot-info">
<p>BMP SKU:</p>
<h1>{sku}</h1>
<h3>
Lot ID: <i>{lotId}</i>
</h3>
<QRCode size={512} value={lotId} level={"H"} />
</div>
{jobId && (
<div className="job-info">
<p>
Job Name: <b>{jobName}</b>
</p>
<p>
Job ID: <b>{jobId}</b>
</p>
<p>
Release: <b>{release}</b>
</p>
<p>
Kit: <b>{kit}</b>
</p>
</div>
)}
</div>
);
}
export default LotLabel;
Over in my AppSheet app, my Item page has a ‘dynamic’ link action button.
CONCATENATE(
"https://labelprinter-cra.vercel.app/lotLabel?lotId=",[Lot ID],
IF(ISNOTBLANK([SKU]),CONCATENATE("&sku=",[SKU]),""),
IF(ISNOTBLANK([Job Name]),CONCATENATE("&jobName=",[Job Name]),""),
IF(ISNOTBLANK([Job ID]),CONCATENATE("&jobId=",[Job ID]), ""),
IF(ISNOTBLANK([Release]),
CONCATENATE("&release=",[Release].[Release Number],"of",[Job ID].[Total Releases]),
""
),
IF(ISNOTBLANK([Kit ID]),CONCATENATE("&kit=",[Kit ID]),"")
)
With this I can render the document right when I make a change; without syncing!
Keep in mind this is a pretty limited use-case. URIs have a character limit. But you could do some stuff with a database and webhooks if you needed to pull more information (though at that point you might as well make a webapp).
I guess you could do it in raw js/html too with
document.addEventListener('DOMContentLoaded', function() {
const params = new URLqueryParams(window.location.search);
const lotID = params.get('lotId')
populateDocument(lotId)
window.print();
}
function populateDocument(lotID) {
document.getElementById('lotId').textContent = `Lot ID: ${lotID}`;
}
or whatever it would be.