1

I have a list of play/pause buttons created by an ng-repeat. You click each play button to stream a song and the button turns into a pause button (so you can then pause it). I was able to get the buttons and click events set up correctly but ran into the problem of when you click one play button, all the buttons change to pause buttons.

play buttons pause buttons

I (think I) get why this is happening: because the ng-show variable (visible) is being changed and that therefore affects all of them.

I read through other similar answers on this (ng-repeat ng-show dilemna) but I haven't been able to apply the lessons (such as using $index) to my example. Also, many of the examples and fiddles use a div that you click which then does something like show = !show which then in turn shows a "loading..." .

I think mine's a bit different.

Here's my html:

<div class="nav nav-stacked list-group-item" id="sidebar" ng-repeat="show in shows"> 

                <div class="media col-md-3">

                    <img class="media-object img-rounded img-responsive" src="/images/play_button.png" alt="playbutton" height="40px" width="40px" ng-click="streamTrack(show.stream_url)" ng-show="visible">
                    <img class="media-object img-rounded img-responsive" src="/images/pause_button.png" alt="playbutton" height="40px" width="40px" padding-right="5px" ng-click="pauseTrack(sound)" ng-hide="visible">

                </div>
        </div>

Here's the relevant part of my controller:

$scope.visible = true;

$scope.streamTrack = function (stream_url) {
    SC.stream(stream_url, function (sound) {
    $scope.sound = sound;
    sound.play();
    });

    $scope.visible = false;

};

$scope.pauseTrack = function (sound) {
    sound.pause();
    $scope.visible = true;
};

What are some ways to handle this? So that when you click on one play button, it hides just than play button and exposes the pause button for only that one. I'm guessing it's probably something with $index or Parentindex but after a couple hours of messing around and reading, I'm still not getting closer.

Kyle Pennell
  • 5,747
  • 4
  • 52
  • 75
  • Use this link[enter link description here][1] [1]: http://stackoverflow.com/questions/24743831/ng-click-ng-show-ng-hide-for-a-list-of-buttons-created-by-ng-repeat – tharo Apr 30 '15 at 10:03
  • @tharo ? Not sure what you mean – Kyle Pennell Apr 30 '15 at 15:57
  • 1
    Sorry Kyle the link is missed You can use the ng-show="showItem[$index]" here you might have to initialize showItem as a array like ng-init="showItem=[]" – tharo May 05 '15 at 08:39

3 Answers3

2

You're applying visible to all of the objects when you need to only apply them to each object like so:

    function sampleController($scope){

        $scope.songs = [
            {title:'song1',visible:true,url:'url-song-1'},
            {title:'song2',visible:true,url:'url-song-2'}
        ];

        $scope.playTrack = function(s) {
            SC.stream(s.stream_url, function (sound) {
              $scope.sound = sound;
              sound.play();
            });
            s.visible = false;
        };

        $scope.pauseTrack = function(s) {
            s.visible = true;
        };
    }

    <div ng-controller="sampleController">
        <ul>
            <li ng-repeat="s in songs">
                {{s.title}}
                <button ng-click="playTrack(s)" ng-show="s.visible">Play</button>
                <button ng-click="pauseTrack(s)" ng-show="!s.visible">Pause</button>
            </li>
        </ul>
    </div>
Rob
  • 1,840
  • 2
  • 12
  • 19
  • 1
    Another way to do this if you don't want to assign a visible property to your data would be to add a conditional in the ng-show attribute like this: – Rob Jul 14 '14 at 19:24
2
<div ng-init="showItem=[]">
    <div class="nav nav-stacked list-group-item" id="sidebar" ng-repeat="show in shows">
        <div class="media col-md-3">
            <img class="media-object img-rounded img-responsive" src="/images/play_button.png" alt="playbutton" height="40px" width="40px" ng-click="streamTrack(show.stream_url)" ng-show="showItem[$index]">
            <img class="media-object img-rounded img-responsive" src="/images/pause_button.png" alt="playbutton" height="40px" width="40px" padding-right="5px" ng-click="pauseTrack(sound)" ng-hide="showItem[$index]">
        </div>
    </div>
</div>

hope this will help you .

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
tharo
  • 74
  • 5
1

That happens because you've got one common variable $scope.visible

please see that jsbin : http://jsbin.com/woxali/1/edit

html:

<div class="nav nav-stacked list-group-item" id="sidebar" ng-repeat="show in shows"> 

                <div class="media col-md-3">

                    <img class="media-object img-rounded img-responsive" 
                         src="https://cdn1.iconfinder.com/data/icons/defaulticon/icons/png/256x256/media-play.png" alt="playbutton" height="40px" width="40px" ng-click="streamTrack(show)" 
                         ng-hide="show.isplaying">
                    <img class="media-object img-rounded img-responsive" src="http://cdn.flaticon.com/png/256/12193.png" alt="playbutton" height="40px" width="40px" padding-right="5px" ng-click="pauseTrack(show)" ng-show="show.isplaying"">

                </div>
        </div>
      </div>

js:

app.controller('firstCtrl', function($scope){
 $scope.sound = {};
 $scope.shows = [
   {  stream_url:1 },
   {  stream_url:2 },
   {  stream_url:3 },
   ];

 $scope.streamTrack = function (show) {

    SC.stream(show.stream_url, function (sound) {
    $scope.sound = sound;
    $scope.sound.play();
    });

    show.isplaying = true;

};

$scope.pauseTrack = function (show) {
    $scope.sound.pause();
    show.isplaying = false;
};
});
sylwester
  • 16,498
  • 1
  • 25
  • 33
  • Thank you Sylwester (and thanks for including the jsbin). Why does `$scope.sound.pause();` need $scope in this case? That's pretty much the only part I don't get. – Kyle Pennell Jul 15 '14 at 00:47
  • 1
    @KylePennell when you invoke method streamTrack we created $scope.sound object now we can access it in pauseTrack and invoke pause method – sylwester Jul 15 '14 at 09:01