Skip to main content

Overview

This guide shows you how to integrate Joyfill Components into your JavaScript application using ES modules and a build tool like Parcel.

🚀 Quick Start

Setup Project

Create a new project and install dependencies:
mkdir my-joyfill-app
cd my-joyfill-app
npm init -y
npm install @joyfill/components@latest
npm install --save-dev parcel

Create HTML File

Create src/index.html:
<!DOCTYPE html>
<html>
<head>
    <title>Joyfill Form - ES Module</title>
    <meta charset="UTF-8" />
</head>
<body>
    <h1>Contact Form</h1>
    <div id="joyfill-container"></div>

    <script type="module" src="./index.js"></script>
</body>
</html>

Create JavaScript Module

Create src/index.js:
import Joyfill from "@joyfill/components/dist/joyfill.min.js";

// Complete contact form example
const contactForm = {
    "_id": "68f231604484695c16d65f97",
    "identifier": "doc_68f231604484695c16d65f97",
    "name": "New Doc",
    "files": [
        {
            "_id": "68f231607dee0bbd73994f87",
            "name": "New File",
            "pageOrder": [
                "68f23160b929e32e60e663a0"
            ],
            "pages": [
                {
                    "_id": "68f23160b929e32e60e663a0",
                    "name": "New Page",
                    "width": 816,
                    "height": 1056,
                    "rowHeight": 8,
                    "cols": 8,
                    "fieldPositions": [
                        {
                            "_id": "68f23164c57b7fe946d32b1b",
                            "type": "text",
                            "displayType": "original",
                            "x": 0,
                            "y": 0,
                            "width": 4,
                            "height": 8,
                            "field": "68f23164886cdb084afec912"
                        },
                        {
                            "_id": "68f231663b6a898390b23fec",
                            "type": "textarea",
                            "displayType": "original",
                            "x": 4,
                            "y": 0,
                            "width": 4,
                            "height": 23,
                            "field": "68f2316612113f6141fac40a"
                        },
                        {
                            "_id": "68f231673dc5e58c883c8437",
                            "type": "number",
                            "displayType": "original",
                            "x": 0,
                            "y": 8,
                            "width": 4,
                            "height": 8,
                            "field": "68f23167998040ea25a54fa8"
                        },
                        {
                            "_id": "68f231796f5ea38ae37f951b",
                            "type": "text",
                            "displayType": "original",
                            "x": 0,
                            "y": 16,
                            "width": 4,
                            "height": 8,
                            "field": "68f23179479739cf0883d27e"
                        }
                    ],
                    "layout": "grid",
                    "presentation": "normal",
                    "padding": 24
                }
            ],
            "styles": {
                "margin": 4
            }
        }
    ],
    "fields": [
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f23164886cdb084afec912",
            "type": "text",
            "title": "Name",
            "identifier": "field_68f23164886cdb084afec912"
        },
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f2316612113f6141fac40a",
            "type": "textarea",
            "title": "Comments",
            "identifier": "field_68f2316612113f6141fac40a",
            "value": ""
        },
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f23167998040ea25a54fa8",
            "type": "number",
            "title": "Phone number",
            "identifier": "field_68f23167998040ea25a54fa8"
        },
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f23179479739cf0883d27e",
            "type": "text",
            "title": "Email",
            "identifier": "field_68f23179479739cf0883d27e"
        }
    ],
    "type": "document"
};

// Initialize the form
Joyfill.JoyDoc(
  document.getElementById('joyfill-container'),
  {
    doc: contactForm,
    mode: 'edit',
    onChange: (changelogs, doc) => {
      console.log('Form updated:', doc);
    }
  }
);

Add Package.json Scripts

Update your package.json:
{
  "name": "my-joyfill-app",
  "version": "1.0.0",
  "scripts": {
    "start": "parcel src/index.html",
    "build": "parcel build src/index.html"
  },
  "dependencies": {
    "@joyfill/components": "latest"
  },
  "devDependencies": {
    "parcel": "^2.8.2"
  }
}

Start Development Server

npm start
Open http://localhost:1234 in your browser.

Complete Project Structure

my-joyfill-app/
├── src/
│   ├── index.html          # Main HTML file
│   └── index.js            # JavaScript module
├── package.json            # Project configuration
└── dist/                   # Built files (auto-generated)

Complete HTML Example

