skmasq
skmasq

Reputation: 4521

Show specific amount of elements from observableArray and hide rest

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.

Here are my current markups

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

Answers (2)

Chris Moutray
Chris Moutray

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

skmasq
skmasq

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

Related Questions