How to hide element if transcluded contents are empty? How to hide element if transcluded contents are empty? angularjs angularjs

How to hide element if transcluded contents are empty?


Here's an approach using ng-show on the template and within compile transcludeFn checking if transcluded html has text length.

If no text length ng-show is set to hide

app.directive('pair', function($timeout) {  return {    replace: true,    restrict: 'E',    scope: {      label: '@'    },    transclude: true,    template: "<div ng-show='1'><span>{{label}} </span><span ng-transclude></span></div>",    compile: function(elem, attrs, transcludeFn) {            transcludeFn(elem, function(clone) {               /* clone is element containing html that will be transcludded*/               var show=clone.text().length?'1':'0'                attrs.ngShow=show;            });        }  }});

Plunker demo


Maybe a bit late but you can also consider using the CSS Pseudo class :empty.So, this will work (IE9+)

.trancluded-item:empty {  display: none;}

The element will still be registered in the dom but will be empty and invisible.


The previously provided answers were helpful but didn't solve my situation perfectly, so I came up with a different solution by creating a separate directive.

Create an attribute-based directive (i.e. restrict: 'A') that simply checks to see if there is any text on all the element's child nodes.

function hideEmpty() {    return {        restrict: 'A',        link: function (scope, element, attr) {            let hasText = false;            // Only checks 1 level deep; can be optimized            element.children().forEach((child) => {                hasText = hasText || !!child.text().trim().length;            });            if (!hasText) {                element.attr('style', 'display: none;');            }        }    }; }angular    .module('directives.hideEmpty', [])    .directive('hideEmpty', hideEmpty);

If you only want to check the main element:

link: function (scope, element, attr) {    if (!element.text().trim().length) {        element.attr('style', 'display: none;');    }}

To solve my problem, all I needed was to check if there were any child nodes:

link: function (scope, element, attr) {    if (!element.children().length) {        element.attr('style', 'display: none;');    }}

YMMV