<!DOCTYPE html>
<html>
  <head>
    <title>Joyfill Form - ES Module</title>
    <meta charset="UTF-8" />
    <style>
      body {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
          max-width: 800px;
          margin: 0 auto;
          padding: 20px;
          background-color: #f5f5f5;
      }

      .container {
          background: white;
          border-radius: 8px;
          padding: 30px;
          box-shadow: 0 2px 10px rgba(0,0,0,0.1);
      }

      h1 {
          color: #333;
          text-align: center;
          margin-bottom: 30px;
      }

      #joyfill-container {
          min-height: 500px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>Contact Us</h1>
      <div id="joyfill-container"></div>
    </div>

    <script type="module" src="./index.js"></script>
  </body>
</html>

Complete JavaScript Example

import Joyfill from "@joyfill/components/dist/joyfill.min.js";

// Complete contact form with validation
const contactForm = {
    "_id": "68f231604484695c16d65f97",
    "identifier": "doc_68f231604484695c16d65f97",
    "name": "New Doc",
    "files": [
        {
            "_id": "68f231607dee0bbd73994f87",
            "name": "New File",
            "pageOrder": [
                "68f23160b929e32e60e663a0"
            ],
            "pages": [
                {
                    "_id": "68f23160b929e32e60e663a0",
                    "name": "New Page",
                    "width": 816,
                    "height": 1056,
                    "rowHeight": 8,
                    "cols": 8,
                    "fieldPositions": [
                        {
                            "_id": "68f23164c57b7fe946d32b1b",
                            "type": "text",
                            "displayType": "original",
                            "x": 0,
                            "y": 0,
                            "width": 4,
                            "height": 8,
                            "field": "68f23164886cdb084afec912"
                        },
                        {
                            "_id": "68f231663b6a898390b23fec",
                            "type": "textarea",
                            "displayType": "original",
                            "x": 4,
                            "y": 0,
                            "width": 4,
                            "height": 23,
                            "field": "68f2316612113f6141fac40a"
                        },
                        {
                            "_id": "68f231673dc5e58c883c8437",
                            "type": "number",
                            "displayType": "original",
                            "x": 0,
                            "y": 8,
                            "width": 4,
                            "height": 8,
                            "field": "68f23167998040ea25a54fa8"
                        },
                        {
                            "_id": "68f231796f5ea38ae37f951b",
                            "type": "text",
                            "displayType": "original",
                            "x": 0,
                            "y": 16,
                            "width": 4,
                            "height": 8,
                            "field": "68f23179479739cf0883d27e"
                        }
                    ],
                    "layout": "grid",
                    "presentation": "normal",
                    "padding": 24
                }
            ],
            "styles": {
                "margin": 4
            }
        }
    ],
    "fields": [
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f23164886cdb084afec912",
            "type": "text",
            "title": "Name",
            "identifier": "field_68f23164886cdb084afec912"
        },
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f2316612113f6141fac40a",
            "type": "textarea",
            "title": "Comments",
            "identifier": "field_68f2316612113f6141fac40a",
            "value": ""
        },
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f23167998040ea25a54fa8",
            "type": "number",
            "title": "Phone number",
            "identifier": "field_68f23167998040ea25a54fa8"
        },
        {
            "file": "68f231607dee0bbd73994f87",
            "_id": "68f23179479739cf0883d27e",
            "type": "text",
            "title": "Email",
            "identifier": "field_68f23179479739cf0883d27e"
        }
    ],
    "type": "document"
};

// Initialize the form
const joyDocInstance = Joyfill.JoyDoc(
  document.getElementById('joyfill-container'),
  {
    doc: contactForm,
    mode: 'edit',
    onChange: (changelogs, doc) => {
      console.log('Form updated:', doc);
      console.log('Changes:', changelogs);

      // Save form data
      saveFormData(doc);
    },
    onError: (error) => {
      console.error('Form error:', error);
    }
  }
);

// Helper function to save form data
async function saveFormData(doc) {
  try {
    const response = await fetch('/api/contact', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(doc)
    });

    if (response.ok) {
      console.log('Form saved successfully');
    } else {
      console.error('Failed to save form');
    }
  } catch (error) {
    console.error('Error saving form:', error);
  }
}

Build for Production

npm run build
This creates optimized files in the dist/ folder ready for deployment.

Common Configuration Options

Joyfill.JoyDoc(container, {
    doc: yourFormData,           // Your form JSON
    mode: 'edit',               // 'edit' | 'view' | 'preview'
    view: 'desktop',            // 'desktop' | 'mobile' | 'tablet'
    width: 800,                 // Component width
    height: 600,                // Component height
    onChange: (changes, doc) => {
        // Handle form changes
    },
    onError: (error) => {
        // Handle errors
    },
    onFocus: (fieldId, fieldData) => {
        // Handle field focus
    },
    onBlur: (fieldId, fieldData) => {
        // Handle field blur
    }
});

That’s it! 🎉

Your form is now ready with ES modules. The build process will bundle everything for production deployment.