Samir Samir - 6 months ago 22
HTML Question

Angularjs - Get element by subdirective name

I am trying to build an expanding box. So I setup my html as so:

<div class="expand" expand-block>
<label expand-button expanded="true">Style</label>
<ul expand-area>
<li><input type="checkbox" /> AWD / 4WD</li>
<li><input type="checkbox" /> Commercial</li>
<li><input type="checkbox" /> Convertable</li>
<li><input type="checkbox" /> Coupe</li>
<li><input type="checkbox" /> Hatchback</li>
<li><input type="checkbox" /> Hybrid / Electric</li>
<li><input type="checkbox" /> Luxury</li>
<li><input type="checkbox" /> Sedan</li>
</ul>
</div>


So here is my JS:

/* EXPAND BOX DIRECTIVE */
app.directive('expandBlock', function() {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
elem.find('label').bind('click', function() {
var some = elem.find('label').html();
console.log(some);
});
}
};
});


I want to make expand-area hide when I click the expand-button. I can probably do this for the most part if I get the element by "label", but I'd rather access it by it's attribute and I can't seem to find a way to get to it without searching the entire DOM.

Do I need to build a separate directive for the expand-button or can I keep this all within a single directive? If I can keep it within a single directive, how do I get the subelement by attribute?

Answer

To find element by attribute you can use a css like selector: [attribute-name]

Replace .find('label') to .find('[expand-button]')

In case you are not using jQuery, you can't use attribute selector so you can get the element by attribute like this:

angular.element(elem[0].querySelector('[expand-button]'))

Related question

Working demo:

var app = angular.module("bLinked", []);
/* EXPAND BOX DIRECTIVE */
app.directive('expandBlock', function() {
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      var btn = angular.element(elem[0].querySelector('[expand-button]')),
          area = angular.element(elem[0].querySelector('[expand-area]'));

      btn.bind('click', function() {
        if (area.hasClass('hidden')) {
          area.removeClass('hidden');
        } else {
          area.addClass('hidden');
        }
      });
    }
  };
});
/* Styles go here */
.hidden {
  display:none;  
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>

<body ng-app="bLinked">

  <div class="expand" expand-block>
    <label expand-button>Style</label>
    <ul expand-area>
      <li><input type="checkbox" /> AWD / 4WD</li>
      <li><input type="checkbox" /> Commercial</li>
      <li><input type="checkbox" /> Convertable</li>
      <li><input type="checkbox" /> Coupe</li>
      <li><input type="checkbox" /> Hatchback</li>
      <li><input type="checkbox" /> Hybrid / Electric</li>
      <li><input type="checkbox" /> Luxury</li>
      <li><input type="checkbox" /> Sedan</li>
    </ul>
  </div>
</body>

https://plnkr.co/edit/z9VGfGxAfeWdC6WmHdfZ?p=preview