0

Have an existing array, and i want it display by 4 in a group wrapped by div:

<div class="swiper-wrapper" data-bind="foreach: roomCards">
     <!-- ko if: ($index == 0 || ($index + 1) % 4) -->
     <div class="swiper-slide">
     <!-- /ko -->
     <div>
        data
     <div>
     <!-- ko if: ($index == 0 || ($index + 1) % 4) -->
     </div>
     <!-- /ko -->
</div>

Ko if doesn't work because it only opens tag (breaking DOM) But that doesn't work.

Need something like this:

<div class="swiper-wrapper">
    <div class="swiper-slide">
        <div>
           data
        </div>
        <div>
           data
        </div>
        <div>
           data
        </div>
        <div>
           data
        </div>
    </div>
    <div class="swiper-slide">
        <div>
           data
        </div>
        <div>
           data
        </div>
        <div>
           data
        </div>
        <div>
           data
        </div>
    </div>
...
</div>

Any solutions?

user2455079
  • 420
  • 4
  • 16

2 Answers2

1

Give the ViewModel a corresponding level of grouping:

self.roomCards = ko.observableArray([1,2,3,4,5,6,7,8]);

self.roomCardsGrouped = ko.computed(function(){
    return self.roomCards().chunk(4);
});

The mentioned chunk method is taken from this answer (credit to @ninjagecko), an excerpt:

Array.prototype.chunk = function(chunkSize) {
    var array=this;
    return [].concat.apply([],
        array.map(function(elem,i) {
            return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
        })
    );
}

At any rate, update your view to something like this:

<div class="swiper-wrapper" data-bind="foreach: roomCardsGrouped">
     <div class="swiper-slide">
         <!-- ko foreach: $data -->
         <div>
             <span data-bind="text: $data"></span>
         </div>
         <!-- /ko -->
     </div>
</div>

See this fiddle for a demo.

Community
  • 1
  • 1
Jeroen
  • 60,696
  • 40
  • 206
  • 339
  • I like this method overall, but I'm not a huge fan of modifying the Array prototype. Stick that `chunk` method on your view model or on a new global namespace instead. I do believe using the computed observable is the right approach. – crush Jan 31 '14 at 14:00
1

You need to unwrap $index like so $index(), also the data div has 2 opening tags rather than one closing tag:

<div class="swiper-wrapper" data-bind="foreach: roomCards">
     <!-- ko if: ($index() == 0 || ($index() + 1) % 4) -->
     <div class="swiper-slide">
     <!-- /ko -->
     <div>
        data
     </div> 
     <!-- ko if: ($index() == 0 || ($index() + 1) % 4) -->
     </div>
     <!-- /ko -->
</div>
Tanner
  • 22,205
  • 9
  • 65
  • 83