/
validation.js
75 lines (67 loc) · 1.8 KB
/
validation.js
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
var React = require("react");
var {Glyphicon} = require("react-bootstrap");
var {Type, Node} = require("./base");
var {CUnit} = require("./primitives");
var {CSideEffect} = require("./util");
var glyphmap = {
error: "ban-circle",
warning: "warning-sign",
info: "info-sign",
}
function CValidate(testFn, type = CUnit()) {
return new Type("validate", function makeValidate(ctx) {
return new ValidationNode(testFn, type.makeNode(ctx), ctx);
});
}
function renderValidation(messages) {
return <div className="validate">{
[for ({level, msg, fragment} of messages)
<div className={`validate-${level}`}><a id={fragment}/><Glyphicon glyph={glyphmap[level]}/>{" "}{msg}</div>
]
}</div>;
}
function renderWithValidation(inner, messages) {
return <div>
{inner}
{renderValidation(messages)}
</div>;
}
class ValidationNode extends Node {
constructor(testFn, innerNode, ctx) {
super();
this._innerNode = innerNode;
var messages = [];
var emitter = level => msg => messages.push(ctx.problems.add({level, msg}));
var callbacks = {
error: emitter("error"),
warning: emitter("warning"),
info: emitter("info")
};
testFn(this, callbacks, ctx);
this._messages = messages;
}
get inner() {
return this._innerNode;
}
get value() {
return this.inner.value;
}
render() {
return renderWithValidation(this._innerNode.render(), this._messages);
}
}
function CValidationMessages(messages) {
return new Type("validationMessages", function makeValidationMessages(ctx) {
return new ValidationMessagesNode(messages.map(m => ctx.problems.add(m)));
});
}
class ValidationMessagesNode extends Node {
constructor(messages) {
super();
this._messages = messages;
}
render() {
return renderValidation(this._messages);
}
}
module.exports = {CValidate, CValidationMessages, renderWithValidation};