Error flags
by whelkaholism
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<button data-bind="click: set1">Name failed</button>
<button data-bind="click: set2">Email failed</button>
<button data-bind="click: clear">Clear</button>
<hr/>
<!-- ko with: Module -->
<!-- ko with: Model -->
With options in child context: <div class="efs" data-bind="ef: { flags: ['ef__namerequired'], field: $parents[1].ErrorFlags }"></div>
<!-- /ko -->
<!-- /ko -->
<hr/>
Default:
<div class="efs" data-bind="___XXX___ef: ['ef__emailrequired', 'ef__emailinvalid']"></div>
<hr/>
<div data-bind="text: CurrentErrorFlags"></div>
JavaScript
ko.bindingHandlers.ef = {
init:
function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
{
// Get current value of supplied value
var val = ko.unwrap(f_valueaccessor());
var field = bindingcontext.$data.ErrorFlags;
if(!!val.flags)
{
field = val.field || field;
val = val.flags;
}
if(field && val)
{
field.subscribe(
function()
{
var visibleflags = [];
for(var i = 0; i < val.length; i++)
{
var err = ko.utils.arrayFirst(ko.unwrap(field), function(x) { return x.Flag == val[i]; });
if(err)
visibleflags.push(err);
}
$('<div class="ef" data-bind="text: Message"></div>').appendTo(el);
ko.applyBindingsToNode(el, { foreach: visibleflags });
});
}
return { controlsDescendantBindings: true };
}
};
function Model(data, mapping)
{
var _this = this;
var _mapping = $.extend({}, {}, mapping);
this.ErrorFlags = ko.observableArray();
this.Module = ko.observable({ Model: ko.observable({}) });
this.CurrentErrorFlags = ko.computed(
function()
{
var a = [];
$.each(_this.ErrorFlags(), function() { a.push(this.Flag); });
return a.length > 0 ? a.join(', ') : '(empty)';
}
);
if(data)
ko.mapping.fromJS(data, _mapping, _this);
this.set1 = function()
{
this.ErrorFlags([
{ Flag: 'ef__namerequired', Message: 'Name is required' }
]);
};
this.set2 = function()
{
this.ErrorFlags([
{ Flag: 'ef__emailrequired', Message: 'Email is required'},
{ Flag: 'ef__emailinvalid', Message: 'This email is invalid' }
]);
...