Skip to content
Coda Lab Experiments

icon picker
Running Javascript

Is it possible to write JS in a document and run it? 🤔
Yes 🥳 ❗But don’t get too excited 🥺

Hello HTML

Can we get condensed tables?

Hello JS Scripts

Mode
Mode
Value
1
Just run it
code
2
Wrap in function
return_code
3
Run as JS Object
jsobject
4
Run as JSON
json
There are no rows in this table

JS Environment Check
Name
Type
Keys
1
window
"undefined"
2
document
"undefined"
3
createElement
"undefined"
4
getSelection
"undefined"
5
Element
"undefined"
6
HTMLElement
"undefined"
7
alert
"undefined"
8
prompt
"undefined"
9
console
"object"
10
Math
"object"
11
coda
"object"
12
There are no rows in this table
@Saulo Vallory
NEXT: Try to get a JSON of the control in the JS side

Code of the Hello JS Pack

Retrieved using

Packs Metadata
It's a Pack that gets information about Packs. 🤯 By Eric Koleda
It's a Pack called "Packs" with a sync table called "Packs" that lists all of the Packs, including itself, the Packs Pack.
There's also a formula called "Pack" and a column format called "Pack" that load information about a single Pack, such as the aforementioned Packs Pack.
PACKS!
Icon designed by OpenMoji – the open-source emoji and icon project. License: CC BY-SA 4.0 Cover photo by SHVETS production (via Pexels)
See more
coda.io

Formula

[Packs Metadata]::SourceCode([Saulo Vallory], "https://coda.io/packs/hello-js-24497")

Expand to See Result

/*Start making Packs!Try out the hello world sample below to create your first build.*/
// This import statement gives you access to all parts of the Coda Packs SDK.import * as coda from "@codahq/packs-sdk";
// type ExecutionModes = "code" | "return_code" | "JsObject" | "JSON";enum ExecutionMode { code = "{code}", return_code = "return {code}", jsobject = "parse JsObject", json = "parse JSON"}
const ExecutionAutoComplete = Object.entries(ExecutionMode).map( ([value, display]) => ({ display, value }) )
// This line creates your new Pack.export const pack = coda.newPack();
const commonParameters: coda.ParamDefs = [ coda.makeParameter({ name: "mode", type: coda.ParameterType.String, autocomplete: ExecutionAutoComplete, suggestedValue: "prepend", description: "Use execution mode to reduce the amount of code you have to write. " }),
coda.makeParameter({ name: "code", type: coda.ParameterType.String, description: "The code to be executed" }),];
let variableParams: coda.ParamDefs = [ { ...commonParameters[1], name: "moreCode" }]
type ExecutionResult = { input: string, result: string | number | boolean | object | Array<string | number | boolean | object>; resultAsString: string}
const ExecutionResultBaseSchema = coda.makeObjectSchema({ displayProperty: "resultAsString", properties: { id: { type: coda.ValueType.String },
input: { type: coda.ValueType.String, }, result: { type: coda.ValueType.Object, properties: {}, includeUnknownProperties: true },
resultAsString: { type: coda.ValueType.String, description: "JSON.stringify'ed result" }, },
});
function runJS(mode: ExecutionMode, firstSnippet: string, ...moreSnippets: string[]): ExecutionResult { try { const input = [firstSnippet, ...moreSnippets].join(';'); let code = input; let result;
if (ExecutionMode.jsobject == mode) { result = JSON.parse(JSON.stringify(input)) } else if (ExecutionMode.json == mode) { result = JSON.parse(input); } else { if (ExecutionMode.return_code == mode) { code = `return ${input}`; }
result = Function(code)();
let modified = false;
if (!result) { modified = true; result = Function(`return (${code});`)(); }
if (!result) { throw new coda.UserVisibleError('Your code must always return a value'); }
console.debug(`[HelloJS] Running ${modified ?? 'modified '}code`, { code, result }); }
return { input, result, resultAsString: JSON.stringify(result) }; } catch(e) { throw new coda.UserVisibleError(e.message); }}
/** * SayHelloJS Action */pack.addFormula({ name: "SayHelloJS", description: "Runs some javascript code", resultType: coda.ValueType.Object, schema: ExecutionResultBaseSchema, isAction: true, parameters: commonParameters, varargParameters: variableParams, execute: async function ([mode, code, ...moreCode]: [ExecutionMode, string, ...string[]], context: coda.ExecutionContext) { if (!Object.values(ExecutionMode).includes(mode)) { throw new coda.UserVisibleError("Invalid execution mode: " + mode); }
return runJS(mode, code, ...moreCode); },});
/** * HelloJS Formula */pack.addFormula({ // This is the name that will be called in the formula builder. // Remember, your formula name cannot have spaces in it. name: "HelloJS", description: "Say Hello JS",
// If your formula requires one or more inputs, you’ll define them here. // Here, we're creating a string input called “name”. parameters: commonParameters, varargParameters: variableParams,
// The resultType defines what will be returned in your Coda doc. Here, we're // returning a simple text string. resultType: coda.ValueType.Object, schema: ExecutionResultBaseSchema,
// Everything inside this execute statement will happen anytime your Coda // formula is called in a doc. An array of all user inputs is always the 1st // parameter. execute: async function ([mode, code, ...moreCode]: [ExecutionMode, string, ...string[]], context: coda.ExecutionContext) { if (!Object.values(ExecutionMode).includes(mode)) { throw new coda.UserVisibleError("Invalid execution mode: " + mode); }
return runJS(mode, code, ...moreCode); },});

const EditorSchema = coda.makeObjectSchema({ properties: { name: { type: coda.ValueType.String }, code: { type: coda.ValueType.String, codaType: coda.ValueHintType.Html, mutable: true }, // ... }, // Use the SKU in mention chips, to save space. displayProperty: "name", // Display the full product name in cards. titleProperty: "name", snippetProperty: "code",});
pack.addFormula({ name: "JsEditor", description: "Edit your code here",
resultType: coda.ValueType.Object, schema: EditorSchema,
parameters: [ coda.makeParameter({ type: coda.ParameterType.String, name: "name", description: "The name of your script", }),
coda.makeParameter({



Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.