111

I'm trying to remove jquery from my Angular.js app in order to make it lighter, and put Angular's jqLite instead. But the app makes heavy use of find('#id') and find ('.classname'), which are not supported by jqLite, only 'tag names' (as per documentation)

wondered what do u feel would be the best approach to change it. One approach I thought about is to create custom HTML tags. for example: change
<span class="btn btn-large" id="add-to-bag">Add to bag</span>

to

<a2b style="display:none;"><span class="btn btn-large" >Add to bag</span></a2b>

and

$element.find('#add-to-bag') 

to

$element.find('a2b')

Any thoughts? other ideas?

thanks

Lior

isherwood
  • 58,414
  • 16
  • 114
  • 157
Lior
  • 40,466
  • 12
  • 38
  • 40
  • 4
    ID's must be unique, therefore it makes no sense to find an element that is a child of another element by ID. Simply select the element by Id. If your Id's aren't unique, change your ID to a class. Also, you can use `DomElement.querySelector(".myclassname")` to select a single decendant element using a css selector, or all matching by adding All to it: `DomElement.querySelectorAll(".myclassname")` That of course doesn't work in IE<9. – Kevin B Jun 24 '13 at 19:48
  • If you define an `a2b` element, you must have defined a directive. Can you do what needs to be done in the link function of the directive, and therefore avoid the need to call find() entirely? Similarly with your classes -- can you define directives and put the functionality you need into the directives' link (or compile) functions? – Mark Rajcok Jun 24 '13 at 19:53
  • 2
    @KevinB Angular's jqLite is said to support 'only tag names' – Lior Jun 24 '13 at 20:08
  • @MarkRajcok I didnt define a directive. it seems to work in IE and chrome. but even if I would define a directive, why would it help? I would still need to get hold of a DOM element. – Lior Jun 24 '13 at 20:11
  • How come find('span.btn') or similar doesn't work for you? – Fabi Jun 24 '13 at 20:12
  • @Fabi `.find` in jqLite doesn't support the `.btn` portion of that string – Kevin B Jun 24 '13 at 20:14
  • oh im sorry I didnt catch the "only tag names" part – Fabi Jun 24 '13 at 20:15
  • In the link function of a directive, the second argument, `element` is the DOM element (wrapped in jQuery or jqLite). – Mark Rajcok Jun 24 '13 at 20:19
  • Maybe you've already read this, but I thought I should share anyways - http://jaketrent.com/post/angularjs-find-element-in-context/ – Fabi Jun 24 '13 at 20:19
  • @Fabi jqLite does not support class names see http://docs.angularjs.org/api/angular.element `$element.find('span.btn');` [] `$element.find('a2b');` [ ​…​​ ] – Lior Jun 24 '13 at 20:22
  • parent.find('#id') is an uncommon but perfectly valid thing to want to do. It provides element #id only when that element is a child of parent, excluding it otherwise. – HonoredMule Sep 14 '15 at 15:52

3 Answers3

206

Essentially, and as-noted by @kevin-b:

// find('#id')
angular.element(document.querySelector('#id'))

//find('.classname'), assumes you already have the starting elem to search from
angular.element(elem.querySelector('.classname'))

Note: If you're looking to do this from your controllers you may want to have a look at the "Using Controllers Correctly" section in the developers guide and refactor your presentation logic into appropriate directives (such as <a2b ...>).

André Laszlo
  • 15,169
  • 3
  • 63
  • 81
psema4
  • 3,007
  • 1
  • 17
  • 22
  • 3
    Thanks! to add from Ricardo Bin answer (angular's mailing list), $document injectable could be used too: http://jsfiddle.net/ricardohbin/fTQcs/ – Lior Jun 26 '13 at 20:31
  • Unfortunately, the referred URL is no longer valid (http://docs.angularjs.org/guide/dev_guide.mvc.understanding_controller), and there doesn't seem to be any replacement in that section. – Per Quested Aronsson Dec 05 '13 at 08:38
  • No. angular.element(document.querySelector('#id')) is the alternative to: $('#id'), not for: elementArray.find('#id') – Broda Noel Feb 12 '15 at 18:44
  • Right - but as we have found as we build new parts of our application in angular we sometimes need to "duct tape" older parts onto it for a while until they can be updated or re-factored. In our case we needed to load some old jquery/ajax data without modifying the existing mess so we did the following- $http.get('/Task/GetTaskStatsByTaskId/' + taskId).success(function (data) { angular.element(document.querySelector('#userTasksContainer')).html(data); }); – Kenn Mar 20 '15 at 17:15
  • 42
    If elem is a jqlite object it would be `angular.element(elem[0].querySelector('.classname'));` – cleversprocket Apr 01 '15 at 22:53
  • Can we select element using `ng-model`? Using Angular element. – Arpit Kumar Nov 03 '16 at 06:35
3

angualr uses the lighter version of jquery called as jqlite which means it doesnt have all the features of jQuery. here is a reference in angularjs docs about what you can use from jquery. Angular Element docs

In your case you need to find a div with ID or class name. for class name you can use

var elems =$element.find('div') //returns all the div's in the $elements
    angular.forEach(elems,function(v,k)){
    if(angular.element(v).hasClass('class-name')){
     console.log(angular.element(v));
}}

or you can use much simpler way by query selector

angular.element(document.querySelector('#id'))

angular.element(elem.querySelector('.classname'))

it is not as flexible as jQuery but what

hannad rehman
  • 4,133
  • 3
  • 33
  • 55
1

If elem.find() is not working for you, check that you are including JQuery script before angular script....

SK.
  • 4,174
  • 4
  • 30
  • 48
AndroC
  • 4,758
  • 2
  • 46
  • 69
  • 3
    Although the OP specifically asked about jqLite, for those using jQuery and expecting find() to work with classes and ID's as well this answer may certainly help. – Matt B Dec 17 '14 at 11:44
  • 2
    To clarify: "If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or jqLite.". Quote from: https://docs.angularjs.org/api/ng/function/angular.element . jqLite contains find(). – Kmaczek Jan 08 '17 at 20:18