Bearing in mind that similar questions have been answered here, I was wondering how one might go about having default text or HTML display inside a Knockout data-bind='foreach: list'
whenever the list is empty.
The solutions on the linked page don't quite seem to line up with this, and in any case I thought of another way to try to accomplish this with a custom binding like this:
text.default = {
update: function (element, valueAccessor) {
var $e = $(element),
obs = valueAccessor();
function _check_blank() {
// the element has content - so we do nothing
if ($e.text().trim()) {
return;
}
// the element is empty;
$e.text("Default Text")
}
// we use setTimeout to ensure that any other bindings complete
// their update
setTimeout(_check_blank, 0);
}
}
This seems to work reasonably well with simple observables but it does not work with the foreach
binding, though in any case I think the extender
suggestion in the above link is probably preferable for a few reasons -- the above code would have a number of caveats. Nevertheless, I threw this example in here because it somewhat highlights an alternative and food for thought.
All that being said, I would like to know what options there might be for providing a default in lieu of foreach
content.
One is to provide a wrapper in a simple if
, like this:
<!-- ko if: xyz().length -->
// foreach
<!-- /ko -->
<!-- ifnot: xyz().length -->
// default text
<!-- /ko -->
However this is not particularly elegant -- lots of code clutter.
Knockout gives you if
and ifnot
bindings. You just have to step back a bit from the element with foreach
; Its insides are just for each element, so when there are none, there aren't any insides.
<div data-bind="if: pets().length > 0">These are the pets:</div>
<div data-bind="if: pets().length == 0">There aren't any pets. To add a pet...</div>
<div data-bind="foreach: pets">
Editorial: Your question is important because empty lists are an opportunity to say something instead of showing a blank slate.