Skip to main content
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"

3. Extracting Data for Non-Table Fields (Text)

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);

5. Extracting Data for Table Fields

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