Skip to content Skip to sidebar Skip to footer

Angularjs: Element.show() In Directive Not Working

I have a directive (see plunk) that wraps a DIV with style display:none and after one second shows its content. I tried to make it display with element.show() and $(element).show()

Solution 1:

The element is shown, the problem is that it does not contain anything to show. Also, to have the show function, you need to add a jQuery dependency and apply it to the correct div.

angular.module("app", []);

functionMyCtrl($scope) {}

angular.module("app").directive('hideme', function($timeout) {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div style="display: none;"><div ng-transclude></div></div>',
    link: function(scope, element, attrs) {
      $timeout(function() {
        element.find("div:hidden").show();
      }, 1000)
    }
  };
});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="app"><hideme>
    Show me after one second.
  </hideme></div>

That said. I would do it this way:

angular.module("app", []).directive('hideme', function($timeout) {
  return {
    restrict: 'E',
    transclude: true,
    scope: true,
    template: '<div ng-show="show"><div ng-transclude></div></div>',
    link: function(scope, element, attrs) {
      scope.show = false;
      $timeout(function() {
        scope.show = true;
      }, 1000)
    }
  };
});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="app"><hideme>
    Show me after one second.
  </hideme></div>

Solution 2:

  1. The template gets inserted into your custom tag, so your <div> becomes a child of the <hideme> tag.

  2. In the link() function, the element argument is the <hideme> tag--not the <div>--therefore unhiding the <hideme> tag does not unhide a child <div> which has been styled with display: none. In other words, if you have this:

    <hideme style="display: block"> <div style="display: none">Show this in three seconds.</div> </hideme>

    that won't display the <div>.

  3. If you don't load jQuery before loading angularjs, then angularjs uses something it calls jqLite to wrap elements. The wrapped elements act like jQuery wrapped sets, but they have reduced functionality, e.g. show() and hide() are not provided.

So if you load jQuery and then load angularjs, you can do this:

app.js:

var app = angular.module('myApp', []);

app.directive('hideMe', ['$timeout', function($timeout) {
  var directive = {};

  directive.restrict = 'E';

  directive.link = function(scope, element, attrs) {
    element.html(
      '<div style="display:none">' 
      + element.text() 
      + '</div>'
    );

    $timeout(function() {
      element.children().show();
    }, 3000);

  };


  return directive;
}]);

index.html:

<!DOCTYPE html><htmlng-app="myApp"><head><!-- For html5 (default is UTF-8) --><metacharaset="UTF-8"><!-- For Bootstrap --><metaname="viewport"content="width=device-width, initial-scale=1"><title>AngularJS Examples</title><!-- Bootstrap CSS --><linkhref="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css"rel="stylesheet"><!-- app.css --><linkhref="app.css"rel="stylesheet"></head><bodyclass="container"><hide-me>Show this after three seconds.</hide-me><!-- JQuery 2.1.1 --><scriptsrc="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><!-- Angular 1.3.3 --><scriptsrc="//ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script><!-- app.js --><scriptsrc="app.js"></script></body></html>

However, I notice that the text flashes briefly on the page before being hidden. Edit: If I replace element.text() with element.html(), then there's no flash.

On the other hand, if you don't load jQuery you can do this:

var app = angular.module('myApp', []);

app.directive('hideMe', ['$timeout', function($timeout) {
  var directive = {};

  directive.restrict = 'E';

  directive.link = function(scope, element, attrs) {
    var hideme = element[0];
    hideme.innerHTML = '<div style="display:none">' + hideme.innerHTML + '</div>';

    $timeout(function() {
      var div = hideme.childNodes[0];
      div.style.display = "block";
    }, 3000);

  };


  return directive;
}]);

Then the text doesn't flash on the screen before being hidden.

Solution 3:

.hide() and .show() functions work only if jquery is inserted before angular in your html file.

Gwenn

Solution 4:

You could easily just use the following without including jQuery to show the element:

element.css('display', 'block');

And corresponding to hide it:

element.css('display', 'none');

Solution 5:

Plunker: http://plnkr.co/edit/bzhCwjXdll3ibxc7qsMY?p=preview

Try using transclude:true and then ng-transclude to display the markup between custom element tags. Also, I'm not familiar with using show(), so instead set html ng-show='showEl' and define showEl = true in the timeout.

angular.module("app", []);

functionMyCtrl($scope) {}

angular.module("app").directive('hideme', function($timeout) {

    return {
          transclude: true,
        restrict: 'E',
        template: '<div ng-show="showEl"><div ng-transclude></div></div>',
        link: function(scope, element, attrs) { 
            $timeout(function() {
                  scope.showEl = true;
              }, 1000);
        }
    };
});

Post a Comment for "Angularjs: Element.show() In Directive Not Working"