angularjsng-show

Show/hide one of the dynamically created elements


I have a simple problem that I can't solve. Having multiple elements dynamically created (see picture attached), I need to show/hide the dropdown content only for the element I clicked on. The code bellow is showing/hiding all the elements by pressing any of the buttons.

dropdown content is hidden

dropdown content is shown

I can get the index of the for loop by {{ loop.index }} and use it to dynamically create an id for every dropdown or pass it as a parameter, but still have issues to use it and manipulate the dropdown content to show or hide.

toggleDropdown() is setting the isVisible variable to true or false and based on the value the dropdown is displayed or not.

Here is my controller:

OffersCtrl.$inject = ['PROFILE_ID', '$location'];

function OffersCtrl(PROFILE_ID, $location) {
  let vm = this;

  vm.isVisible = false;
  vm.getText = getText;
  vm.toggleDropdown = toggleDropdown;

  function toggleDropdown() {
    vm.isVisible = !vm.isVisible;
  }
}

this is my html/twig (OffersCtrl is defined as $ctrl):

<ul class="offer-tiles">
    {% for offer in profile.offers %}
    <li>
        <div class="content">
            <p class="title">{{ offer.title }}</p>

            <p class="price">
                <span class="symbol">€</span>
                <span class="value">{{ offer.price.convertedAmount }}</span>
            </p>

            <p class="description">{{ offer.category.name }}</p>

            <input type="button" id="expandBtn" class="expand" value="v" ng-click="$ctrl.toggleDropdown()" />
        </div>
        <div class="box-dropdown" ng-show="$ctrl.isVisible">
            <p>{{ offer.description }}</p>
            <hr/>
            .... 
        </div>
    </li>
    {% endfor %}
</ul>

Solution

  • You have to use isVisible as an array, because you have multiple values.

    angular.module('app', [])
      .controller('ctrl', function() {
        const vm = this;
    
        vm.isVisible = [];
        vm.toggleDropdown = toggleDropdown;
        vm.offers = [
          {description: 'lorem'},
          {description: 'ipsum'},
          {description: 'dolor'},
          {description: 'sit'},
          {description: 'amet'},
        ]
    
        function toggleDropdown(index) {
          vm.isVisible[index] = !vm.isVisible[index];
        }
      });
    <div ng-app="app" ng-controller="ctrl as vm">
      <ul class="offer-tiles">
        <li ng-repeat="offer in vm.offers track by $index">
            <!-- ... -->
            <input type="button" value="v" ng-click="vm.toggleDropdown($index)" />
            <div class="box-dropdown" ng-show="vm.isVisible[$index]">
                <p>{{ offer.description }}</p>
                <hr />
                ...
            </div>
        </li>
      </ul>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>