Flexicoder
Flexicoder

Reputation: 8511

Knockout foreach conditional tag based on change of value

I have the following HTML/Knockout and I would like the dayDivider div to only appear when there is a new date, i.e. messages on the same day appear under a date banner. Normally I would save the last value in a temporary variable and check that each time around. But I'm pretty new to Knockout and not sure where to start

<div data-bind="foreach: SelectedConversation().messages()" class="messages">
    <div class="row">
        <div class="dayDivider"><hr/><span class="center-block" data-bind="text: moment(timestamp()).format('D MMM')"></span></div>
        <!-- ko if: personId() === @Model.PersonId-->
        <div class="talk-bubble tri-right right-top pull-right border">
            <div class="talktext">
                <span class="pull-left messageTime" data-bind="text: moment(timestamp()).format('D MMM - HH:mm')"></span>
                <span class="pull-right messageFrom" data-bind="text: personFullName()"></span><br/>
                <span class="pull-right messageBody" data-bind="text: message"></span>
            </div>
        </div>
        <!-- /ko -->
        <!-- ko if: personId() !== @Model.PersonId-->
        <div class="talk-bubble tri-right left-top border">
            <div class="talktext">
                <span class="pull-right messageTime" data-bind="text: moment(timestamp()).format('D MMM - HH:mm')"></span>
                <span class="pull-left messageFrom" data-bind="text: personFullName()"></span><br/>
                <span class="pull-left messageBody" data-bind="text: message"></span>
            </div>
        </div>
        <!-- /ko -->

   </div>

Upvotes: 0

Views: 113

Answers (2)

Waggles
Waggles

Reputation: 403

$parent is not messages() or SelectedConversation(). Instead, it is the view model that is holding SelectedConversation(). Therefore, if you wanted to follow Shawson's suggestion, try something like:

visible: moment($parent.selectedConversation().messages()[$index() - 1]().timestamp()).diff(moment(timestamp()), 'days') > 0

Here is a fiddle showing an example of how to use $parent and $index inside of a foreach (notice how the parent is not the list used in foreach): https://jsfiddle.net/05r9pa6u/

All that said, this is too much logic in your html for my taste. You may want to consider making the message objects smarter, so they know when they should show the date div (and incidentally, who owns them, and if they should display on the right or left, etc).

Upvotes: 1

Shawson
Shawson

Reputation: 1998

how about something like;

<div class="dayDivider" data-bind="visible: $index > 0 && $parent[$index -1]().timestamp() !== timestamp()">

(Brackets may need adding/removing to this- i can never rememeber with Knockout!!)

Upvotes: 1

Related Questions