Documentation Index
Fetch the complete documentation index at: https://docs.joyfill.io/llms.txt
Use this file to discover all available pages before exploring further.
This guide explains how to populate and extract data from JoyDoc, focusing on text fields and table fields.
1. Accessing Fields
You can access fields using doc.fields. The fields property contains an array of all field objects in the document.
// Access all fields
const allFields = doc.fields;
// Example field structure
{
"_id": "name-field",
"identifier": "name",
"type": "text",
"title": "Your Name",
"value": "",
"file": "file1"
}
2. Finding Fields
Fields can be found using their fieldId (which is the _id property of the field).
// Find a specific field by its ID
const findFieldById = (doc, fieldId) => {
return doc.fields.find(field => field._id === fieldId);
};
// Example usage
const nameField = findFieldById(doc, "name-field");
console.log(nameField.title); // "Your Name"
At any moment, you can get the latest document from JoyDoc.onChange and extract text field values using the fieldId.
// In your JoyDoc component
<JoyDoc
doc={doc}
onChange={(changelog, updatedDoc) => {
// Extract text field value
const textField = updatedDoc.fields.find(
(field) => field._id === "name-field"
);
const textValue = textField.value;
console.log("Text field value:", textValue);
}}
/>;
4. Populating Data
You can populate fields by injecting values into doc.fields[].value. Here’s how to populate text fields:
// Populate text fields
const populateTextFields = (doc) => {
const updatedDoc = { ...doc };
const updatedFields = [...doc.fields];
// Find and populate specific text fields
const nameField = updatedFields.find(field => field._id === "name-field");
if (nameField) {
nameField.value = "John Doe";
}
const emailField = updatedFields.find(field => field._id === "email-field");
if (emailField) {
emailField.value = "john.doe@example.com";
}
updatedDoc.fields = updatedFields;
return updatedDoc;
};
// Example usage
const populatedDoc = populateTextFields(doc);
You can get a table field value by mapping through fields and accessing the table field’s value using the table fieldId.
// Extract table field data
const extractTableData = (doc, tableFieldId) => {
const tableField = doc.fields.find((field) => field._id === tableFieldId);
if (tableField && tableField.type === "table") {
return tableField.value.map((row) => {
const rowData = {};
// Extract data from each cell
Object.keys(row.cells).forEach((columnId) => {
const column = tableField.tableColumns.find(
(col) => col._id === columnId
);
rowData[column.title] = row.cells[columnId];
});
return rowData;
});
}
return [];
};
// Example usage
const tableData = extractTableData(doc, "68ef815e4c716f176ea8d2ba");
console.log("Table data:", tableData);
6. Populating Table Fields
You can populate table rows by updating the value.cells property. Here’s how to populate table fields:
// Populate table fields
const populateTableFields = (doc, tableFieldId) => {
const updatedDoc = { ...doc };
const updatedFields = [...doc.fields];
const tableField = updatedFields.find((field) => field._id === tableFieldId);
if (tableField && tableField.type === "table") {
// Create cells object with column data
const cells = {};
tableField.tableColumns.forEach((column) => {
if (column.type === "text") {
cells[column._id] = "Sample text data";
} else if (column.type === "dropdown") {
cells[column._id] = column.options[0]._id; // Select first option
}
});
// Create new rows with populated cells
const newRows = [
{
_id: "row1",
deleted: false,
cells: { ...cells },
},
{
_id: "row2",
deleted: false,
cells: { ...cells },
},
];
tableField.value = newRows;
tableField.rowOrder = ["row1", "row2"];
}
updatedDoc.fields = updatedFields;
return updatedDoc;
};
// Example usage
const populatedTableDoc = populateTableFields(doc, "68ef815e4c716f176ea8d2ba");
Complete Example
Here’s a complete example showing both population and extraction:
import React, { useState } from "react";
import JoyDoc from "./JoyDoc";
const MyForm = () => {
const [doc, setDoc] = useState(initialDoc);
// Populate data function
const populateData = () => {
const updatedDoc = { ...doc };
const updatedFields = [...doc.fields];
// Populate text field
const nameField = updatedFields.find((field) => field._id === "name-field");
if (nameField) {
nameField.value = "Jane Smith";
}
// Populate table field
const tableField = updatedFields.find(
(field) => field._id === "68ef815e4c716f176ea8d2ba"
);
if (tableField && tableField.type === "table") {
const cells = {};
tableField.tableColumns.forEach((column) => {
if (column.type === "text") {
cells[column._id] = "Table cell data";
}
});
tableField.value = [{ _id: "row1", deleted: false, cells: { ...cells } }];
tableField.rowOrder = ["row1"];
}
updatedDoc.fields = updatedFields;
setDoc(updatedDoc);
};
// Extract data function
const extractData = () => {
// Extract text field
const nameField = doc.fields.find((field) => field._id === "name-field");
console.log("Name:", nameField?.value);
// Extract table data
const tableField = doc.fields.find(
(field) => field._id === "68ef815e4c716f176ea8d2ba"
);
if (tableField && tableField.type === "table") {
const tableData = tableField.value.map((row) => {
const rowData = {};
Object.keys(row.cells).forEach((columnId) => {
const column = tableField.tableColumns.find(
(col) => col._id === columnId
);
rowData[column.title] = row.cells[columnId];
});
return rowData;
});
console.log("Table data:", tableData);
}
};
return (
<div>
<button onClick={populateData}>Populate Data</button>
<button onClick={extractData}>Extract Data</button>
<JoyDoc
doc={doc}
onChange={(changelog, updatedDoc) => {
setDoc(updatedDoc);
}}
/>
</div>
);
};
Key Points to Remember
- Field Access: Use
doc.fields to access all fields
- Field Finding: Use
field._id to find specific fields
- Text Fields: Access value directly with
field.value
- Table Fields: Access rows through
field.value array, each row has cells object
- Population: Modify
field.value for text fields, or field.value[].cells for table fields
- Extraction: Use
onChange callback to get the latest document state
- Immutable Updates: Always create new objects when updating to avoid mutation issues