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.
Overview
JoyDoc provides validation for required fields, ensuring users complete necessary information before submitting forms. The validation system respects conditional logic and field visibility.
How It Works
Basic Usage
import { validator } from '@joyfill/components';
// Validate a document
const validation = validator.validate(doc);
Validation Logic
- Hidden fields are always valid (respects conditional logic)
- Non-required fields are always valid
- Required fields with empty values are invalid
- Required fields with values are valid
Empty Value Detection
- Text/Number/Dropdown: Empty if
"", null, or undefined
- Arrays (image, file, multiSelect): Empty if not array, empty array, or all items are empty strings
- Table : Empty if field.value is an empty array
Configuring Required Fields
Set required: true on any field:
{
"_id": "name-field",
"type": "text",
"title": "Full Name",
"value": "",
"required": true, // Makes field required
"file": "file1"
}
Validation Results
{
status: 'valid' | 'invalid' | null,
fieldValidations: [
{
field: { /* field object */ },
status: 'valid' | 'invalid'
}
]
}
Status meanings:
'valid': All required fields filled
'invalid': One or more required fields empty
null: Invalid document structure
Implementation Example
import React, { useEffect, useState } from "react";
import { JoyDoc, validator } from "@joyfill/components";
function JoyDocPage() {
const [doc, setDoc] = useState(null);
const [validationResult, setValidationResult] = useState(null);
useEffect(() => {
const getDocument = async () => {
try {
const response = await fetch("YOUR_API_ENDPOINT", {
method: "GET",
headers: {
Authorization: "Bearer YOUR_TOKEN",
"Content-Type": "text/JSON",
},
});
const data = await response.json();
setDoc(data);
// Validate the document
if (data) {
const validation = validator.validate(data);
setValidationResult(validation);
}
} catch (e) {
console.log(e);
}
};
getDocument();
}, []);
return (
<div>
{/* Validation Status Display */}
{validationResult && (
<div
style={{
padding: "20px",
margin: "20px",
border: `2px solid ${
validationResult.status === "valid"
? "#4CAF50"
: validationResult.status === "invalid"
? "#f44336"
: "#ff9800"
}`,
borderRadius: "8px",
backgroundColor:
validationResult.status === "valid"
? "#e8f5e8"
: validationResult.status === "invalid"
? "#ffebee"
: "#fff3e0",
}}
>
<h3
style={{
margin: "0 0 10px 0",
color:
validationResult.status === "valid"
? "#2e7d32"
: validationResult.status === "invalid"
? "#c62828"
: "#ef6c00",
}}
>
Validation Status:{" "}
{validationResult.status?.toUpperCase() || "NULL"}
</h3>
{validationResult.status === "invalid" && (
<div>
<p style={{ margin: "10px 0 5px 0", fontWeight: "bold" }}>
Invalid Fields (
{
validationResult.fieldValidations.filter(
(f) => f.status === "invalid"
).length
}
):
</p>
<ul style={{ margin: "0", paddingLeft: "20px" }}>
{validationResult.fieldValidations
.filter((fv) => fv.status === "invalid")
.map((fieldValidation, index) => (
<li
key={index}
style={{ color: "#c62828", marginBottom: "5px" }}
>
<strong>
{fieldValidation.field?.title ||
fieldValidation.field?._id}
</strong>
<span
style={{
marginLeft: "10px",
fontSize: "12px",
color: "#666",
}}
>
({fieldValidation.field?.type})
</span>
</li>
))}
</ul>
</div>
)}
<details style={{ marginTop: "10px" }}>
<summary style={{ cursor: "pointer", fontWeight: "bold" }}>
Raw Validation Data
</summary>
<pre
style={{
marginTop: "10px",
padding: "10px",
backgroundColor: "#f5f5f5",
borderRadius: "4px",
overflow: "auto",
fontSize: "12px",
}}
>
{JSON.stringify(validationResult, null, 2)}
</pre>
</details>
</div>
)}
<JoyDoc
doc={doc}
mode="edit"
onChange={(params, changes, doc) => {
// Re-validate when document changes
if (doc) {
const validation = validator.validate(doc);
setValidationResult(validation);
}
}}
/>
</div>
);
}
export default JoyDocPage;
Key Points
- Hidden fields are always valid (respects conditional logic)
- Validate on document changes using the
onChange callback
- Use visual feedback to show validation status to users
- Debug with raw validation data when troubleshooting