0
# Schema Validation
1
2
JSON schema validation system with comprehensive error reporting, custom validation support, and real-time validation feedback powered by the Ajv library.
3
4
## Capabilities
5
6
### Set JSON Schema
7
8
Configure JSON schema for automatic validation of editor content.
9
10
```javascript { .api }
11
/**
12
* Set a JSON schema for validation of the JSON object
13
* @param schema - JSON schema object, or null to remove validation
14
* @param schemaRefs - Optional referenced schemas for $ref properties
15
*/
16
setSchema(schema: object | null, schemaRefs?: { [key: string]: object }): void;
17
```
18
19
**Usage Example:**
20
21
```javascript
22
// Define a schema
23
const userSchema = {
24
type: "object",
25
properties: {
26
name: {
27
type: "string",
28
minLength: 1
29
},
30
email: {
31
type: "string",
32
format: "email"
33
},
34
age: {
35
type: "number",
36
minimum: 0,
37
maximum: 150
38
},
39
active: {
40
type: "boolean"
41
}
42
},
43
required: ["name", "email"],
44
additionalProperties: false
45
};
46
47
// Set the schema
48
editor.setSchema(userSchema);
49
50
// Remove schema validation
51
editor.setSchema(null);
52
```
53
54
### Schema with References
55
56
Use referenced schemas for complex validation scenarios.
57
58
```javascript { .api }
59
// Example with schema references
60
const mainSchema = {
61
type: "object",
62
properties: {
63
user: { $ref: "#/definitions/User" },
64
company: { $ref: "company.json" }
65
}
66
};
67
68
const schemaRefs = {
69
"#/definitions/User": {
70
type: "object",
71
properties: {
72
name: { type: "string" },
73
email: { type: "string", format: "email" }
74
}
75
},
76
"company.json": {
77
type: "object",
78
properties: {
79
name: { type: "string" },
80
industry: { type: "string" }
81
}
82
}
83
};
84
85
editor.setSchema(mainSchema, schemaRefs);
86
```
87
88
### Validate Content
89
90
Manually trigger validation and retrieve validation errors.
91
92
```javascript { .api }
93
/**
94
* Validate current JSON object against the configured JSON schema
95
* @returns Promise resolving to array of validation errors
96
*/
97
validate(): Promise<ValidationError[]>;
98
```
99
100
**Usage Example:**
101
102
```javascript
103
// Trigger validation manually
104
const errors = await editor.validate();
105
106
if (errors.length > 0) {
107
console.log("Validation errors found:");
108
errors.forEach(error => {
109
console.log(`- ${error.message} at path: ${error.path.join('.')}`);
110
});
111
} else {
112
console.log("Validation passed!");
113
}
114
```
115
116
### Validation Error Structure
117
118
Structure of validation error objects returned by the validation system.
119
120
```javascript { .api }
121
interface ValidationError {
122
/** Type of validation error */
123
type: "validation" | "customValidation" | "error";
124
125
/** Path to the invalid data as an array */
126
path: (string | number)[];
127
128
/** Human-readable error message */
129
message: string;
130
131
/** Original error object (for type: "error") */
132
error?: Error;
133
134
/** Schema keyword that failed (for type: "validation") */
135
keyword?: string;
136
137
/** Schema path where validation failed */
138
schemaPath?: string;
139
140
/** Additional error data from Ajv */
141
data?: any;
142
}
143
```
144
145
### Custom Validation Function
146
147
Implement custom validation logic beyond JSON schema capabilities.
148
149
```javascript { .api }
150
/**
151
* Custom validation function in editor options
152
*/
153
interface ValidationOptions {
154
onValidate?: (json: any) => ValidationError[] | Promise<ValidationError[]> | null;
155
}
156
```
157
158
**Usage Example:**
159
160
```javascript
161
const options = {
162
mode: "tree",
163
onValidate: (json) => {
164
const errors = [];
165
166
// Custom business logic validation
167
if (json.users && Array.isArray(json.users)) {
168
json.users.forEach((user, index) => {
169
if (user.email && user.email.endsWith('@tempmail.com')) {
170
errors.push({
171
type: "customValidation",
172
path: ['users', index, 'email'],
173
message: "Temporary email addresses are not allowed"
174
});
175
}
176
});
177
}
178
179
// Async validation example
180
if (json.username) {
181
return fetch(`/api/validate-username/${json.username}`)
182
.then(response => response.json())
183
.then(result => {
184
if (!result.available) {
185
return [{
186
type: "customValidation",
187
path: ['username'],
188
message: "Username is already taken"
189
}];
190
}
191
return [];
192
});
193
}
194
195
return errors;
196
}
197
};
198
199
const editor = new JSONEditor(container, options);
200
```
201
202
### Validation Error Callback
203
204
Handle validation errors with a dedicated callback function.
205
206
```javascript { .api }
207
/**
208
* Validation error callback in editor options
209
*/
210
interface ValidationOptions {
211
onValidationError?: (errors: ValidationError[]) => void;
212
}
213
```
214
215
**Usage Example:**
216
217
```javascript
218
const options = {
219
mode: "tree",
220
schema: userSchema,
221
onValidationError: (errors) => {
222
const errorContainer = document.getElementById('validation-errors');
223
224
if (errors.length > 0) {
225
const errorList = errors.map(error => {
226
const pathStr = error.path.length > 0 ? ` at ${error.path.join('.')}` : '';
227
return `<li>${error.message}${pathStr}</li>`;
228
}).join('');
229
230
errorContainer.innerHTML = `<ul class="errors">${errorList}</ul>`;
231
errorContainer.style.display = 'block';
232
} else {
233
errorContainer.style.display = 'none';
234
}
235
}
236
};
237
```
238
239
### Custom Ajv Instance
240
241
Provide a custom Ajv instance with specific configuration.
242
243
```javascript { .api }
244
/**
245
* Custom Ajv configuration in editor options
246
*/
247
interface ValidationOptions {
248
ajv?: any; // Ajv instance
249
}
250
```
251
252
**Usage Example:**
253
254
```javascript
255
import Ajv from 'ajv';
256
import addFormats from 'ajv-formats';
257
258
// Create custom Ajv instance
259
const ajv = new Ajv({
260
allErrors: true,
261
verbose: true,
262
$data: true,
263
strictSchema: false
264
});
265
266
// Add format validation
267
addFormats(ajv);
268
269
// Add custom keyword
270
ajv.addKeyword({
271
keyword: 'isEven',
272
type: 'number',
273
schemaType: 'boolean',
274
validate: (schemaValue, data) => {
275
return schemaValue ? data % 2 === 0 : data % 2 !== 0;
276
}
277
});
278
279
const options = {
280
mode: "tree",
281
ajv: ajv,
282
schema: {
283
type: "object",
284
properties: {
285
evenNumber: {
286
type: "number",
287
isEven: true
288
}
289
}
290
}
291
};
292
293
const editor = new JSONEditor(container, options);
294
```
295
296
### Schema-based Autocomplete
297
298
Enable autocomplete suggestions based on JSON schema properties and enums.
299
300
```javascript { .api }
301
/**
302
* Schema autocomplete configuration in editor options
303
*/
304
interface ValidationOptions {
305
allowSchemaSuggestions?: boolean;
306
}
307
```
308
309
**Usage Example:**
310
311
```javascript
312
const schemaWithEnums = {
313
type: "object",
314
properties: {
315
status: {
316
type: "string",
317
enum: ["draft", "published", "archived"],
318
examples: ["draft"]
319
},
320
category: {
321
type: "string",
322
enum: ["tech", "business", "lifestyle"]
323
}
324
}
325
};
326
327
const options = {
328
mode: "code", // Only works in code mode
329
schema: schemaWithEnums,
330
allowSchemaSuggestions: true
331
};
332
333
const editor = new JSONEditor(container, options);
334
```
335
336
## Real-time Validation
337
338
JSONEditor automatically validates content in real-time as users edit:
339
340
- **Tree/View/Form modes**: Invalid nodes are highlighted with error styling
341
- **Code/Text modes**: Error annotations appear in the editor gutter
342
- **All modes**: Error table can be displayed showing all validation issues
343
- **Debounced**: Validation is debounced (150ms default) to avoid excessive validation calls
344
345
## Validation Error Display
346
347
Control how validation errors are displayed to users:
348
349
```javascript
350
const options = {
351
mode: "tree",
352
schema: userSchema,
353
354
// Show error table for specific modes
355
showErrorTable: true, // boolean
356
// or
357
showErrorTable: ["text", "code"], // array of modes
358
359
// Custom error handling
360
onValidationError: (errors) => {
361
// Custom error display logic
362
displayCustomErrorUI(errors);
363
}
364
};
365
```
366
367
## Validation Best Practices
368
369
### Schema Design
370
```javascript
371
// Good: Comprehensive schema with clear constraints
372
const goodSchema = {
373
type: "object",
374
properties: {
375
id: { type: "string", pattern: "^[a-zA-Z0-9_-]+$" },
376
name: { type: "string", minLength: 1, maxLength: 100 },
377
email: { type: "string", format: "email" },
378
age: { type: "integer", minimum: 0, maximum: 150 },
379
tags: {
380
type: "array",
381
items: { type: "string" },
382
maxItems: 10
383
}
384
},
385
required: ["id", "name"],
386
additionalProperties: false
387
};
388
```
389
390
### Error Handling
391
```javascript
392
// Handle validation errors gracefully
393
const options = {
394
onValidationError: (errors) => {
395
// Group errors by type
396
const schemaErrors = errors.filter(e => e.type === 'validation');
397
const customErrors = errors.filter(e => e.type === 'customValidation');
398
const parseErrors = errors.filter(e => e.type === 'error');
399
400
// Display appropriate user feedback
401
if (parseErrors.length > 0) {
402
showMessage("Invalid JSON format", "error");
403
} else if (schemaErrors.length > 0 || customErrors.length > 0) {
404
showMessage(`${errors.length} validation error(s) found`, "warning");
405
}
406
}
407
};
408
```
409
410
### Performance Optimization
411
```javascript
412
// For large schemas or frequent validation
413
const ajv = new Ajv({
414
allErrors: false, // Stop on first error for better performance
415
verbose: false, // Reduce error object size
416
validateSchema: false // Skip schema validation if schema is trusted
417
});
418
```