How to access iframe by id in AngularJS? - javascript

How can I get reference of the iframe element with AngularJS ?
<div>
<iframe id="myframe" ...>
</div>
mycontroller.$inject = ['$document'];
function mycontroller ($document) {
console.log($document.getElementById("myframe")); //always null
}
I can see the iframe, but the reference lookup always prints null. Why?

The $document service returns an array.
You should use it like his :
console.log($document[0].getElementById("myframe"));
Please, see the jsfiddled solution : https://jsfiddle.net/jjbw1z8j/2/

use this,
angular.element('#myframe');
or
console.log(angular.element('#myframe'));

In angular interaction with the DOM elements should be implemented in the directives.
For example jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope) {
})
.directive('myFrame', function() {
return {
link: function(scope, elem) {
console.log('it`s your iframe', elem);
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<div>
<iframe my-frame></iframe>
</div>
</div>
</div>

Related

How to get the value of a custom attribute in angular js

I have created a custom attribute called test in angular js. When I write the test attribute just beside the ng-controller keyword i.d.
<div ng-controller="myCon" test="abc"></div> then I can access that test from the controller by using alert($attrs.test). But if I write the custom attribute test other than beside of the ng-controller keyword, I can't access that. i.e.
<div ng-controller="myCon">
<div test="def"></div>
</div>
In this case I got undefined in alert($attrs.test)
Full code...
<html>
<script src="angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="kumar" >
<button ng-click="check()" test="def">Click</button>
</div>
<script>
var app = angular.module("myApp", []);
app.directive("test", function() {
return {
//template : "<h1>Hello</h1>"
};
});
app.controller("kumar",function($scope,$attrs){
$scope.check=function(){
alert(JSON.stringify($attrs.test)); //getting undefined. I
//should get def.
}
});
</script>
</body>
</html>
app.directive("test", function() {
return {
restrict: "A",
scope: {
text: "#test"
}
};
});
Update your directive scope and add restrict . For better understanding refer to this question
You can check it:
<html>
<script src="src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js""></script>
<body ng-app="myApp">
<div ng-controller="kumar" >
<button ng-click="check()" test="def">Click</button>
</div>
<script>
var app = angular.module("myApp", []);
app.directive("test", function() {
return {
//template : "<h1>Hello</h1>"
};
});
app.controller("kumar",function($scope,$attrs){
$scope.check=function(){
var testa=$scope.test;
alert(JSON.stringify(testa)); //getting undefined. I
//should get def.
}
});
</script>
</body>
</html>
You can get the element on click if you pass $event in ng-click, i.e. ng-click="check($event)" and can get the attribute from $event.target.
Check fiddle : https://jsfiddle.net/ayusharma/xb63g9ca/
JS
app.controller('myCtrl', function($scope) {
$scope.clickMe = function(evt) {
console.log(evt.target.getAttribute('test'))
}
});
HTML
<div ng-controller="myCtrl">
<div ng-click="clickMe($event)" test="abc">Click on Me</div>
</div>

How to let the angularjs controller run only once even many ng-controllers defined in DOM?

I wish I can handle this, but in the bad way...namely I need to use $cookieStore to check either the function called or not.
Every time to use push array then I need to use $cookieStore. But it seems not practical.
Here was my DOM:
<div ng-controller="MyCtrl">
<div>
<div ng-include="'temp2.html'">
Hello, {{name}}!
</div>
</div>
</div>
<script type="text/ng-template" id="temp2.html">
<div ng-controller="MyCtrl">Another View</div>
</script>
And my angularjs controller:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
alert(1);
}
alert(1) function will be called 2 times every times the page was called.
How to avoid this problem without using watcher?
My fiddle for your convenience. Thanks!
The controller would called be twice for both the views, i would suggest you to move controller specific code to init function and use ng-init in one of your views.
var Controller = function($scope) {
$scope.init = function () {
};
};
Your View
<div ng-controller="Controller" ng-init="init()"/>
Yo don't need to specify the Controller name again in the include.... if its the same as the parent one(same as controller of main page).
just go with this
<div ng-controller="MyCtrl">
<div>
<div ng-include="'temp2.html'">
Hello, {{name}}!
</div>
</div>
</div>
<script type="text/ng-template" id="temp2.html">
<div>Another View {{name}}</div>
</script>
Js Fiddel
name will be accessible in the view you included.
Hope it will help you..

How to grab ng-binds output text from a directive?

In most of my application I'm using ng-bind to display the data in my application of curly interpolation {{ }} in my templates instead o. I attempted to grab the interpolated ng-bind value from my element, however I keep getting undefined. Here is a JSbin of my code (suggestion:open web dev console):
HTML:
<body ng-app="app">
<div ng-controller="controller as vm">
<section directit>
<p ng-bind="vm.value"></p>
</section>
</div>
</body>
JS:
angular.module('app', [])
.controller('controller', function(){
this.value = 'hello';
})
.directive('directit', function(){
return {
restrict: 'A',
link: function(scope,element,atts){
var p = element.children()[0];
console.log('pText',p.innerHTML); //undefined
console.log('p',[p]); //innerText value is defined upon inspection
}
}
});

Using ng-click inside a tooltip

I'm using Angular Bootstrap UI and I have a working tooltip.
HTML:
<div ng-app="helloApp">
<div ng-controller="helloCtrl as hello">
<a tooltip-trigger="click" tooltip-placement="bottom" uib-tooltip-html="<h1 ng-click='hello.clickInsideToSeeTheWorld()'>Click again!</h1>">Click me to see the tooltip</a>
</div>
</div>
Javascript:
angular.module('helloApp', ['ui.bootstrap'])
.controller('helloCtrl', helloCtrl)
function helloCtrl() {
var vm = this;
vm.clickInsideToSeeTheWorld = function() {alert(123)}
}
When I open up the tooltip, ng-click doesn't work. No alert appears. I receive no errors in my console. This is because the HTML isn't compiled. How can I properly compile the tooltip html to get this to work?
Extending the previous answer: You can probably use
uib-tooltip-template
instead of
uib-tooltip-html
when you exploit the angular template cache.
I understand that you maybe do not want to create an external template.html, but you do not have to do so. Simply try:
var app = angular.module("test", ['ui.bootstrap']);
app.controller("testController", function($scope, $templateCache) {
$scope.clickInsideToSeeTheWorld = function() {
alert(123)
}
if (!$templateCache.get ('template.html')) {
$templateCache.put (
'template.html',
'<a ng-click="clickInsideToSeeTheWorld()">Click again!</a>'
);
}
});
and
<div ng-app="test" ng-controller="testController">
<p style="margin-top: 5em;" uib-tooltip-template="'template.html'" tooltip-popup-close-delay="3000" >
Click me to see the tooltip
</p>
Here's an external plunker as well:
https://plnkr.co/edit/Dsi69MQg4NfgOSI5ClFh?p=preview
I added uib-tooltip-template instead uib-tooltip-html and changed this to $scope.
index.html
<body>
<script>
var app = angular.module("test", ['ui.bootstrap']);
app.controller("testController", function($scope) {
$scope.clickInsideToSeeTheWorld = function() {
alert(123)}
});
</script>
<div ng-app="test" ng-controller="testController">
<p style="margin-top: 5em;" uib-tooltip-template="'template.html'" tooltip-popup-close-delay="3000" >
Click me to see the tooltip
</p>
</div>
</body>
template.html
<a ng-click="clickInsideToSeeTheWorld()">Click again!</a>
Here is working Plunker
Or Alternative solution is for you to compile code yourself and then assign it to tooltip html
var sc = scope.$new( true ); //scope for html
sc.hello = {} // assign your hallo object to new scope
var compiledHtml = $compile( '<h1 ng-click="hello.clickInsideToSeeTheWorld()">Click again!</h1>')( sc );
Then you can set tooltip html to compiledHtml.

How to render HTML Tags from ngModel?

I'm using AngularJS for binding JS variables to my HTML content, and it works fine.
JS
var app = angular.module("Tabs", [])
.controller("TabsController", ['$scope', function($scope){
$scope.events = my_JS_object;
})
HTML
<div>{{events.test}}</div>
It works as long as my_JS_object.test is a simple string, like "Hello World", but once I try to put HTML tag in there, such as Hello <b>World</b> It doesn't use the tags as HTML elements, but as simple text. Which makes sense, only I have no idea how to make the HTML tags work.
As stated by Angular documentation, you can use inbuilt ng-bind-html directive to evaluate model string and insert resulting HTML into element.
Example:
If you have model value like:
$scope.myHTML =
'I am an <code>HTML</code>string with ' +
'links! and other <em>stuff</em>';
Use ng-bind-html like:
<p ng-bind-html="myHTML"></p>
For detailed information go through: https://docs.angularjs.org/api/ng/directive/ngBindHtml
Note: Don't forget to inject ngSanitize service in your app.
You need to use the ngBindHtml directive that properly evaluates the expression and inserts the resulting HTML into the element in a secure way. To do this, you must include a reference to angular-sanitize.js in your HTML and then in your angular module, inject ngSanitize.
Like so
var app = angular.module("Tabs", ['ngSanitize'])
.controller("TabsController", ['$scope', function($scope){
$scope.events = my_JS_object;
})
<div ng-controller="TabsController">
<div ng-bind-html="events.test"></div>
</div>
Here is a full working example:
(function(angular) {
'use strict';
angular.module('bindHtmlExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', function($scope) {
$scope.myHTML = 'Hello This is <b>BOLD<b/>';
}]);
})(window.angular);
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular-sanitize.js"></script>
</head>
<body ng-app="bindHtmlExample">
<div ng-controller="ExampleController">
<p ng-bind-html="myHTML"></p>
</div>
</body>
Refer to the official angular documentation for details:
https://docs.angularjs.org/api/ng/directive/ngBindHtml
If you want to insert HTML into page you shouldn't do it this way.
There is sanitize for this task.
For example in your controller:
$scope.trustedHtml = "<b>Hello World</b>"
And in your html:
<div ng-bind-html="trustedHtml "></div>
Always check html if using a user given text before inserting.
Also don't forget to add ngSanitize as dependency while creating controller
It's easier to use transclusion if you want to embed custom HTML into your DOM tree.
angular.module('myApp', [])
.controller('MainCtrl', function ($scope) {
$scope.overwrite = false;
$scope.origin = 'parent controller';
})
.directive('myDirective', function() {
return {
restrict: 'E',
templateUrl: 'my-directive.html',
scope: {},
transclude: true,
link: function (scope) {
scope.overwrite = !!scope.origin;
scope.origin = 'link function';
}
};
});
<script src="https://code.angularjs.org/1.3.2/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<my-directive>
<p>HTML template</p>
<p>Scope from {{origin}}</p>
<p>Overwritten? {{overwrite}}</p>
</my-directive>
</div>
<script type="text/ng-template" id="my-directive.html">
<ng-transclude></ng-transclude>
<hr />
<p>Directive template</p>
<p>Scope from {{origin}}</p>
<p>Overwritten? {{overwrite}}</p>
</script>
</div>

Categories

Resources