Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
305 lines (290 loc) · 23.7 KB
/
Copy pathindex.html
File metadata and controls
305 lines (290 loc) · 23.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
<!DOCTYPE html>
<html>
<head>
<meta name=viewport content='width=560'>
<link rel="stylesheet" href='lib/bootstrap/css/bootstrap.min.css'/>
<link rel="stylesheet" href="lib/codemirror/codemirror.css">
<link rel="stylesheet" href="lib/bootstrap-select/css/bootstrap-select.min.css">
<link rel="stylesheet" href="lib/octicons/octicons.css">
<link rel="stylesheet" href='dist/css/brutusin-json-forms.min.css'/>
<style>
img {
max-width: 100%
}
.CodeMirror {
height: 400px;
}
</style>
<script src='lib/jquery-1.11.3.min.js'></script>
<script src='lib/bootstrap/js/bootstrap.min.js'></script>
<script src="lib/codemirror/codemirror.js"></script>
<script src="lib/codemirror/codemirror-javascript.js"></script>
<script src="lib/markdown.min.js"></script>
<script src="lib/bootstrap-select/js/bootstrap-select.min.js"></script>
<script src="lib/bootstrap-select/js/i18n/defaults-en_US.min.js"></script>
<!--
<script src="dist/js/brutusin-json-forms.min.js"></script>
-->
<script src="src/js/brutusin-json-forms.js"></script>
<script src="dist/js/brutusin-json-forms-bootstrap.min.js"></script>
<script lang="javascript">
var BrutusinForms = brutusin["json-forms"];
BrutusinForms.bootstrap.addFormatDecorator("inputstream", "file", "glyphicon-search", function (element) {
alert("user callback on element " + element)
});
BrutusinForms.bootstrap.addFormatDecorator("color", "color");
BrutusinForms.bootstrap.addFormatDecorator("date", "date");
var codeMirrors = new Object();
var input = new Object();
var inputString = new Object();
var title;
var desc;
var selectedDemo;
var demos = [
["Dynamic schemas",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"species": {"title": "Species supported", "description": "Changes in this property (`$.species`) trigger the resolution of the actual (depending on the values being selected) schema of a dependent property (`$.subspecies`)", "type": "string", "enum": ["human", "dog", "cat"], "required": true}, "subspecies": {"dependsOn": ["species"]}}},
null,
"function (names, data, cb) {\n var schemas = new Object();\n var schema = new Object();\n if (data.species === \"human\") {\n schema.type = \"null\"; // no such property for humans\n } else {\n schema.type = \"string\";\n if (data.species === \"dog\") {\n schema.title = \"Dog breed\";\n schema.enum = [\"bulldog\", \"labrador\"]\n } else {\n schema.title = \"Cat breed\";\n schema.enum = [\"siamese\", \"persian\"]\n }\n }\n schemas[\"$.subspecies\"] = schema;\n setTimeout(function(){cb(schemas)},500); // in order to show asynchrony\n}",
"Example of [dynamic schemas](https://github.com/brutusin/json-forms#dynamic-schemas) in action. Notice the usage of `dependsOn` (*Schema* tab), and the specific implementation of `bf.schemaResolver` (*Schema resolver* tab). See a real application of this feature at [http://demo.rpc.brutusin.org/rpc/repo/#http-services/logo](http://demo.rpc.brutusin.org/rpc/repo/#http-services/logo)"],
["Simple",
{"$schema": "http://json-schema.org/draft-03/schema#", "title": "A boolean", "description": "A simple boolean data type as schema root", "type": "boolean"},
null,
null,
"Example showing that root object in the schema is not required to be an object"],
["Objects, arrays, enums, default, required, minItems, uniqueItems",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"pageNum": {"type": "integer", "title": "Page number", "description": "Page number to be queried, `1-based`. See [Pagination](https://en.wikipedia.org/wiki/Pagination) for more details", "default": 1, "required": true}, "pageSize": {"type": "integer", "title": "Page size", "description": "Number of records per page", "required": true, "default": 50, "enum": [10, 25, 50, 100]}, "selectedFacetValues": {"type": "array", "title": "Query terms", "minItems": 2, "uniqueItems":true, "items": {"description": "Query item", "type": "object", "properties": {"facetName": {"type": "string", "title": "Field name", "description": "Indexed field name", "required": true}, "matchAllNull": {"type": "boolean", "title": "Match nulls"}, "matchAllNotNull": {"type": "boolean", "title": "Match not nulls"}, "facetValues": {"type": "array", "title": "Field values", "items": {"type": "object", "properties": {"value": {"type": "string", "title": "Value"}}}}, "included": {"type": "boolean", "title": "Included"}}}}, "sorts": {"type": "array", "title": "Sorting", "items": {"type": "object", "properties": {"fieldName": {"type": "string", "title": "Field name"}, "ascending": {"type": "boolean", "title": "Ascending"}}}}}},
null,
null,
"Example covering several common features"],
["Initial data",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"pageNum": {"type": "integer", "title": "Page number", "description": "Page number to be queried, `1-based`. See [Pagination](https://en.wikipedia.org/wiki/Pagination) for more details", "default": 1, "required": true}, "pageSize": {"type": "integer", "title": "Page size", "description": "Number of records per page", "required": true, "default": 50, "enum": [10, 25, 50, 100]}, "selectedFacetValues": {"type": "array", "title": "Query terms", "minItems": 2, "items": {"description": "Query item", "type": "object", "properties": {"facetName": {"type": "string", "title": "Field name", "description": "Indexed field name", "required": true}, "matchAllNull": {"type": "boolean", "title": "Match nulls"}, "matchAllNotNull": {"type": "boolean", "title": "Match not nulls"}, "facetValues": {"type": "array", "title": "Field values", "items": {"type": "object", "properties": {"value": {"type": "string", "title": "Value"}}}}, "included": {"type": "boolean", "title": "Included"}}}}, "sorts": {"type": "array", "title": "Sorting", "items": {"type": "object", "properties": {"fieldName": {"type": "string", "title": "Field name"}, "ascending": {"type": "boolean", "title": "Ascending"}}}}}},
{"pageNum": 1, "pageSize": 50, "selectedFacetValues": [{"facetName": "id", "matchAllNull": false, "matchAllNotNull": true, "facetValues": [{"value": "1223"}], "included": false}], "sorts": [{"fieldName": "name", "ascending": true}]},
null,
"Example of a form created with initial data preloaded. Same schema as the previous example."],
["String validation",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"s1": {"type": "string", "title": "A validated string", "minLength": 1, "maxLength": 2, "pattern": "a", "description": "A string of length `1` or `2` characters long and containing `'a'`"}}},
null,
null,
"[String validation](http://json-schema.org/latest/json-schema-validation.html#anchor25) supporting `minLength`, `maxLength`, and `pattern`"],
["Numeric validation",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"num1": {"type": "integer", "title": "A number", "minimum": 1, "maximum": 10, "multipleOf": 3, "description": "An integer multiple of `3`, between `1` and `10` (inclusive)"}, "num2": {"type": "integer", "title": "Other number", "minimum": 1, "exclusiveMinimum": true, "maximum": 10, "exclusiveMaximum": true, "description": "A integer between `2` and `9` (inclusive). This example makes use of `exclusiveMinimum` and `exclusiveMaximum` schema keywords"}}},
null,
null,
"[Numeric validation](http://json-schema.org/latest/json-schema-validation.html#anchor13) supporting `multipleOf`, `minimum`, `maximum` and `exclusiveMinimum`, `exclusiveMaximum` "],
["Additional properties",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"fixed": {"description": "Object supporting schema-fixed additional properties", "type": "object", "maxProperties": 2, "additionalProperties": {"description": "Fixed-schema additional property", "type": "object", "properties": {"name": {"type": "string"}, "age": {"type": "integer"}}}}, "free": {"description": "Object supporting schema-free additional properties", "type": "object", "maxProperties": 3, "additionalProperties": true}}},
null,
null,
"Both object and boolean typed [additionalProperties](http://json-schema.org/latest/json-schema-validation.html#anchor64) are supported. Also, notice the support of the validation keywords `minProperties` and `maxProperties`"],
["oneOf example",
{"$schema": "http://json-schema.org/draft-03/schema#", "oneOf": [{"type": "number", "required": true, "multipleOf": 3, "title": "A multiple of 3"}, {"title": "An object", "type": "object", "properties": {"p1": {"type": "string", "required": true, "title": "A required string"}, "p2": {"type": "boolean", "title": "A boolean"}}}]},
null,
null,
"`oneOf` types support in schemas"],
["Textarea example",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"prop1": {"type": "string", "title": "A short string", "description": "A short string property whose input is rendered as `input`"}, "prop2": {"type": "string", "title": "A long text", "format": "text", "description": "A long text property whose input is rendered as `textarea`"}}},
null,
null,
"`textarea` rendering for `string` schemas"],
["Custom string formats",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"file": {"type": "string", "format": "inputstream", "description": "Using a custom format decorator with **glyphicon** via `addFormatDecorator(...)` of the bootstrap extension script"}, "color": {"type": "string", "format": "color", "description": "Using a custom format decorator via `addFormatDecorator(...)` of the bootstrap extension script"}, "date": {"type": "string", "format": "date", "description": "Using a custom format decorator with glyphicon via `addFormatDecorator(...)` of the bootstrap extension script"}}},
null,
null,
"Input types can be chosen for custom `string` schema formats via `BrutusinForms.bootstrap.addFormatDecorator(...)`. See current registered decorators at this page source code."],
["Pattern Properties",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"s1": {"type": "string", "title": "A string", "description": "A string"}}, "patternProperties": {"^ref_.*": {"type": "number"}}},
null,
null,
"[Pattern Properties](http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.17) Supporting additional properties with names constrained by a regular expression pattern."],
["Definitions ($ref)",
{"$schema":"http://json-schema.org/draft-03/schema#","type":"object","definitions":{"d1":{"type":"string","title":"Definition title","description":"Definition description"}},"properties":{"s1":{"description":"Overwritten description","$ref":"#/definitions/d1"},"s2":{"title":"Overwritten title","$ref":"#/definitions/d1"}}},
null,
null,
"[Definitions](http://json-schema.org/latest/json-schema-validation.html) Supporting internal references to definitions. `title` and `description` can be overwritten by the pointing instance."],
["ReadOnly",
{"$schema": "http://json-schema.org/draft-03/schema#", "type": "object", "properties": {"s1": {"type": "string"}, "s2": {"type": "string", "readOnly": true}, "a1": {"type": "array", "items": {"type": "string"}}, "a2": {"type": "array", "items": {"type": "string"}, "readOnly": true}}},
{"s1": "foo", "s2": "bar", "a1": ["foo", "bar"], "a2": ["baz", "corge"]},
null,
"[Read Only](http://json-schema.org/latest/json-schema-validation.html) Supporting greyed-out display of read-only elements"],
["Required v3, v4+",
{"type":"object","properties":{"prop1":{"type":"integer"},"prop2":{"type":"integer","required":true},"prop3":{"type":"integer","required":true},"composite1":{"type":"object","properties":{"nested1":{"type":"number","required":true},"nested2":{"type":"number","required":true}},"required":["nested1","nested2"]},"composite2":{"type":"object","properties":{"nested1":{"type":"number","required":true},"nested2":{"type":"number","required":true}},"required":["nested1","nested2"]}},"required":["prop1","prop2","composite1"]},
null,
null,
"Required properties supported in both v3 and v4+ spec formats. Last one format takes preference. More info [here](https://github.com/brutusin/json-forms/issues/56)"]
];
var selectedTab = "schema";
var bf;
function selectExample(selectedExampleIndex) {
document.getElementById("examples").selectedIndex = selectedExampleIndex;
input.schema = demos[selectedExampleIndex][1];
input.data = demos[selectedExampleIndex][2];
eval("input.resolver=" + demos[selectedExampleIndex][3]);
inputString.schema = JSON.stringify(input.schema, null, 2);
inputString.data = input.data ? JSON.stringify(input.data, null, 2) : "";
inputString.resolver = demos[selectedExampleIndex][3] ? demos[selectedExampleIndex][3] : "";
if (codeMirrors[selectedTab]) {
codeMirrors[selectedTab].setValue(inputString[selectedTab]);
}
title = demos[selectedExampleIndex][0];
desc = markdown.toHTML(demos[selectedExampleIndex][4]);
}
function route() {
if (!window.onhashchange) {
window.onhashchange = route;
}
selectedDemo = parseInt(window.location.hash.substring(1));
if (isNaN(selectedDemo) || selectedDemo < 0 || selectedDemo >= demos.length) {
selectedDemo = 0;
}
selectExample(selectedDemo);
}
function generateForm() {
var schema;
var data;
var message;
var resolver;
var tabId;
inputString[selectedTab] = codeMirrors[selectedTab].getValue();
$("#jsonAlert").hide();
try {
message = "The was a syntax error in the schema JSON";
tabId = "schema";
eval("schema=" + inputString.schema);
if (inputString.data) {
message = "The was a syntax error in the initial data JSON";
tabId = "data";
eval("data=" + inputString.data);
} else {
data = null;
}
if (inputString.resolver) {
tabId = "resolver";
message = "The was a syntax error in the resolver code";
eval("resolver=" + inputString.resolver);
if ("function" !== typeof resolver) {
throw "Schema resolver does not evaluate to a function";
}
}
} catch (err) {
document.getElementById('error-message').innerHTML = message + (err ? ". " + err : "");
$('[href=#' + tabId + ']').tab('show');
$("#jsonAlert").show();
return;
}
$('#formLink').click();
bf = BrutusinForms.create(schema);
if (resolver) {
bf.schemaResolver = resolver;
}
var container = document.getElementById('container');
while (container.firstChild) {
container.removeChild(container.firstChild);
}
if (title) {
document.getElementById('example-title').innerHTML = title;
}
if (desc) {
document.getElementById('example-desc').innerHTML = desc;
}
bf.render(container, data);
}
</script>
</head>
<body>
<a href="https://github.com/brutusin/json-forms/tree/gh-pages"><img style="position: absolute; top: 0; right: 0; border: 0; width: 149px; height: 149px;" src="img/forkme.png" alt="Fork me on GitHub"></a>
<div class="container" >
<h1><img alt="Butusin" src="https://avatars0.githubusercontent.com/u/10341159?v=3&s=200" style="border: 0; width: 50px; height: 50px;"/><code>brutusin:json-forms</code> demo</h1>
<blockquote>
<p><b>JSON Schema to HTML form generator</b>, supporting dynamic subschemas (on the fly resolution). Extensible and customizable library with zero dependencies. Bootstrap add-ons provided.</p>
<p>Source code and documentation available at <a href="https://github.com/brutusin/json-forms"><span class="octicon octicon-logo-github"></span></a></p>
<p>Originally created for <a href="http://rpc.brutusin.org">Brutusin-RPC</a>. See who else is using it <a href="https://github.com/brutusin/json-forms/blob/master/WHO-IS-USING.md">here</a>.</p>
</blockquote>
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-primary">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseInput" aria-expanded="true" aria-controls="collapseInput">
Input
</a>
</h4>
</div>
<div id="collapseInput" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<label for="examples">Predefined examples:</label>
<select class="form-control" id="examples" onchange="document.location.hash = this.selectedIndex;">
<script>
for (var i = 0; i < demos.length; i++) {
document.write("<option " + (selectedDemo === i ? "selected=true" : "") + ">" + demos[i][0] + "</option>");
}
</script>
</select>
<br>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#schema" aria-controls="schema" role="tab" data-toggle="tab">Schema</a></li>
<li role="presentation"><a href="#data" aria-controls="data" role="tab" data-toggle="tab">Initial data</a></li>
<li role="presentation"><a href="#resolver" aria-controls="resolver" role="tab" data-toggle="tab">Schema resolver</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="schema"></div>
<div role="tabpanel" class="tab-pane" id="data"></div>
<div role="tabpanel" class="tab-pane" id="resolver"></div>
</div>
<div class="alert alert-danger in" role="alert" id="jsonAlert" style="display:none">
<a href="#" onclick='$("#jsonAlert").hide();' class="close" >×</a>
<strong>Error!</strong> <span id="error-message"></span>
</div>
</div>
<div class="panel-footer">
<button class="btn btn-primary" onclick="generateForm()">Create form</button>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading" role="tab" id="headingTwo">
<h4 class="panel-title">
<a class="collapsed" id="formLink" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseForm" aria-expanded="false" aria-controls="collapseForm">
Generated form
</a>
</h4>
</div>
<div id="collapseForm" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
<div class="alert alert-info" role="alert"><strong id="example-title"></strong><div id="example-desc"></div></div>
<div id='container' style="padding-left:12px;padding-right:12px;padding-bottom: 12px;"></div>
<div class="panel-footer">
<button class="btn btn-primary" onclick="alert(JSON.stringify(bf.getData(), null, 4))">getData()</button> <button class="btn btn-primary" onclick="if (bf.validate()) {
alert('Validation succeeded')
}">validate()</button>
</div>
</div>
</div>
</div>
</div>
<script lang="javascript">
route();
codeMirrors["schema"] = CodeMirror(document.getElementById("schema"), {
value: JSON.stringify(demos[selectedDemo][1], null, 4),
mode: "javascript",
lineNumbers: true
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
selectedTab = $(e.target).attr("aria-controls");
var pt = $(e.relatedTarget);
var prevTab;
if (pt) {
prevTab = pt.attr("aria-controls");
inputString[prevTab] = codeMirrors[prevTab].getValue();
}
if (!codeMirrors[selectedTab]) {
codeMirrors[selectedTab] = CodeMirror(document.getElementById(selectedTab), {
mode: "javascript",
lineNumbers: true
});
}
codeMirrors[selectedTab].setValue(inputString[selectedTab]);
}
);
</script>
</div>
</body>
</html>