Kyle Pennell
Kyle Pennell

Reputation: 6097

Ng-click ng-show/ng-hide for a list of buttons created by ng-repeat

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.

Upvotes: 1

Views: 3839

Answers (3)

tharo
tharo

Reputation: 74

<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 .

Upvotes: 2

sylwester
sylwester

Reputation: 16498

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;
};
});

Upvotes: 1

Rob
Rob

Reputation: 1860

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>

Upvotes: 2

Related Questions