> ## 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.

# Required Field Validation

## 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

```jsx theme={null}
import { validator } from '@joyfill/components';

// Validate a document
const validation = validator.validate(doc);

```

### Validation Logic

1. **Hidden fields** are always valid (respects conditional logic)
2. **Non-required fields** are always valid
3. **Required fields** with empty values are invalid
4. **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:

```jsx theme={null}
{
  "_id": "name-field",
  "type": "text",
  "title": "Full Name",
  "value": "",
  "required": true,  // Makes field required
  "file": "file1"
}

```

## Validation Results

```jsx theme={null}
{
  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

```jsx theme={null}
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
