Angular JS manipulating dom by element from link function - angularjs

we know that we can access dom from directive by element because element is injected in link function.
see the approach
var app = angular.module("myApp", []);
app.directive('busyBox',function(){
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.on('click', function(){
if(attrs.id=='btnadd')
{
var divElement = angular.element(document.body.querySelector('.parent')).append('<div class="child">Some text</div>');
// console.log(divElement);
// element.parent().find('.parent').append('<div>Some text</div>')
//element.closest('.parent').append('<div class="child">child</div>')
//angular.element(document).find('.parent').append('<div class="child">child</div>');
}
else if(attrs.id=='btnDel')
{
angular.element(document.body.querySelector('.child')).remove();
// m.removeChild(m.firstChild);
}
});
}
}
})
the above code is working but if i do not use angular.element() instead if i use element(document.body.querySelector('.parent')) the code is not working.
the element is injected in link function link: function(scope, element, attrs)
when element is there in directive then why should i use angular.element() ?
please tell me how could i use element from directive to access dom instead of angular.element().
thanks

The element exposed to the postLink function is a jqLite class object which is a tiny, API-compatible subset of jQuery that allows AngularJS to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most commonly needed functionality with the goal of having a very small footprint.
The find() method is limited to lookups by tag name. If you want the find() method to work with class selectors, load jQuery before the angular.js file.
If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to AngularJS's built-in subset of jQuery, called "jQuery lite" or jqLite.
To use jQuery, simply ensure it is loaded before the angular.js file. You can also use the ngJq directive to specify that jqlite should be used over jQuery, or to use a specific version of jQuery if multiple versions exist on the page.
— AngularJS angular.element API Reference
Can't we use element. closest function instead of find to get the div?
The jQuery closest function is not part of AngularJS jqLite. To use the closest function with the element value exposed to the directive postLink function, load the jQuery library before loading the AngularJS library.
For the list of jqLite functions, see AngularJS angular.element API Reference

please tell me how could i use element from directive to access dom instead of angular.element()
If you want to use the element object that is passed into the link function of the directive to manipulate the DOM, you have to use various methods that the element object exposes, like find.
Do not use it like this:
element(document.body.querySelector('.parent'))
Instead you can do:
// works only if you are using jQuery
element.find('.parent');
// for JQLite, the find method is limited to lookup by tag name:
element.find('div');
Note that as mentioned in the answer from #georgeawg, that you might be using JQLite or JQuery ... where the JQLite functionality is not as full featured as JQuery.

Related

Find element without using angular.element and jQuery

I have an Angular controller which uses pure Angular (no jQuery or Javascript). My problem is that I need to find and element without using jQuery or Javascript. I searched a lot on net but could not find any helpful answer.
The solution I found was to use angular.element, but it is not a good idea to use it.
Can anybody help me how to find element without using jquery.element or angular.element?
Thanks in advance.
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.
From here
PS: if you still want to use something other than this look here
Oh, one other edit: you can't actually use angular without javascript, since it is javascript framework..
I would recommend is to create a directive. The element is handed to you in the linking function:
link: function(scope, elem, attr) {
//elem is the dom element that contains the directive...your target object
}
If you do it like this you dont have to create a selector that would look at the entire dom from your controller. In your directive you could also do document.querySelector(".myclass") if the elem object doesn't work for your use case for whatever reason....but I think it should.

Confusing attributes in angularjs directive's link function

I'm writing an angular.js directive, which would conditionally hide the element.
So it would look like this:
link: function(scope, elem, attrs) {
...
elem.hide()
}
I found a lot of examples that were doing exactly that, but somehow my elem attribute is an array not an element, so it does not have a hide() method.
What am I missing?
Thanks!
Most people are loading jQuery before they load angular, which extends its jqLite to the full jQuery.
The hide method doesn't seem to be part of jqLite API (https://docs.angularjs.org/api/ng/function/angular.element), hence such method is not exposed.
That doesn't mean you need jQuery, but that it is not the correct way to handle your problem. There are already the ng-show and ng-if directives to conditionnaly hide an element based on the controller, couldn't you use them?
In your html, add <div ng-show="isDisplayed">, and in your linking function scope.isDisplayed = false

Loading jquery is must in angularjs?

Am trying to manipulate dom by using jquery in angularjs; As per the documentation
"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."
I have two links one using jquery works and one without using jquery throws error.
Needed some suggestion on how to get this working without declaring jquery externally?
I don't think Angular's jQlite supports the .focus() shortcut - jQlite is only a subset of jQuery see https://docs.angularjs.org/api/ng/function/angular.element for a list of jQlite methods.
You need to call focus on element[0].focus as per this stackoverflow answer HTML5: How to set focus on a text input in a list with AngularJS
You can read here the methods that jqLite provide.
In this particular case you could write something like this.
var app = angular.module("myapp", []);
app.controller('myappCtrl', function($scope,$timeout) {
$timeout(function() {
document.getElementById('number').focus()
}, 1);
angular.element(document.getElementById('focusguard-2')).on('focus', function() {
document.getElementById('number').focus();
});
angular.element(document.getElementById('focusguard-1')).on('focus', function() {
document.getElementById('cancel').focus()
});
});

AngularJs element.height() not a function

I am trying to make a directive that would influence element width/height. Looking through examples I've seen that you can get/set width/height by referencing appropriate function. For example in link function of the directive I try to do:
function link(scope, element, attr) {
var height = element.height();
}
However, in my code I get "Error: element.height is not a function".
Am I missing the reference to some angular.js module/library or documentation is not up to date?
Geoff Genz is correct that jqLite has no height() method or equivalent, but there is still a way to get the height of the selected element. Try this:
var height = element[0].offsetHeight;
element[0] returns the pure DOM element (without the jqLite wrapper) which has an offsetHeight property.
If you are not including jQuery angular substitutes its own smaller library, jqLite. jqLite does not have a height() function for DOM elements, so you will either need to write your own or use the full version of jQuery in your project.
The limited jqLite api is here.

What is meant by AngularJS element?

I am trying to learn AngularJS. I was reading the https://github.com/angular/angular.js/wiki/Understanding-Directives : "You do NOT have to wrap AngularJS elements in jQuery()"
What is meant by an AngularJS element?
In Jquery, if I have a DOM element, say by using document.getElementByID() and if I want to make it a jquery element with access to all of its awesome functions, I will simply say
var domElement = document.getElementByID("elemID");
var $domElement = $(domElement); (To cache the element)
So, if in angular I dont have to wrap the DOM element as in Jquery, then can I simply query the DOM and access it and still be able to access all the angular methods.
If so, how it is done? Is it because of the ng-app binding?
Are all DOM elements inside ng-app internally accessed by Angular and turned to equivalent AngularJS elements?
The wiki page is talking about the elements passed by Angular as arguments to the compile and link functions of the directive:
link: function LinkingFunction($scope, $element, $attributes) { ... }
^-- here
If you get an element from the DOM using document.getElementById(), it won't be wrapped in jQuery automatically.

Resources