JSFiddle - React, Tailwind, and code Playground
by Dan Bonelli
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.js"></script>
<ul data-bind="foreach: products">
<li class="product">
<strong data-bind="text: name"></strong>
<div data-bind="component: { name: 'like-widget' }"></div>
</li>
</ul>
<script id="like-template" type="text/x-knockout-template">
<div>
<div class="like-or-dislike" data-bind="visible: ratingButtonVisible">
<button data-bind="click: like">Like it</button>
<button data-bind="click: dislike">Dislike it</button>
</div>
<div class="result" data-bind="visible: ratingDescriptionVisible">
You <strong data-bind="text: userRating"></strong> it
</div>
</div>
</script>
JavaScript
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = [
new Product('Garlic bread'),
new Product('Pain au chocolat'),
new Product('Seagull spaghetti', 'like') // This one was already 'liked'
];
}
ko.components.register('like-widget', {
viewModel: {
createViewModel: function (params, componentInfo) {
var context = ko.contextFor(componentInfo.element);
var self = context.$data;
return ko.utils.extend(context.$data, {
ratingButtonVisible: ko.computed(function() {
return (self.userRating()==null);
}),
ratingDescriptionVisible: ko.computed(function() {
return !(self.userRating()==null);
}),
like: function() {
self.userRating('like');
},
dislike: function() {
self.userRating('dislike');
}
});
}
},
template: { element: 'like-template' }
});
ko.applyBindings(new MyViewModel());