Reputation: 4521
I want to show for example 10 items from my observableArray
and hide rest of them, and when I add a new element to beginning of array hide the 10Th element, and user to be able to click show more items.
Javascript:
var itemViewModel = {
item: {},
isLoaded: ko.observable(false),
comments: ko.observableArray([]),
loadcontent: function (getID) {
$.ajax({
url: '/api/item/details/' + getID,
dataType: 'json',
success: function (data) {
itemViewModel.item = data;
itemViewModel.comments([]);
$.each(data.Comments, function (index, thisComment) {
itemViewModel.comments.push(thisComment);
});
itemViewModel.comments.sort(function (a, b) {
return new Date(a.DateTime) == new Date(b.DateTime)
? 0 : (new Date(a.DateTime) < new Date(b.DateTime) ?
1 : -1)
});
itemViewModel.isLoaded(true);
itemDetailBindings();
}
});
},
showComment: function (ele) {
if (ele.nodeType === 1) $(ele).hide().fadeIn()
}
};
//Item detail element bindings
var itemDetailBindings = function () {
// Add auto expand to textarea
$('#this-text-is-comment').TextAreaExpander(50, 200);
//Add comment
$('#this-text-is-comment').bind('keypress', function (e) {
if (e.keyCode == 13) {
e.preventDefault();
if ($(this).val() != "") {
addComment($("#this-text-is-comment").val(), $("#hidden-item-id").val());
$(this).val('');
};
}
});
};
var addComment = function (cText, getID) {
$.ajax({
url: '/api/comment/create',
type: 'POST',
dataType: 'json',
data: { comment1: cText, itemid: getID },
success: function (data) {
itemViewModel.comments.splice(0, 0, data);
}
/*error: function (xhr, status) {
switch (status) {
case 404:
alert('File not found');
break;
case 500:
alert('Server error');
break;
case 0:
alert('Request aborted');
break;
default:
alert('Unknown error ' + status);
}
}*/
});
};
HTML:
<div class="comment-list clearfix" data-bind="template: {foreach: comments, afterAdd: showComment }">
<div class="comment-container clearfix">
<div class="left-side">
<img src="../../content/u/2012.08.17.634808075593134766.jpg" />
</div>
<div class="right-side clearfix">
<div class="top">
<span class="user-name" data-bind="text: User.FullName"></span><span class="time-posted"
data-bind="text: $.datepicker.formatDate('yy-mm-dd', new Date(DateTime))"></span>
</div>
<div class="middle clearfix">
<div class="body">
<p data-bind="text: Comment1">
</p>
</div>
</div>
</div>
</div>
</div>
For staters: I have no clue how can I do that in ko.js
Upvotes: 4
Views: 1706
Reputation: 18399
I happened upon computed filtered arrays (see tip2) but after thinking this through you can do this simply by combining Computed Observables and Javascript slice()
method.
In this following example you would bind to the filteredComments
. self.comments()
is the main list of comments, the array is sorted and then sliced to show the first # number of comments (self.commentsShown()
).
self.filteredComments = ko.computed(function() {
return self.comments()
.sort(compareComments) // important to sort before slicing
.slice(0, self.commentsShown());
});
See fiddle for a full working example. It allows for sorted/filtered list of comments, add to to start of comments array (not filtered array) and show more.
Upvotes: 4
Reputation: 4521
The problem was I couldn't find how to access the observableArray
here is my solution.
visible: $parent.comments.indexOf($data) < 2
Upvotes: 0