AngularJS - Find Element by Attribute Value - angularjs

I'm trying to use AngularJS to query the DOM of my view. I need to get all of the elements that have the attribute 'data-placement' with the value of 'top'. In jQuery, I would do this:
var elements = $('[data-placement="top"]');
However, I don't know how to do it with AngularJS. Can someone tell me how to do this?
Thank you!

In AngularJS you won't do direct DOM manipulation from the controller, you should create a directive to to that. Inside the directive you can use JQuery as you wish.
Anyway you I think you can use angular.element() with a JQlite selector, here's the documentation of angular.element.
Example:
// find('#id')
angular.element(document.querySelector('#id'))

From your question I understand that you wanted to find elements with atrributes requiring certain condition in that case we can use $document.
You can find more info about it here.
So coming to your requirement, you can find it by.
$document.find("[attribute-name='attribute-value')");
That will return the element object wrapped in jQuery or jqLite. But to use it you need to inject $document into your controller. So you continue angular related operations with it.
Another approach to this is angular.element.
angular.element.find("[attribute-name='attribute-value')");
But this will return element with wrapped raw DOM element or HTML string as a jQuery element. you can find more info about it here
I prefer to use $document as Angular operations can be done using the first method.

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.

Checking element visibility in Angularjs

I have been trying to find a way to determine if an element is visible in Angular without including full blown jQuery. The line I am struggling with is:
visibleElement = $('#detect-breakpoints .breakpoint:visible');
I have tried using various combinations of document.querySelector and document.querySelectorAll but nothing has worked.
Any help would be appreciated.
I'd suggest to use angular.element if you want to use jquery like element selectors. Something like:
$('#detect-breakpoints .breakpoint').is(':visible');
should also work.
But if you use the in-built directives ng-hideor ng-show to handle the visibility states of your elements in the angular app, then you won't need such selectors in because you could use the framework to achieve the same.

Dynamically created element not firing click event

$scope.addNew = function(){
$('.thumb-img-gallary').append("<li><span class='img-del' ng-click='delThumbImgGallaryPhoto($event)'>X</span><img class='thumb-img' src='data:image/jpeg;base64,"+imageData+"'/></li>");
}
I am calling this function to add element dynamically. But then delThumbImgGallaryPhoto() is not getting called.
you cannot just append an element with a ng-click or any other directive, and expect it to work. it has got to be compiled by angular.
explenation about compilation from angular docs:
For AngularJS, "compilation" means attaching directives to the HTML to make it interactive
compelation happens in one of two cases:
When Angular bootstraps your application, the HTML compiler traverses the DOM matching directives against the DOM elements
when you call the $compile service inside an angular context
so what you need to do, is first to compile it(remeber to inject the $compile service in your controller), and then append it:
$scope.addNew = function(){
var elem = $compile("<li><span class='img-del' ng-click='delThumbImgGallaryPhoto($event)'>X</span><img class='thumb-img' src='data:image/jpeg;base64,"+imageData+"'/></li>")($scope);
$('.thumb-img-gallary').append(elem);
}
BTW, remember it is prefable not to have any DOM manipulations done in the controller. angular has directives for that.
You have to compile it with scope
try like this
var item="<li><span class='img-del' ng-click='delThumbImgGallaryPhoto($event)'>X</span><img class='thumb-img' src='data:image/jpeg;base64,"+imageData+"'/></li>"
$('.thumb-img-gallary').append(item);
$compile(item)($scope);
angular doesn't know anything about your newly added element. You need to compile your newly added element using $compile. and you should better use directive for this task.
It is a bad habit to access ui elements from controller.
edit: it would be best using ng-repeat for this task. lets say you have a thumb-gallery directive which is repeated using ng-repeat by thumbs array.
when you need to add a new image you only need to add it to your thumbs array.
it is simple and straightforward
Your html would look like
<thumb-gallery ng-repeat="gallery in galleries"></thumb-gallery>
and your js would look like
var gallery = {};
$scope.galleries.add(gallery);

Angular equivalent of Knockout ko.dataFor

ko.dataFor(element) allows to retrieve the object bound to a DOM element. Does angular have a similar function?
Maybe you can use:
angular.element(element1).scope().variable
element1: dom element,
variable: scope variable
More information here.
AngularJS have a different approach on that and data is not strictly bounded to DOM elements, You probably can look up for two way data binding that will bring you closer to the answer
Don't bind data to DOM elements in the first place. Store data in for example angular services.

AngularJS - ng-bind-html-unsafe and ng-model Problems

I have the following line in my html:
<div ng-bind-html-unsafe="departmentConfig" class="control-group"></div>
and I use a $resource get to retrieve the HTML, assign the HTML to $scope.departmentConfig, and then the view is updated perfectly. The HTML that is assigned to $scope.departmentConfig contains form elements, with ng-model attributes in it, but when I change the values in these input elements, they don't update the $scope model at all.
This is what I have tried, based on a lot of other internet posts, and it isn't working:
$resource('resources/sources/departments/:mappedName', {
mappedName:departmentKey
}).get(function(departmentConfig) {
// This will call another function that will build a chunk of HTML
$scope.departmentConfig = $scope.buildDepartmentConfigHtml(departmentConfig);
// This is my feeble attempt to access the element, and bootstrap it to include the items in the $scope model.
var $departmentConfigContainer = $('#departmentConfig');
angular.bootstrap($departmentConfigContainer, ['sourcemanager']);
I have even seen some jsFiddle examples where this appears to be working, but mine isn't. Am I calling bootstrap too soon? I also tried putting a $watch on $scope.departmentConfig like this:
$scope.$watch('departmentConfig', function() {
var $departmentConfigContainer = $('#departmentConfig');
angular.bootstrap($departmentConfigContainer);
});
but it didn't work either. I bet there is an easy explanation to this, I just can't seem to get the input elements with ng-model that are loaded after page compile to get bound to the model. Any help is appreciated, this is the last piece of functionality I need to get working on my page. Let me know if you need more information about my configuration as well.
So, simply put, how can I force a section of the DOM to recompile after I know it has been loaded?
UPDATE
Here is a jsfiddle outlining what I would like to do: http://jsfiddle.net/j_snyder/ctyfg/. You will notice that property two and three don't update the model, and I am calling bootstrap on the outer div, hoping that will include those in the model binding. This is the first time I have posted to jsfiddle, please let me know if you can't see the example.
ng-bind-html is made for regular HTML, not compiling new angular elements.
You will have use the $compile service.
Here is how you would edit your current example to work: http://jsfiddle.net/andytjoslin/ctyfg/21/. But this way ends up being bad, because you have to do DOM manipulation in your controller.
You just need to create a directive that will basically do what you wanted ng-bind-html to do: http://jsfiddle.net/andytjoslin/ctyfg/22/

Resources