Search code examples
javascripthtmlangularjsangularjs-ng-repeatng-show

how to use ng-show to display specific divs inside an ng-repeat?


I have an ng-repeat div to dynamically display a set of div tags based on a dynamic list of items, that each have a unique Id , a type and a "title" value which are both strings and I have a click function assigned to each of them. When I want to click on one of these divs , I want to display an separate div associated to that clicked div and I want to do that using an ng-show which at the moment has a condition where the id of this item/div should be equal/equivalent to a scope variable I've defined in a controller associated with the html for this new div to be displayed.

The problem I'm getting is that every one of these separate divs is showing and assuming that all the ng-shows are true which shouldn't be the case and I'm not sure why this is happening as all the id's for the items are unique. I've printed out to the console and can't see anything wrong with the assigning of the variable but not sure if I've missed something with regards to the ng-show condition.

Here is what I have so far in html with 2 div examples (don't worry about replicating all the styling, i just want to figure out what is going on with the html/angular stuff):

<div class="col-md-12 col-sm-12 col-xs-12  " ng-repeat="item in items track by item.id"  ng-click="onClick(item.id)">

  //first type div that is clickable
  <div class="row">
    <div>
      <header class="text">
        <h1 data-ng-if="item.title" ng-bind-html="item.title"></h1>
      </header>
    </div>
  </div>

  //div to be displayed after associated first div type is clicked 
  <div class=" col-sm-11 row"  ng-show="displayMessage===item.id"   >
      <header class="col-sm-12 text">
          <h1  data-ng-if="item.title" ng-bind-html="item.title"></h1>
      </header>
      <p class="col-sm-12" > text about {{item.id]} </p>
  </div>

  //2nd type of  div 
  <div class="row"  style=" background: linear-gradient(135deg, #156570, #1e9d8b);">
      <h1 data-ng-if="item.title" ng-bind-html="item.title"></h1>
      <i class="ms-icon ms-icon-heart-rate"></i>
      <div class="clearfix"></div>
  </div>

  //div to be displayed after associated second div is clicked 
  <div class="col-md-11 col-sm-11 col-xs-11"  ng-show="displayMessage===item.id">

    <div style="background: linear-gradient(135deg, #156570, #1e9d8b);"></div>

    <h1 class="col-sm-12 col-xs-12"  data-ng-if="item.title" ng-bind-html="item.title" style="color:#000"></h1>

    <p class="col-sm-12 col-xs-12 "> text associated with {{item.id}}
    </p>

  </div>

</div>

And here is the simple click function I have . $scope.displayMessage is defined earlier on during the controller setup where its set to an empty string:

$scope.onClick = function (itemId) {
    $scope.displayMessage = itemId;
}

Let me know if I need to add more code.


Solution

  • It could be done in a simpler way without adding property to the items varible you have in scope.

    Let the Controller be

    app.controller('MainCtrl', function($scope) {
      $scope.div_=[]; 
    
      $scope.items = [
      {
        id: 1,
        title: "first item"
       },
      {
        id: 2,
        title: "second item",
       },
      {
        id: 3,
        title: "third item",
       }
    ];
    
      $scope.onClick=function(index,row){
         $scope.div_[index+'_'+row]=true;
       }
      });
    

    HTML will be like

    <body ng-controller="MainCtrl">
        <div ng-repeat="item in items">
        <div style="color:red" ng-click="onClick($index,0)">DIV {{$index}}.0---click to show DIV {{$index}}.0_CHILD</div>
        <div style="color:blue" ng-show="div_[$index+'_0']">DIV {{$index}}.0_CLILD</div>
        <br>
        <div style="color:red" ng-click="onClick($index,1)">DIV {{$index}}.1---click to show DIV {{$index}}.1_CHILD</div>
        <div style="color:blue" ng-show="div_[$index+'_1']">DIV {{$index}}.1_CLILD</div>
        <hr>
        </div>
      </body>
    

    Here an array named 'div_' is maintained to trace all ng-show value of all div.

    Working plunker https://plnkr.co/edit/uhFdCXkmS4gB95c9bjTR?p=preview