Closed Ognian closed 11 years ago
My first thought would be to add a new type of render component.
There are already separate components in the rendering system for adding/removing, type switching, schema switching and actually rendering the data - one renderer of each type is used for every data instance being rendered. To add a new component, you can make a call like:
Jsonary.render.Components.add('VALIDATION');
Then, you register a renderer with that component like this:
Jsonary.render.register({
component: Jsonary.render.Components.VALIDATION,
renderHtml: function (data, context) {
return "(validation info)" + context.renderHtml(data);
}
});
That renderer will now be used for every node in the data tree - so you'll see "(validation info)" inserted in front of every object, string, undefined, etc.
At that point, all that remains is to get the appropriate error messages. One way to do that would be to attach something to the Document object, like this:
renderHtml: function (data, context) {
if (!data.document.validationResult) {
data.document.validationResult = tv4.validateResult(data.document.raw.value(), <<schema>>);
}
...
},
update: function (element, data, context, operation) {
// Force an update of the validation result
data.document.validationResult = null;
}
All that remains at that point is to assemble a suitable value for <<schema>>
, and then determine which errors to display at which data nodes - tv4
includes the relevant data path in any validation results, so you should be able to compare that with data.pointerPath()
.
Hope that helps!
Thanks a lot. This opened my eyes... Actually I'm doing the following now:
this is the extension:
Jsonary.render.Components.add('VALIDATION');
Jsonary.render.register({
component: Jsonary.render.Components.VALIDATION,
renderHtml: function (data, context) {
var result = "";
var rootData = data.document.root;
if (!!rootData.validation) {
if (data.pointerPath() != "") {
for (i in rootData.validation.errors) {
if (rootData.validation.errors[i].dataPath == data.pointerPath()) {
//result += "<span class='validationError'>(validation message: " + rootData.validation.errors[i].message+" code: "+rootData.validation.errors[i].code+" schemaKey: "+rootData.validation.errors[i].schemaKey+")</span>";
result += "<span class='validationError'>"+rootData.validation.errors[i].message+"</span>";
//remove i entry in errors
rootData.validation.errors.splice(i,1);
}
;
}
;
}
//else {
// result += "<span class='validationError'>(validation info: " + JSON.stringify(rootData.validation.errors, undefined, 2) + ")</span>";
// it is not a good idea to display something here since we do not know which errors can be displayed by subsequent nodes
// therefore the remaining errors are displayed after renderTo
//}
;
}
;
return context.renderHtml(data) + result;
}
});
so thank you very much and maybe someone else can use this too... Ognian
So when you render a particular error, you then pop it off from the list?
That works if you only render the item once. If it's a read-only item and it's guaranteed to be rendered exactly once in only one place, that's probably reasonable.
(I feel it should be possible to somehow make it work with editable items all over the place, though... OK, this is an interesting problem!)
the tv4 validator is great too. Wouldn't it be nice to enable the errors reported by tv4 to be "displayed" in a rendered JSON. What do you think? What would be the easiest way to do it?