Question

I have a set of headings (<h3>) that when clicked, they hide/show their corresponding sections.

I have achieved this by using ng-show/ng-hide and then calling a $scope variable isInactive/isActive.

What i would like to know, is if the same result can be achieved, without the need for using JS within $scope.isInactive and $scope.isActive and logic be placed in the HTML markup? Possibly with the us of ng-class?

HTML:

<div ng-app="">
  <div ng-controller="EventController">
    <div class="tabs">
         <h3 class="" id="tab-{{$index}}-0"><a id="1" data="{{$index}}" ng-click="switch($event)">1 - 5 Years</a></h3>

         <h3 class="inactive" id="tab-{{$index}}-1"><a id="2" data="{{$index}}" ng-click="switch($event)">6 - 10 Years</a></h3>

         <h3 class="inactive" id="tab-{{$index}}-2"><a id="3" data="{{$index}}" ng-click="switch($event)">11 - 15 Years</a></h3>

         <h3 class="inactive" id="tab-{{$index}}-3"><a id="4" data="{{$index}}" ng-click="switch($event)">16 - 20 Years</a></h3>

        <div class="clear" data="{{$index}}" ng-hide="isInactive('#tab-'+{{$index}} + '-0')">1 - 5 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
        <br>
        <div class="clear" ng-show="isActive('#tab-'+{{$index}} + '-1')">6 - 10 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
        <br>
        <div class="clear" ng-show="isActive('#tab-'+{{$index}} + '-2')">11 - 15 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
        <br>
        <div class="clear" ng-show="isActive('#tab-'+{{$index}} + '-3')">16 - 20 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
    </div>
  </div>
</div>

JS:

function EventController($scope) {

$scope.
switch = function (e) {
    var target = e.target || e.srcElement;
    var elem = angular.element(target);
    var parent = elem.parent();
    var allHeadings = parent.parent().find("h3");

    angular.forEach(allHeadings, function (aHeading) {
        var child = angular.element(aHeading);
        child.addClass("inactive");
    });
    parent.removeClass("inactive");
}

$scope.isInactive = function (e) {
    var elem = angular.element(document.querySelector(e));
    if (elem.hasClass("inactive")) {
        return true;
    } else {
        return false;
    }
};

$scope.isActive = function (e) {
    var elem = angular.element(document.querySelector(e));
    if (elem.hasClass("inactive")) {
        return false;
    } else {
        return true;
    }
};

}

My jsFiddle: http://jsfiddle.net/oampz/Wr79J/2/

Was it helpful?

Solution

Yes, you have correctly identified this the apt place for using ng-class.

It is possible to do only using HTML and a minimalistic controller: http://jsfiddle.net/Wr79J/4/

JS

function EventController($scope) {
    $scope._activeTab = 1;
}

HTML

<div ng-app="">
    <div ng-controller="EventController">
        <div class="tabs">
             <h3 ng-class="{ 'inactive': _activeTab !== 1, 'active': _activeTab == 1 }">
               <a id="1" ng-click="_activeTab=1">1 - 5 Years</a></h3>

     <!-- .... -->

    <div class="clear" ng-show="_activeTab == 1">
       1 - 5 Years Text - Lorem ipsum ...
    </div>

</div>

Note: I think you were using {{$index}} from a scope this part of the template had inherited. I have left that untouched in the example.

Though this works, this code is not very maintainable. You may want to use more descriptive names for the tabs instead of 1, 2, 3, and 4.

You can get rid of the controller completely using an ng-init="_activeTabe = 1" on the container div, but it is not the correct use of ng-init.


Also, it is not considered good practise to manipulate the DOM in any way from the controller (I am looking at the addClass/removeClass in the code). If it is necessary, then one should use directives (e.g. ng-class) for the manipulation.

OTHER TIPS

You can just set a variable to set the active tab.

<div class="tabs">
  <h3 ng-click="range=1">1-5</h3>
  <h3 ng-click="range=2">6-10</h3>
  <div class="clear" ng-show="range==1">1 - 5 Years Text</div>
  <div class="clear" ng-show="range==2">6 - 10 Years Text</div>
</div>

Here is an example - http://plnkr.co/edit/NTVPbOC5k7HKo88qp6vN?p=preview with no javascript code for the above logic.

  <div>
    <div>
      <div class="tabs">
        <h3 ng-init="active=1" ng-click="active=1" ng-class="{true:'active', false:'inactive'}[active==1]"><a >1 - 5 Years</a></h3>
        <h3 ng-click="active=2" ng-class="{true:'active', false:'inactive'}[active==2]"><a >6 - 10 Years</a></h3>
        <h3 ng-click="active=3" ng-class="{true:'active', false:'inactive'}[active==3]"><a >11 - 15 Years</a></h3>
        <h3 ng-click="active=4" ng-class="{true:'active', false:'inactive'}[active==4]"><a >16 - 20 Years</a></h3>

        <div ng-show="active==1">1 - 5 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
        <br>
        <div ng-show="active==2">6 - 10 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
        <br>
        <div ng-show="active==3">11 - 15 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
        <br>
        <div ng-show="active==4">16 - 20 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
      </div>
    </div>
  </div>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top