5

Sample

Please consider this Plunkr.

What I need

I need to be able to get an element by it's id.

The sample code should be able to assign a css class to any DOM element that exists on the current view.

This should be checked using a source object, provided by the $scope in a controller. This source object may/will have more properties than there are input elements on the view.

So I want to loop through each object key and see if a corresponding DOM element exists. If so, validate it's value.

The question

How do I get an element by id, using AngularJS only (jQuery is NOT allowed!!)?

Specifically for the Plunkr, I need this function to (really) work:

self.IsFieldCurrentlyActive = function(field){
  // Should be (in pseudocode):
  // var inputElement = angular.find(field);
  // return (inputElement != 'undefined');

  // Sample only
  var idx = field.indexOf('Unused');
  return idx == -1;
};

And this one (basically the same):

self.GetElementByKey = function(key)
{
  // Should be (in pseudocode):
  // var inputElement = angular.find(field);
  // return inputElement;

  // Sample only
  return null;
}

Update

Apologies, I forgot to add an important requirement: I can't use any mechanism that assumes unique IDs, because there may be multiple occurrences of the same form (and the same IDs). So, I need to respect the Angular scope.

Thanks!

Spikee
  • 3,967
  • 7
  • 35
  • 68
  • 1
    What you want to achieve ? just assign a class to element ? – Ajinder Singh Sep 09 '15 at 10:12
  • 1
    methinks you doing something wrong if you need use dom manipulation in factory or controller, try see [“Thinking in AngularJS” if I have a jQuery background?](http://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background?rq=1) – Grundy Sep 09 '15 at 10:13
  • 1
    As @Grundy said this is not angular way of doing things . Consider controller,directives for DOM manipulation. – Ajinder Singh Sep 09 '15 at 10:15
  • Agree with the above comments. Try to take advantage of Angular's bindings instead of trying to do direct DOM manipulation. – Asa Sep 09 '15 at 10:23
  • @Ajinder: Basically yes, just the class. Re factory/controller: Thanks for the link, I know, I have that exact problem :). But, I chose to use a service because that functionality will be shared by other directives. – Spikee Sep 09 '15 at 10:44
  • 1
    @Spikee Consider using ng-class for conditionally assigning classes to element. Check https://docs.angularjs.org/api/ng/directive/ngClass – Ajinder Singh Sep 09 '15 at 10:51
  • 1
    @Spikee - you can move the conditional logic to service and manipulate the element via directives – Ajinder Singh Sep 09 '15 at 10:55
  • @Ajinder: I moved away from ng-class because of this issue: [link](http://stackoverflow.com/questions/32439287/angularjs-conditional-ng-class-with-a-function-triggering-ridiculous-amounts) – Spikee Sep 09 '15 at 10:58
  • @Spikee, so, you moved away from ng-class becuase used it wrong? :-) – Grundy Sep 09 '15 at 11:21
  • Possibly :). Though, I tested it, and it runs multiple times even with very simple scenarios. Let's just say I keep my options open right now ... – Spikee Sep 09 '15 at 11:29

2 Answers2

14

In pure JS you can do document.querySelector('#myID');

Or within angular using angular.element: angular.element(document.querySelector('#myID'));

Lauromine
  • 1,453
  • 9
  • 19
  • Depending on the browsers that you want support it's better to use [document.getElementById()](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById). `querySelector` is only supported in modern browsers. – Daniele Torino Sep 09 '15 at 10:15
  • Sadly this wont work because there may be multiple occurrences of the same form (and the same id), so I need to stay in (Angular) scope. – Spikee Sep 09 '15 at 10:40
  • 3
    An Id should be unique. http://www.w3.org/TR/2014/REC-html5-20141028/dom.html#the-id-attribute – Lauromine Sep 09 '15 at 11:08
  • Like I said, there's no way to guarantee it, and providing a mechanism that would force unique ids would make state-management very hard considering the complexity. – Spikee Sep 09 '15 at 11:42
  • Actually, I found a possible solution that would be doable: [link](http://stackoverflow.com/questions/23655009/how-to-set-the-id-attribute-of-a-html-element-dynamically-with-angular-js). – Spikee Sep 09 '15 at 12:21
  • 1
    If your IDs are not unique, your DOM is not valid and browsers may react in unpredictable ways. Fix that first, before addressing this question. – Mawg says reinstate Monica Jan 28 '17 at 13:56
1

Instead try angular.element($('#myElement'));

Johan
  • 8,068
  • 1
  • 33
  • 46
Nishith Kant Chaturvedi
  • 4,719
  • 2
  • 16
  • 24
  • 1
    The $('#myElement') part means you're using jQuery right? Sadly that's not an option because I can't guarantee the ID is unique on the view. – Spikee Sep 09 '15 at 11:01
  • Old question is old but, for clarity, [angular.element()](https://docs.angularjs.org/api/ng/function/angular.element) is an AngularJS method, not jQuery. Under the hood angular.element() is actually jqLite. However, if jQuery is loaded before AngularJS it will replace the jqLite implementation with jQuery... making angular.element() be equivalent to jQuery's $() under the hood of angular. – Cliff Armstrong Aug 11 '17 at 18:15
  • 1
    All that said, not being able to guarantee unique IDs represents a flawed design. And using angular.element() is just as likely to fail due to multiple IDs because it is no more limited to the current angular scope than native js methods. – Cliff Armstrong Aug 11 '17 at 18:15