-1

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?

Tyler
  • 3,713
  • 6
  • 37
  • 63
  • What's wrong with your code?! – Mosh Feu May 19 '16 at 10:55
  • Like I said, "I can do this for the most part if I get the element by "label," but I'd rather access it by it's attribute name." So nothing is wrong with my code, my code is there to give an example of what I am currently doing that works, but now I want to grab that subelement by the attribute, not by the element tag – Tyler May 19 '16 at 10:58
  • So you can replace `.find('label')` to `.find('[expand-button]')` - unless I missing something.. – Mosh Feu May 19 '16 at 11:04
  • My pleasure.. Thanks! – Mosh Feu May 19 '16 at 11:11

1 Answers1

3

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

Community
  • 1
  • 1
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Just a sec, I'm having some issues getting it to load. You can see here: https://plnkr.co/edit/7cZDmxDDSJ3zcHHTTRr4 It doesn't seem to be finding the element. Or am I missing something? – Tyler May 19 '16 at 11:25
  • This ended up working for me var el = angular.element(elem[0].querySelector('[expand-button]')); console.log(el.html());. The ugliness of it is making me think this is the wrong way of doing things. I'll mark your answer as correct but I don't think this is the angular way of doing it, so I'm gonna keep looking. – Tyler May 19 '16 at 11:41