How to select an element by classname using jqLite?
Asked Answered
C

3

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

Crepuscule answered 24/6, 2013 at 19:39 Comment(11)
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.Shaven
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?Moneywort
@KevinB Angular's jqLite is said to support 'only tag names'Crepuscule
@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.Crepuscule
How come find('span.btn') or similar doesn't work for you?Weal
@Weal .find in jqLite doesn't support the .btn portion of that stringShaven
oh im sorry I didnt catch the "only tag names" partWeal
In the link function of a directive, the second argument, element is the DOM element (wrapped in jQuery or jqLite).Moneywort
Maybe you've already read this, but I thought I should share anyways - jaketrent.com/post/angularjs-find-element-in-contextWeal
@Weal jqLite does not support class names see docs.angularjs.org/api/angular.element $element.find('span.btn'); [] $element.find('a2b'); [ <a2b style=​"display:​none;​">​…​</a2b>​ ]Crepuscule
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.Nevanevada
W
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 ...>).

Wooton answered 26/6, 2013 at 20:15 Comment(6)
Thanks! to add from Ricardo Bin answer (angular's mailing list), $document injectable could be used too: jsfiddle.net/ricardohbin/fTQcsCrepuscule
Unfortunately, the referred URL is no longer valid (docs.angularjs.org/guide/dev_guide.mvc.understanding_controller), and there doesn't seem to be any replacement in that section.Wandering
No. angular.element(document.querySelector('#id')) is the alternative to: $('#id'), not for: elementArray.find('#id')Senegal
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); });Syllabize
If elem is a jqlite object it would be angular.element(elem[0].querySelector('.classname'));Krilov
Can we select element using ng-model? Using Angular element.Pray
T
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

Terricolous answered 13/12, 2016 at 6:43 Comment(0)
A
1

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

Abscond answered 28/11, 2014 at 22:45 Comment(2)
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.Reggi
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: docs.angularjs.org/api/ng/function/angular.element . jqLite contains find().Petuu

© 2022 - 2024 — McMap. All rights reserved.