user1742646
user1742646

Reputation: 303

Hiding specific elements after creating them with ng-repeat

I'm trying to create a piano on my page using two image files: white-key and black-key.

I've created them, but the black keys on the piano alternate in groups of 2 and 3 and I'd hide the black key images for indices [1, 4(1+3), 8(4+4), 11(8+3), 15(11+4), .., 54]. I'm unsure of how to go about doing this though.

This is how I created them.

HTML:

<div ng-controller="DrawCtrl as draw">
            <ul class="white-keys">
                <li ng-repeat="t in draw.range(56) track by $index">
                    <img ng-src={{draw.white_key}} />
                </li>
            </ul>
            <ul class="black-keys">
                <li ng-repeat="t in draw.range(55) track by $index">
                    <img ng-src={{draw.black_key}} />
                </li>
            </ul>
        </div>

JS:

angular.module('app')
.controller('DrawCtrl', function() {
    var self = this;
    self.piano_back = 'img/background.png';
    self.white_key = 'img/midi_white_up.png';
    self.black_key = 'img/midi_black_up.png';
    self.range = function(num) {
        return new Array(num);
    };
});

EDIT: Got it working thanks to hansmaad's answer.

HTML:

                <ul class="black-keys">
                <li ng-repeat="key in draw.keys" ng-switch="key.black">
                    <img ng-switch-when="true" ng-src={{draw.black_key}}  />
                    <img ng-switch-when="false" ng-src={{draw.black_key}} class="black-hidden" />
                </li>
            </ul>

JS:

    self.keys = [];
    var keyGroupOf3 = true;

    self.keys.push({black: true}); // first key is shown
    var i = 1;
    while (i < 54) {
        self.keys.push({black: false});
        // alwasy followed by at least two
        self.keys.push({black: true});
        self.keys.push({black: true});
        if (keyGroupOf3){
            self.keys.push({black: true});
            i += 4;
        } else {
            i += 3;
        }

Upvotes: 1

Views: 172

Answers (2)

hansmaad
hansmaad

Reputation: 18905

I think you should create your keyboard in the controller as array of keys. You can then use a single ng-repeat to draw all the keys. To draw the right img for a key you can use ng-switch or store the imgage url in the key.

A simple example without images but using ng-class:

http://plnkr.co/edit/kIvRqdkbHHNcUXKzSLZC?p=preview

<div ng-controller="DrawCtrl as draw">
    <ul >
        <li ng-repeat="key in draw.keys" ng-class="{ 'black' : key.black, 'white' : !key.black}">
        </li>
    </ul>
</div>

Controller:

function DrawCtrl() {
  this.keys = []
  for(var i = 0, e = 55; i < e; ++i) {
    this.keys.push({
      black : isBlackKey(i)
    });

  }

  function isBlackKey(i) {
    // your piano logic here
    return i % 2 == 0;
  }
}

Using ng-switch you could do:

    <ul>
        <li ng-repeat="key in draw.keys" ng-switch="key.black">
          <span ng-switch-when="true">Black key</span>
          <span ng-switch-when="false">White key</span>
        </li>
    </ul>

Edit: This could be a simple, stupid algorithm to fill the keys array:

  this.keys = []

  var lastWasBlack = true;
  var d = 5;
  var next = 5;
  for(var i = 0, e = 55; i < e; ++i) {

    var isBlack = !lastWasBlack;
    if (i === next) {
      isBlack =!isBlack;
      d = d === 5 ? 7 : 5;
      next += d;
    }
    this.keys.push({
      black : isBlack
    });

    lastWasBlack = isBlack;
  }

}

http://plnkr.co/edit/kIvRqdkbHHNcUXKzSLZC?p=preview

Upvotes: 2

Rajeshwar
Rajeshwar

Reputation: 2509

Have a look at the below plunker. I haven't added any css. But just to hide and show the images you can use this link.

http://plnkr.co/edit/pgFKHShXpeS4EQhoaFTI?p=preview

<ul class="white-keys">
  <li ng-repeat="t in draw.range(20) track by $index">
    <img ng-src='http://lorempixel.com/g/50/15/technics' ng-hide="($index == 1 || $index == 4 || $index == 8 || $index == 11)"/>
  </li>
</ul>

I have used ng-hide to hide the images at specific position. Is this you are looking for? If not let me know.

Upvotes: 0

Related Questions